changeset 4970:33df1aeaebbf

Merge with http://hg.openjdk.java.net/hsx/hsx24/hotspot/
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Mon, 27 Feb 2012 13:10:13 +0100
parents 2cfb7fb2dce7 (diff) b183b0863611 (current diff)
children 5d6aa83676be
files .hgtags make/Makefile make/bsd/Makefile make/bsd/makefiles/vm.make make/hotspot_version make/linux/makefiles/adlc.make make/linux/makefiles/buildtree.make make/linux/makefiles/launcher.make make/linux/makefiles/rules.make make/linux/makefiles/top.make make/linux/makefiles/vm.make make/windows/build_vm_def.sh make/windows/makefiles/projectcreator.make make/windows/makefiles/vm.make src/cpu/sparc/vm/assembler_sparc.cpp src/cpu/sparc/vm/methodHandles_sparc.cpp src/cpu/sparc/vm/stubGenerator_sparc.cpp src/cpu/x86/vm/assembler_x86.cpp src/cpu/x86/vm/c1_MacroAssembler_x86.cpp src/cpu/x86/vm/c1_Runtime1_x86.cpp src/cpu/x86/vm/c2_globals_x86.hpp src/cpu/x86/vm/frame_x86.cpp src/cpu/x86/vm/frame_x86.hpp src/cpu/x86/vm/nativeInst_x86.hpp src/cpu/x86/vm/sharedRuntime_x86_64.cpp src/cpu/x86/vm/stubGenerator_x86_32.cpp src/cpu/x86/vm/stubGenerator_x86_64.cpp src/cpu/x86/vm/vm_version_x86.cpp src/cpu/x86/vm/vm_version_x86.hpp src/os/bsd/vm/decoder_bsd.cpp src/os/linux/vm/os_linux.cpp src/os/windows/vm/os_windows.cpp src/share/tools/ProjectCreator/BuildConfig.java src/share/vm/c1/c1_IR.hpp src/share/vm/c1/c1_LIRAssembler.cpp src/share/vm/c1/c1_LIRGenerator.cpp src/share/vm/c1/c1_Runtime1.cpp src/share/vm/ci/ciEnv.hpp src/share/vm/ci/ciInstanceKlass.cpp src/share/vm/classfile/systemDictionary.cpp src/share/vm/classfile/systemDictionary.hpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/code/compiledIC.cpp src/share/vm/code/nmethod.cpp src/share/vm/code/nmethod.hpp src/share/vm/compiler/compileBroker.cpp src/share/vm/compiler/compileBroker.hpp src/share/vm/gc_implementation/g1/heapRegion.cpp src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp src/share/vm/interpreter/interpreterRuntime.cpp src/share/vm/oops/constantPoolOop.cpp src/share/vm/oops/instanceKlass.cpp src/share/vm/oops/instanceKlass.hpp src/share/vm/oops/klass.cpp src/share/vm/oops/klass.hpp src/share/vm/oops/methodKlass.cpp src/share/vm/oops/methodOop.cpp src/share/vm/oops/methodOop.hpp src/share/vm/opto/output.cpp src/share/vm/prims/jni.cpp src/share/vm/runtime/arguments.cpp src/share/vm/runtime/compilationPolicy.cpp src/share/vm/runtime/compilationPolicy.hpp src/share/vm/runtime/deoptimization.cpp src/share/vm/runtime/frame.cpp src/share/vm/runtime/frame.hpp src/share/vm/runtime/globals.hpp src/share/vm/runtime/java.cpp src/share/vm/runtime/os.cpp src/share/vm/runtime/sharedRuntime.cpp src/share/vm/runtime/sharedRuntime.hpp src/share/vm/runtime/sweeper.cpp src/share/vm/runtime/thread.cpp src/share/vm/runtime/thread.hpp src/share/vm/runtime/vmStructs.cpp src/share/vm/runtime/vm_version.cpp src/share/vm/utilities/exceptions.cpp src/share/vm/utilities/globalDefinitions.hpp
diffstat 2165 files changed, 174735 insertions(+), 9942 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Fri Feb 24 18:08:59 2012 -0800
+++ b/.hgignore	Mon Feb 27 13:10:13 2012 +0100
@@ -1,9 +1,53 @@
+^mx/env
+^mx/includes
 ^build/
 ^dist/
+^java/
+^lib/
+^jdk1.7.0
+^java64/
+^work/
+\.checkstyle$
+\.checkstyle.*.timestamp
+\.classpath
+\.project
+\.settings/
+\.metadata/
+~$
+\.csv$
+\.swp$
+\.class$
+\.log$
+\.bak$
+\.aux$
+\.pdf$
+\.dot$
+\.pyc$
+\.hprof$
+\.hprof\.txt$
+^graal/.*/build.xml
+^graal/.*/nbproject/
+dist
+^doc/.*/dot_temp_
+^doc/doxygen/.*$
+\.orig$
+output\.txt$
+output\.cfg$
+\.cfg
 /nbproject/private/
+^graal/hotspot/java$
+^scratch/
+^test-output/
+scratch/
+bin/
+^local/
 ^src/share/tools/hsdis/build/
 ^src/share/tools/IdealGraphVisualizer/[a-zA-Z0-9]*/build/
 ^src/share/tools/IdealGraphVisualizer/build/
 ^src/share/tools/IdealGraphVisualizer/dist/
+^visualizer/[a-zA-Z0-9]*/build/
+^visualizer/build/
+^visualizer/dist/
+^visualizer/nbplatform/
 ^.hgtip
 .DS_Store
--- a/.jcheck/conf	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-project=jdk8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GRAAL_AUTHORS	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,20 @@
+Doug Simon (doug.simon@oracle.com)
+* Since December 2011
+
+Christian Wimmer (christian.wimmer@oracle.com)
+* Since December 2011
+
+Lukas Stadler (stadler@ssw.jku.at)
+* July - September 2010: Initial feature-complete implementation, remote compilation
+* Since April 2011: New IR design
+
+Gilles Duboscq (gilles.duboscq@oracle.com)
+* Since April 2011: New IR design
+
+Peter Hofer (hofer@ssw.jku.at)
+* Since May 2011: Graphviz visualization
+
+Thomas Wuerthinger (thomas.wuerthinger@oracle.com)
+* June 2011: Initial prototype
+* October 2010 - January 2011: Bug fixes (all DaCapo's pass), better performance on SciMark than C1
+* Since April 2011: New IR design
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GRAAL_README	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,24 @@
+For creating a Graal VM JDK, the file jre\lib\jvm.cfg has to be modified such that it includes the line:
+-graal KNOWN
+
+Before running the Graal VM, the following environment variables is needed:
+- MAXINE: Pointing to a Maxine VM repository with compiled Java files.
+
+In particular, the VM will look for the compiled Java files in the following directories:
+${MAXINE}/com.oracle.max.cri/bin
+${MAXINE}/com.oracle.max.base/bin
+${MAXINE}/com.oracle.max.asmdis/bin
+${MAXINE}/com.oracle.max.asm/bin
+${MAXINE}/com.oracle.max.graal.graph/bin
+${MAXINE}/com.oracle.max.graal.compiler/bin
+${MAXINE}/com.oracle.max.graal.nodes/bin
+${MAXINE}/com.oracle.max.graal.extensions/bin
+${MAXINE}/com.oracle.max.graal.runtime/bin
+${MAXINE}/com.oracle.max.graal.graphviz/bin
+
+For starting the Graal VM, the flag "-graal" has to be specified. Additional flags that might be useful:
+-G:Plot Sends the graphs of compiled methods via network stream to the IdealGraphVisualizer (NetBeans project at ${GRAAL}/src/share/tools/IdealGraphVisualizer that can be built and run with NetBeans 7.0, use "Graal Coloring" and "Graal Edge Coloring" filters)
+-G:Time Prints timings for the different compilation phases
+-G:Meter Prints metrics for the different compilation phases
+
+The usual HotSpot flags -Xcomp -XX:CompileOnly= -XX:CompileCommand= or -XX:+PrintCompilation can be used to control the compiled methods.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/clean	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,5 @@
+#!/bin/bash
+pushd make
+LANG=C ARCH_DATA_MODEL=64 HOTSPOT_BUILD_JOBS=16 make clean
+popd
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/domake	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,3 @@
+mxtools/mx make
+mxtools/mx --debug make
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.asm/src/com/oracle/max/asm/AbstractAssembler.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2009, 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.max.asm;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiArchitecture.*;
+
+/**
+ * The platform-independent base class for the assembler.
+ */
+public abstract class AbstractAssembler {
+    public final CiTarget target;
+    public final Buffer codeBuffer;
+
+    public AbstractAssembler(CiTarget target) {
+        this.target = target;
+
+        if (target.arch.byteOrder == ByteOrder.BigEndian) {
+            this.codeBuffer = new Buffer.BigEndian();
+        } else {
+            this.codeBuffer = new Buffer.LittleEndian();
+        }
+    }
+
+    public final void bind(Label l) {
+        assert !l.isBound() : "can bind label only once";
+        l.bind(codeBuffer.position());
+        l.patchInstructions(this);
+    }
+
+    public abstract void align(int modulus);
+
+    public abstract void jmp(Label l);
+
+    protected abstract void patchJumpTarget(int branch, int jumpTarget);
+
+    protected final void emitByte(int x) {
+        codeBuffer.emitByte(x);
+    }
+
+    protected final void emitShort(int x) {
+        codeBuffer.emitShort(x);
+    }
+
+    protected final void emitInt(int x) {
+        codeBuffer.emitInt(x);
+    }
+
+    protected final void emitLong(long x) {
+        codeBuffer.emitLong(x);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.asm/src/com/oracle/max/asm/AsmOptions.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2011, 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.max.asm;
+
+public class AsmOptions {
+    public static int     InitialCodeBufferSize         = 232;
+    public static int     Atomics                       = 0;
+    public static boolean UseNormalNop                  = true;
+    public static boolean UseAddressNop                 = true;
+    public static boolean UseIncDec                     = false;
+    public static boolean UseXmmLoadAndClearUpper       = true;
+    public static boolean UseXmmRegToRegMoveAll         = false;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.asm/src/com/oracle/max/asm/Buffer.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2009, 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.max.asm;
+
+import java.util.*;
+
+/**
+ * Code buffer management for the assembler. Support for little endian and big endian architectures is implemented using subclasses.
+ */
+public abstract class Buffer {
+    protected byte[] data;
+    protected int position;
+
+    public Buffer() {
+        data = new byte[AsmOptions.InitialCodeBufferSize];
+    }
+
+    public void reset() {
+        position = 0;
+    }
+
+    public int position() {
+        return position;
+    }
+
+    public void setPosition(int position) {
+        assert position >= 0 && position <= data.length;
+        this.position = position;
+    }
+
+    /**
+     * Closes this buffer. No extra data can be written to this buffer after
+     * this call.
+     *
+     * @param trimmedCopy
+     *            if {@code true}, then a copy of the underlying byte array up
+     *            to (but not including) {@code position()} is returned
+     * @return the data in this buffer or a trimmed copy if {@code trimmedCopy}
+     *         is {@code true}
+     */
+    public byte[] close(boolean trimmedCopy) {
+        byte[] result = trimmedCopy ? Arrays.copyOf(data, position()) : data;
+        data = null;
+        return result;
+    }
+
+    public byte[] copyData(int start, int end) {
+        return Arrays.copyOfRange(data, start, end);
+    }
+
+    /**
+     * Copies the data from this buffer into a given array.
+     *
+     * @param dst
+     *            the destination array
+     * @param off
+     *            starting position in {@code dst}
+     * @param len
+     *            number of bytes to copy
+     */
+    public void copyInto(byte[] dst, int off, int len) {
+        System.arraycopy(data, 0, dst, off, len);
+    }
+
+    protected void ensureSize(int length) {
+        if (length >= data.length) {
+            data = Arrays.copyOf(data, length * 4);
+        }
+    }
+
+    public void emitBytes(byte[] arr, int off, int len) {
+        ensureSize(position + len);
+        System.arraycopy(arr, off, data, position, len);
+        position += len;
+    }
+
+    public void emitByte(int b) {
+        position = emitByte(b, position);
+    }
+
+    public void emitShort(int b) {
+        position = emitShort(b, position);
+    }
+
+    public void emitInt(int b) {
+        position = emitInt(b, position);
+    }
+
+    public void emitLong(long b) {
+        position = emitLong(b, position);
+    }
+
+    public int emitByte(int b, int pos) {
+        assert NumUtil.isUByte(b);
+        int newPos = pos + 1;
+        ensureSize(newPos);
+        data[pos] = (byte) (b & 0xFF);
+        return newPos;
+    }
+
+    public abstract int emitShort(int b, int pos);
+
+    public abstract int emitInt(int b, int pos);
+
+    public abstract int emitLong(long b, int pos);
+
+    public int getByte(int pos) {
+        return data[pos] & 0xff;
+    }
+
+    public abstract int getShort(int pos);
+
+    public abstract int getInt(int pos);
+
+    public static final class BigEndian extends Buffer {
+        @Override
+        public int emitShort(int b, int pos) {
+            assert NumUtil.isUShort(b);
+            int newPos = pos + 2;
+            ensureSize(pos + 2);
+            data[pos] = (byte) ((b >> 8) & 0xFF);
+            data[pos + 1] = (byte) (b & 0xFF);
+            return newPos;
+        }
+
+        @Override
+        public int emitInt(int b, int pos) {
+            int newPos = pos + 4;
+            ensureSize(newPos);
+            data[pos] = (byte) ((b >> 24) & 0xFF);
+            data[pos + 1] = (byte) ((b >> 16) & 0xFF);
+            data[pos + 2] = (byte) ((b >> 8) & 0xFF);
+            data[pos + 3] = (byte) (b & 0xFF);
+            return newPos;
+        }
+
+        @Override
+        public int emitLong(long b, int pos) {
+            int newPos = pos + 8;
+            ensureSize(newPos);
+            data[pos] = (byte) ((b >> 56) & 0xFF);
+            data[pos + 1] = (byte) ((b >> 48) & 0xFF);
+            data[pos + 2] = (byte) ((b >> 40) & 0xFF);
+            data[pos + 3] = (byte) ((b >> 32) & 0xFF);
+            data[pos + 4] = (byte) ((b >> 24) & 0xFF);
+            data[pos + 5] = (byte) ((b >> 16) & 0xFF);
+            data[pos + 6] = (byte) ((b >> 8) & 0xFF);
+            data[pos + 7] = (byte) (b & 0xFF);
+            return newPos;
+        }
+
+        @Override
+        public int getShort(int pos) {
+            return
+                (data[pos + 0] & 0xff) << 8 |
+                (data[pos + 1] & 0xff) << 0;
+        }
+
+        @Override
+        public int getInt(int pos) {
+            return
+                (data[pos + 0] & 0xff) << 24 |
+                (data[pos + 1] & 0xff) << 16 |
+                (data[pos + 2] & 0xff) << 8 |
+                (data[pos + 3] & 0xff) << 0;
+        }
+    }
+
+    public static final class LittleEndian extends Buffer {
+        @Override
+        public int emitShort(int b, int pos) {
+            assert NumUtil.isUShort(b);
+            int newPos = pos + 2;
+            ensureSize(newPos);
+            data[pos] = (byte) (b & 0xFF);
+            data[pos + 1] = (byte) ((b >> 8) & 0xFF);
+            return newPos;
+        }
+
+        @Override
+        public int emitInt(int b, int pos) {
+            int newPos = pos + 4;
+            ensureSize(newPos);
+            data[pos] = (byte) (b & 0xFF);
+            data[pos + 1] = (byte) ((b >> 8) & 0xFF);
+            data[pos + 2] = (byte) ((b >> 16) & 0xFF);
+            data[pos + 3] = (byte) ((b >> 24) & 0xFF);
+            return newPos;
+        }
+
+        @Override
+        public int emitLong(long b, int pos) {
+            int newPos = pos + 8;
+            ensureSize(newPos);
+            data[pos] = (byte) (b & 0xFF);
+            data[pos + 1] = (byte) ((b >> 8) & 0xFF);
+            data[pos + 2] = (byte) ((b >> 16) & 0xFF);
+            data[pos + 3] = (byte) ((b >> 24) & 0xFF);
+            data[pos + 4] = (byte) ((b >> 32) & 0xFF);
+            data[pos + 5] = (byte) ((b >> 40) & 0xFF);
+            data[pos + 6] = (byte) ((b >> 48) & 0xFF);
+            data[pos + 7] = (byte) ((b >> 56) & 0xFF);
+            return newPos;
+        }
+
+        @Override
+        public int getShort(int pos) {
+            return
+                (data[pos + 1] & 0xff) << 8 |
+                (data[pos + 0] & 0xff) << 0;
+        }
+
+        @Override
+        public int getInt(int pos) {
+            return
+                (data[pos + 3] & 0xff) << 24 |
+                (data[pos + 2] & 0xff) << 16 |
+                (data[pos + 1] & 0xff) << 8 |
+                (data[pos + 0] & 0xff) << 0;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.asm/src/com/oracle/max/asm/Label.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2009, 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.max.asm;
+
+import java.util.ArrayList;
+
+/**
+ * This class represents a label within assembly code.
+ */
+public final class Label {
+    private int position = -1;
+
+    /**
+     * References to instructions that jump to this unresolved label.
+     * These instructions need to be patched when the label is bound
+     * using the {@link #patchInstructions(AbstractAssembler)} method.
+     */
+    private ArrayList<Integer> patchPositions = new ArrayList<>(4);
+
+    /**
+     * Returns the position of this label in the code buffer.
+     * @return the position
+     */
+    public int position() {
+        assert position >= 0 : "Unbound label is being referenced";
+        return position;
+    }
+
+    public Label() {
+    }
+
+    /**
+     * Binds the label to the specified position.
+     * @param pos the position
+     */
+    protected void bind(int pos) {
+        this.position = pos;
+        assert isBound();
+    }
+
+    public boolean isBound() {
+        return position >= 0;
+    }
+
+    public void addPatchAt(int branchLocation) {
+        assert !isBound() : "Label is already bound";
+        patchPositions.add(branchLocation);
+    }
+
+    protected void patchInstructions(AbstractAssembler masm) {
+        assert isBound() : "Label should be bound";
+        int target = position;
+        for (int i = 0; i < patchPositions.size(); ++i) {
+            int pos = patchPositions.get(i);
+            masm.patchJumpTarget(pos, target);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return isBound() ? String.valueOf(position()) : "?";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.asm/src/com/oracle/max/asm/NumUtil.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2011, 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.max.asm;
+
+/**
+ * A collection of static utility functions that check ranges of numbers.
+ */
+public class NumUtil {
+    public static boolean isShiftCount(int x) {
+        return 0 <= x && x < 32;
+    }
+
+    /**
+     * Determines if a given {@code int} value is the range of unsigned byte
+     * values.
+     */
+    public static boolean isUByte(int x) {
+        return (x & 0xff) == x;
+    }
+
+    /**
+     * Determines if a given {@code int} value is the range of signed byte
+     * values.
+     */
+    public static boolean isByte(int x) {
+        return (byte) x == x;
+    }
+
+    /**
+     * Determines if a given {@code long} value is the range of unsigned byte
+     * values.
+     */
+    public static boolean isUByte(long x) {
+        return (x & 0xffL) == x;
+    }
+
+    /**
+     * Determines if a given {@code long} value is the range of signed byte
+     * values.
+     */
+    public static boolean isByte(long l) {
+        return (byte) l == l;
+    }
+
+    /**
+     * Determines if a given {@code long} value is the range of unsigned int
+     * values.
+     */
+    public static boolean isUInt(long x) {
+        return (x & 0xffffffffL) == x;
+    }
+
+    /**
+     * Determines if a given {@code long} value is the range of signed int
+     * values.
+     */
+    public static boolean isInt(long l) {
+        return (int) l == l;
+    }
+
+    /**
+     * Determines if a given {@code int} value is the range of signed short
+     * values.
+     */
+    public static boolean isShort(int x) {
+        return (short) x == x;
+    }
+
+    public static boolean isUShort(int s) {
+        return s == (s & 0xFFFF);
+    }
+
+    public static boolean is32bit(long x) {
+        return -0x80000000L <= x && x < 0x80000000L;
+    }
+
+    public static short safeToShort(int v) {
+        assert isShort(v);
+        return (short) v;
+    }
+
+    public static int roundUp(int number, int mod) {
+        return ((number + mod - 1) / mod) * mod;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.asm/src/com/oracle/max/asm/target/amd64/AMD64.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2009, 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.max.asm.target.amd64;
+
+import static com.oracle.max.cri.ci.CiKind.*;
+import static com.oracle.max.cri.ci.CiRegister.RegisterFlag.*;
+import static com.oracle.max.cri.util.MemoryBarriers.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiRegister.*;
+
+/**
+ * Represents the AMD64 architecture.
+ */
+public class AMD64 extends CiArchitecture {
+
+    // General purpose CPU registers
+    public static final CiRegister rax = new CiRegister(0, 0, 8, "rax", CPU, RegisterFlag.Byte);
+    public static final CiRegister rcx = new CiRegister(1, 1, 8, "rcx", CPU, RegisterFlag.Byte);
+    public static final CiRegister rdx = new CiRegister(2, 2, 8, "rdx", CPU, RegisterFlag.Byte);
+    public static final CiRegister rbx = new CiRegister(3, 3, 8, "rbx", CPU, RegisterFlag.Byte);
+    public static final CiRegister rsp = new CiRegister(4, 4, 8, "rsp", CPU, RegisterFlag.Byte);
+    public static final CiRegister rbp = new CiRegister(5, 5, 8, "rbp", CPU, RegisterFlag.Byte);
+    public static final CiRegister rsi = new CiRegister(6, 6, 8, "rsi", CPU, RegisterFlag.Byte);
+    public static final CiRegister rdi = new CiRegister(7, 7, 8, "rdi", CPU, RegisterFlag.Byte);
+
+    public static final CiRegister r8  = new CiRegister(8,  8,  8, "r8", CPU, RegisterFlag.Byte);
+    public static final CiRegister r9  = new CiRegister(9,  9,  8, "r9", CPU, RegisterFlag.Byte);
+    public static final CiRegister r10 = new CiRegister(10, 10, 8, "r10", CPU, RegisterFlag.Byte);
+    public static final CiRegister r11 = new CiRegister(11, 11, 8, "r11", CPU, RegisterFlag.Byte);
+    public static final CiRegister r12 = new CiRegister(12, 12, 8, "r12", CPU, RegisterFlag.Byte);
+    public static final CiRegister r13 = new CiRegister(13, 13, 8, "r13", CPU, RegisterFlag.Byte);
+    public static final CiRegister r14 = new CiRegister(14, 14, 8, "r14", CPU, RegisterFlag.Byte);
+    public static final CiRegister r15 = new CiRegister(15, 15, 8, "r15", CPU, RegisterFlag.Byte);
+
+    public static final CiRegister[] cpuRegisters = {
+        rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
+        r8, r9, r10, r11, r12, r13, r14, r15
+    };
+
+    // XMM registers
+    public static final CiRegister xmm0 = new CiRegister(16, 0, 8, "xmm0", FPU);
+    public static final CiRegister xmm1 = new CiRegister(17, 1, 8, "xmm1", FPU);
+    public static final CiRegister xmm2 = new CiRegister(18, 2, 8, "xmm2", FPU);
+    public static final CiRegister xmm3 = new CiRegister(19, 3, 8, "xmm3", FPU);
+    public static final CiRegister xmm4 = new CiRegister(20, 4, 8, "xmm4", FPU);
+    public static final CiRegister xmm5 = new CiRegister(21, 5, 8, "xmm5", FPU);
+    public static final CiRegister xmm6 = new CiRegister(22, 6, 8, "xmm6", FPU);
+    public static final CiRegister xmm7 = new CiRegister(23, 7, 8, "xmm7", FPU);
+
+    public static final CiRegister xmm8 =  new CiRegister(24,  8, 8, "xmm8",  FPU);
+    public static final CiRegister xmm9 =  new CiRegister(25,  9, 8, "xmm9",  FPU);
+    public static final CiRegister xmm10 = new CiRegister(26, 10, 8, "xmm10", FPU);
+    public static final CiRegister xmm11 = new CiRegister(27, 11, 8, "xmm11", FPU);
+    public static final CiRegister xmm12 = new CiRegister(28, 12, 8, "xmm12", FPU);
+    public static final CiRegister xmm13 = new CiRegister(29, 13, 8, "xmm13", FPU);
+    public static final CiRegister xmm14 = new CiRegister(30, 14, 8, "xmm14", FPU);
+    public static final CiRegister xmm15 = new CiRegister(31, 15, 8, "xmm15", FPU);
+
+    public static final CiRegister[] xmmRegisters = {
+        xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
+        xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
+    };
+
+    public static final CiRegister[] cpuxmmRegisters = {
+        rax,  rcx,  rdx,   rbx,   rsp,   rbp,   rsi,   rdi,
+        r8,   r9,   r10,   r11,   r12,   r13,   r14,   r15,
+        xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
+        xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
+    };
+
+    /**
+     * Register used to construct an instruction-relative address.
+     */
+    public static final CiRegister rip = new CiRegister(32, -1, 0, "rip");
+
+    public static final CiRegister[] allRegisters = {
+        rax,  rcx,  rdx,   rbx,   rsp,   rbp,   rsi,   rdi,
+        r8,   r9,   r10,   r11,   r12,   r13,   r14,   r15,
+        xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
+        xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
+        rip
+    };
+
+    public static final CiRegisterValue RSP = rsp.asValue(Long);
+
+    public AMD64() {
+        super("AMD64",
+              8,
+              ByteOrder.LittleEndian,
+              allRegisters,
+              LOAD_STORE | STORE_STORE,
+              1,
+              r15.encoding + 1,
+              8);
+    }
+
+    @Override
+    public boolean isX86() {
+        return true;
+    }
+
+    @Override
+    public boolean twoOperandMode() {
+        return true;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.asm/src/com/oracle/max/asm/target/amd64/AMD64Assembler.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2988 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.asm.target.amd64;
+
+import static com.oracle.max.asm.NumUtil.*;
+import static com.oracle.max.asm.target.amd64.AMD64.*;
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.max.cri.util.MemoryBarriers.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+
+/**
+ * This class implements an assembler that can encode most X86 instructions.
+ */
+public class AMD64Assembler extends AbstractAssembler {
+    /**
+     * The kind for pointers and raw registers.  Since we know we are 64 bit here, we can hardcode it.
+     */
+    private static final CiKind Word = CiKind.Long;
+
+    private static final int MinEncodingNeedsRex = 8;
+
+    /**
+     * The x86 condition codes used for conditional jumps/moves.
+     */
+    public enum ConditionFlag {
+        zero(0x4),
+        notZero(0x5),
+        equal(0x4),
+        notEqual(0x5),
+        less(0xc),
+        lessEqual(0xe),
+        greater(0xf),
+        greaterEqual(0xd),
+        below(0x2),
+        belowEqual(0x6),
+        above(0x7),
+        aboveEqual(0x3),
+        overflow(0x0),
+        noOverflow(0x1),
+        carrySet(0x2),
+        carryClear(0x3),
+        negative(0x8),
+        positive(0x9),
+        parity(0xa),
+        noParity(0xb);
+
+        public final int value;
+
+        private ConditionFlag(int value) {
+            this.value = value;
+        }
+
+        public static final ConditionFlag[] values = values();
+    }
+
+    /**
+     * Constants for X86 prefix bytes.
+     */
+    private static class Prefix {
+        private static final int REX = 0x40;
+        private static final int REXB = 0x41;
+        private static final int REXX = 0x42;
+        private static final int REXXB = 0x43;
+        private static final int REXR = 0x44;
+        private static final int REXRB = 0x45;
+        private static final int REXRX = 0x46;
+        private static final int REXRXB = 0x47;
+        private static final int REXW = 0x48;
+        private static final int REXWB = 0x49;
+        private static final int REXWX = 0x4A;
+        private static final int REXWXB = 0x4B;
+        private static final int REXWR = 0x4C;
+        private static final int REXWRB = 0x4D;
+        private static final int REXWRX = 0x4E;
+        private static final int REXWRXB = 0x4F;
+    }
+
+    /**
+     * The register to which {@link CiRegister#Frame} and {@link CiRegister#CallerFrame} are bound.
+     */
+    public final CiRegister frameRegister;
+
+    /**
+     * Constructs an assembler for the AMD64 architecture.
+     *
+     * @param registerConfig the register configuration used to bind {@link CiRegister#Frame} and
+     *            {@link CiRegister#CallerFrame} to physical registers. This value can be null if this assembler
+     *            instance will not be used to assemble instructions using these logical registers.
+     */
+    public AMD64Assembler(CiTarget target, RiRegisterConfig registerConfig) {
+        super(target);
+        this.frameRegister = registerConfig == null ? null : registerConfig.getFrameRegister();
+    }
+
+    private static int encode(CiRegister r) {
+        assert r.encoding < 16 && r.encoding >= 0 : "encoding out of range: " + r.encoding;
+        return r.encoding & 0x7;
+    }
+
+    private void emitArithB(int op1, int op2, CiRegister dst, int imm8) {
+        assert dst.isByte() : "must have byte register";
+        assert isUByte(op1) && isUByte(op2) : "wrong opcode";
+        assert isUByte(imm8) : "not a byte";
+        assert (op1 & 0x01) == 0 : "should be 8bit operation";
+        emitByte(op1);
+        emitByte(op2 | encode(dst));
+        emitByte(imm8);
+    }
+
+    private void emitArith(int op1, int op2, CiRegister dst, int imm32) {
+        assert isUByte(op1) && isUByte(op2) : "wrong opcode";
+        assert (op1 & 0x01) == 1 : "should be 32bit operation";
+        assert (op1 & 0x02) == 0 : "sign-extension bit should not be set";
+        if (isByte(imm32)) {
+            emitByte(op1 | 0x02); // set sign bit
+            emitByte(op2 | encode(dst));
+            emitByte(imm32 & 0xFF);
+        } else {
+            emitByte(op1);
+            emitByte(op2 | encode(dst));
+            emitInt(imm32);
+        }
+    }
+
+    // immediate-to-memory forms
+    private void emitArithOperand(int op1, CiRegister rm, CiAddress adr, int imm32) {
+        assert (op1 & 0x01) == 1 : "should be 32bit operation";
+        assert (op1 & 0x02) == 0 : "sign-extension bit should not be set";
+        if (isByte(imm32)) {
+            emitByte(op1 | 0x02); // set sign bit
+            emitOperandHelper(rm, adr);
+            emitByte(imm32 & 0xFF);
+        } else {
+            emitByte(op1);
+            emitOperandHelper(rm, adr);
+            emitInt(imm32);
+        }
+    }
+
+    private void emitArith(int op1, int op2, CiRegister dst, CiRegister src) {
+        assert isUByte(op1) && isUByte(op2) : "wrong opcode";
+        emitByte(op1);
+        emitByte(op2 | encode(dst) << 3 | encode(src));
+    }
+
+    private void emitOperandHelper(CiRegister reg, CiAddress addr) {
+        CiRegister base = isLegal(addr.base) ? asRegister(addr.base) : CiRegister.None;
+        CiRegister index = isLegal(addr.index) ? asRegister(addr.index) : CiRegister.None;
+
+        CiAddress.Scale scale = addr.scale;
+        int disp = addr.displacement;
+
+        if (base == CiRegister.Frame) {
+            assert frameRegister != null : "cannot use register " + CiRegister.Frame + " in assembler with null register configuration";
+            base = frameRegister;
+//        } else if (base == CiRegister.CallerFrame) {
+//            assert frameRegister != null : "cannot use register " + CiRegister.Frame + " in assembler with null register configuration";
+//            base = frameRegister;
+//            disp += targetMethod.frameSize() + 8;
+        }
+
+        // Encode the registers as needed in the fields they are used in
+
+        assert reg != CiRegister.None;
+        int regenc = encode(reg) << 3;
+
+        if (base == AMD64.rip) {
+            // [00 000 101] disp32
+            emitByte(0x05 | regenc);
+            emitInt(disp);
+        } else if (addr == CiAddress.Placeholder) {
+            // [00 000 101] disp32
+            emitByte(0x05 | regenc);
+            emitInt(0);
+
+        } else if (base.isValid()) {
+            int baseenc = base.isValid() ? encode(base) : 0;
+            if (index.isValid()) {
+                int indexenc = encode(index) << 3;
+                // [base + indexscale + disp]
+                if (disp == 0 && base != rbp && (base != r13)) {
+                    // [base + indexscale]
+                    // [00 reg 100][ss index base]
+                    assert index != rsp : "illegal addressing mode";
+                    emitByte(0x04 | regenc);
+                    emitByte(scale.log2 << 6 | indexenc | baseenc);
+                } else if (isByte(disp)) {
+                    // [base + indexscale + imm8]
+                    // [01 reg 100][ss index base] imm8
+                    assert index != rsp : "illegal addressing mode";
+                    emitByte(0x44 | regenc);
+                    emitByte(scale.log2 << 6 | indexenc | baseenc);
+                    emitByte(disp & 0xFF);
+                } else {
+                    // [base + indexscale + disp32]
+                    // [10 reg 100][ss index base] disp32
+                    assert index != rsp : "illegal addressing mode";
+                    emitByte(0x84 | regenc);
+                    emitByte(scale.log2 << 6 | indexenc | baseenc);
+                    emitInt(disp);
+                }
+            } else if (base == rsp || (base == r12)) {
+                // [rsp + disp]
+                if (disp == 0) {
+                    // [rsp]
+                    // [00 reg 100][00 100 100]
+                    emitByte(0x04 | regenc);
+                    emitByte(0x24);
+                } else if (isByte(disp)) {
+                    // [rsp + imm8]
+                    // [01 reg 100][00 100 100] disp8
+                    emitByte(0x44 | regenc);
+                    emitByte(0x24);
+                    emitByte(disp & 0xFF);
+                } else {
+                    // [rsp + imm32]
+                    // [10 reg 100][00 100 100] disp32
+                    emitByte(0x84 | regenc);
+                    emitByte(0x24);
+                    emitInt(disp);
+                }
+            } else {
+                // [base + disp]
+                assert base != rsp && (base != r12) : "illegal addressing mode";
+                if (disp == 0 && base != rbp && (base != r13)) {
+                    // [base]
+                    // [00 reg base]
+                    emitByte(0x00 | regenc | baseenc);
+                } else if (isByte(disp)) {
+                    // [base + disp8]
+                    // [01 reg base] disp8
+                    emitByte(0x40 | regenc | baseenc);
+                    emitByte(disp & 0xFF);
+                } else {
+                    // [base + disp32]
+                    // [10 reg base] disp32
+                    emitByte(0x80 | regenc | baseenc);
+                    emitInt(disp);
+                }
+            }
+        } else {
+            if (index.isValid()) {
+                int indexenc = encode(index) << 3;
+                // [indexscale + disp]
+                // [00 reg 100][ss index 101] disp32
+                assert index != rsp : "illegal addressing mode";
+                emitByte(0x04 | regenc);
+                emitByte(scale.log2 << 6 | indexenc | 0x05);
+                emitInt(disp);
+            } else {
+                // [disp] ABSOLUTE
+                // [00 reg 100][00 100 101] disp32
+                emitByte(0x04 | regenc);
+                emitByte(0x25);
+                emitInt(disp);
+            }
+        }
+    }
+
+    public final void addl(CiAddress dst, int imm32) {
+        prefix(dst);
+        emitArithOperand(0x81, rax, dst, imm32);
+    }
+
+    public final void addl(CiAddress dst, CiRegister src) {
+        prefix(dst, src);
+        emitByte(0x01);
+        emitOperandHelper(src, dst);
+    }
+
+    public final void addl(CiRegister dst, int imm32) {
+        prefix(dst);
+        emitArith(0x81, 0xC0, dst, imm32);
+    }
+
+    public final void addl(CiRegister dst, CiAddress src) {
+        prefix(src, dst);
+        emitByte(0x03);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void addl(CiRegister dst, CiRegister src) {
+        prefixAndEncode(dst.encoding, src.encoding);
+        emitArith(0x03, 0xC0, dst, src);
+    }
+
+    private void addrNop4() {
+        // 4 bytes: NOP DWORD PTR [EAX+0]
+        emitByte(0x0F);
+        emitByte(0x1F);
+        emitByte(0x40); // emitRm(cbuf, 0x1, EAXEnc, EAXEnc);
+        emitByte(0); // 8-bits offset (1 byte)
+    }
+
+    private void addrNop5() {
+        // 5 bytes: NOP DWORD PTR [EAX+EAX*0+0] 8-bits offset
+        emitByte(0x0F);
+        emitByte(0x1F);
+        emitByte(0x44); // emitRm(cbuf, 0x1, EAXEnc, 0x4);
+        emitByte(0x00); // emitRm(cbuf, 0x0, EAXEnc, EAXEnc);
+        emitByte(0); // 8-bits offset (1 byte)
+    }
+
+    private void addrNop7() {
+        // 7 bytes: NOP DWORD PTR [EAX+0] 32-bits offset
+        emitByte(0x0F);
+        emitByte(0x1F);
+        emitByte(0x80); // emitRm(cbuf, 0x2, EAXEnc, EAXEnc);
+        emitInt(0); // 32-bits offset (4 bytes)
+    }
+
+    private void addrNop8() {
+        // 8 bytes: NOP DWORD PTR [EAX+EAX*0+0] 32-bits offset
+        emitByte(0x0F);
+        emitByte(0x1F);
+        emitByte(0x84); // emitRm(cbuf, 0x2, EAXEnc, 0x4);
+        emitByte(0x00); // emitRm(cbuf, 0x0, EAXEnc, EAXEnc);
+        emitInt(0); // 32-bits offset (4 bytes)
+    }
+
+    public final void addsd(CiRegister dst, CiRegister src) {
+        assert dst.isFpu() && src.isFpu();
+        emitByte(0xF2);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x58);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void addsd(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+        emitByte(0xF2);
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x58);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void addss(CiRegister dst, CiRegister src) {
+        assert dst.isFpu() && src.isFpu();
+        emitByte(0xF3);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x58);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void addss(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+        emitByte(0xF3);
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x58);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void andl(CiRegister dst, int imm32) {
+        prefix(dst);
+        emitArith(0x81, 0xE0, dst, imm32);
+    }
+
+    public final void andl(CiRegister dst, CiAddress src) {
+        prefix(src, dst);
+        emitByte(0x23);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void andl(CiRegister dst, CiRegister src) {
+        prefixAndEncode(dst.encoding, src.encoding);
+        emitArith(0x23, 0xC0, dst, src);
+    }
+
+    public final void bsfq(CiRegister dst, CiRegister src) {
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0xBC);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void bsfq(CiRegister dst, CiAddress src) {
+        prefixq(src, dst);
+        emitByte(0xBC);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void bsrq(CiRegister dst, CiRegister src) {
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0xBD);
+        emitByte(0xC0 | encode);
+    }
+
+
+    public final void bsrq(CiRegister dst, CiAddress src) {
+        prefixq(src, dst);
+        emitByte(0xBD);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void bswapl(CiRegister reg) { // bswap
+        int encode = prefixAndEncode(reg.encoding);
+        emitByte(0x0F);
+        emitByte(0xC8 | encode);
+    }
+
+    public final void btli(CiAddress src, int imm8) {
+        prefixq(src);
+        emitByte(0x0F);
+        emitByte(0xBA);
+        emitOperandHelper(rsp, src);
+        emitByte(imm8);
+    }
+
+    public final void cdql() {
+        emitByte(0x99);
+    }
+
+    public final void cmovl(ConditionFlag cc, CiRegister dst, CiRegister src) {
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x40 | cc.value);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void cmovl(ConditionFlag cc, CiRegister dst, CiAddress src) {
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x40 | cc.value);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void cmpb(CiAddress dst, int imm8) {
+        prefix(dst);
+        emitByte(0x80);
+        emitOperandHelper(rdi, dst);
+        emitByte(imm8);
+    }
+
+    public final void cmpl(CiAddress dst, int imm32) {
+        prefix(dst);
+        emitByte(0x81);
+        emitOperandHelper(rdi, dst);
+        emitInt(imm32);
+    }
+
+    public final void cmpl(CiRegister dst, int imm32) {
+        prefix(dst);
+        emitArith(0x81, 0xF8, dst, imm32);
+    }
+
+    public final void cmpl(CiRegister dst, CiRegister src) {
+        prefixAndEncode(dst.encoding, src.encoding);
+        emitArith(0x3B, 0xC0, dst, src);
+    }
+
+    public final void cmpl(CiRegister dst, CiAddress src) {
+        prefix(src, dst);
+        emitByte(0x3B);
+        emitOperandHelper(dst, src);
+    }
+
+    // The 32-bit cmpxchg compares the value at adr with the contents of X86.rax,
+    // and stores reg into adr if so; otherwise, the value at adr is loaded into X86.rax,.
+    // The ZF is set if the compared values were equal, and cleared otherwise.
+    public final void cmpxchgl(CiRegister reg, CiAddress adr) { // cmpxchg
+        if ((AsmOptions.Atomics & 2) != 0) {
+            // caveat: no instructionmark, so this isn't relocatable.
+            // Emit a synthetic, non-atomic, CAS equivalent.
+            // Beware. The synthetic form sets all ICCs, not just ZF.
+            // cmpxchg r,[m] is equivalent to X86.rax, = CAS (m, X86.rax, r)
+            cmpl(rax, adr);
+            movl(rax, adr);
+            if (reg != rax) {
+                Label l = new Label();
+                jcc(ConditionFlag.notEqual, l);
+                movl(adr, reg);
+                bind(l);
+            }
+        } else {
+
+            prefix(adr, reg);
+            emitByte(0x0F);
+            emitByte(0xB1);
+            emitOperandHelper(reg, adr);
+        }
+    }
+
+    public final void comisd(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+        // NOTE: dbx seems to decode this as comiss even though the
+        // 0x66 is there. Strangly ucomisd comes out correct
+        emitByte(0x66);
+        comiss(dst, src);
+    }
+
+    public final void comiss(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x2F);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void cvtdq2pd(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+
+        emitByte(0xF3);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0xE6);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void cvtdq2ps(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x5B);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void cvtsd2ss(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+        emitByte(0xF2);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x5A);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void cvtsi2sdl(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        emitByte(0xF2);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x2A);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void cvtsi2ssl(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        emitByte(0xF3);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x2A);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void cvtss2sd(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+        emitByte(0xF3);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x5A);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void cvttsd2sil(CiRegister dst, CiRegister src) {
+        assert src.isFpu();
+        emitByte(0xF2);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x2C);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void cvttss2sil(CiRegister dst, CiRegister src) {
+        assert src.isFpu();
+        emitByte(0xF3);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x2C);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void decl(CiAddress dst) {
+        // Don't use it directly. Use Macrodecrement() instead.
+        prefix(dst);
+        emitByte(0xFF);
+        emitOperandHelper(rcx, dst);
+    }
+
+    public final void divsd(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+        emitByte(0xF2);
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x5E);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void divsd(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+        emitByte(0xF2);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x5E);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void divss(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+        emitByte(0xF3);
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x5E);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void divss(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+        emitByte(0xF3);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x5E);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void hlt() {
+        emitByte(0xF4);
+    }
+
+    public final void idivl(CiRegister src) {
+        int encode = prefixAndEncode(src.encoding);
+        emitByte(0xF7);
+        emitByte(0xF8 | encode);
+    }
+
+    public final void divl(CiRegister src) {
+        int encode = prefixAndEncode(src.encoding);
+        emitByte(0xF7);
+        emitByte(0xF0 | encode);
+    }
+
+    public final void imull(CiRegister dst, CiRegister src) {
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0xAF);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void imull(CiRegister dst, CiRegister src, int value) {
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        if (isByte(value)) {
+            emitByte(0x6B);
+            emitByte(0xC0 | encode);
+            emitByte(value & 0xFF);
+        } else {
+            emitByte(0x69);
+            emitByte(0xC0 | encode);
+            emitInt(value);
+        }
+    }
+
+    public final void incl(CiAddress dst) {
+        // Don't use it directly. Use Macroincrement() instead.
+        prefix(dst);
+        emitByte(0xFF);
+        emitOperandHelper(rax, dst);
+    }
+
+    public final void jcc(ConditionFlag cc, int jumpTarget, boolean forceDisp32) {
+        int shortSize = 2;
+        int longSize = 6;
+        long disp = jumpTarget - codeBuffer.position();
+        if (!forceDisp32 && isByte(disp - shortSize)) {
+            // 0111 tttn #8-bit disp
+            emitByte(0x70 | cc.value);
+            emitByte((int) ((disp - shortSize) & 0xFF));
+        } else {
+            // 0000 1111 1000 tttn #32-bit disp
+            assert isInt(disp - longSize) : "must be 32bit offset (call4)";
+            emitByte(0x0F);
+            emitByte(0x80 | cc.value);
+            emitInt((int) (disp - longSize));
+        }
+    }
+
+    public final void jcc(ConditionFlag cc, Label l) {
+        assert (0 <= cc.value) && (cc.value < 16) : "illegal cc";
+        if (l.isBound()) {
+            jcc(cc, l.position(), false);
+        } else {
+            // Note: could eliminate cond. jumps to this jump if condition
+            // is the same however, seems to be rather unlikely case.
+            // Note: use jccb() if label to be bound is very close to get
+            // an 8-bit displacement
+            l.addPatchAt(codeBuffer.position());
+            emitByte(0x0F);
+            emitByte(0x80 | cc.value);
+            emitInt(0);
+        }
+
+    }
+
+    public final void jccb(ConditionFlag cc, Label l) {
+        if (l.isBound()) {
+            int shortSize = 2;
+            int entry = l.position();
+            assert isByte(entry - (codeBuffer.position() + shortSize)) : "Dispacement too large for a short jmp";
+            long disp = entry - codeBuffer.position();
+            // 0111 tttn #8-bit disp
+            emitByte(0x70 | cc.value);
+            emitByte((int) ((disp - shortSize) & 0xFF));
+        } else {
+
+            l.addPatchAt(codeBuffer.position());
+            emitByte(0x70 | cc.value);
+            emitByte(0);
+        }
+    }
+
+    public final void jmp(CiAddress adr) {
+        prefix(adr);
+        emitByte(0xFF);
+        emitOperandHelper(rsp, adr);
+    }
+
+    public final void jmp(int jumpTarget, boolean forceDisp32) {
+        int shortSize = 2;
+        int longSize = 5;
+        long disp = jumpTarget - codeBuffer.position();
+        if (!forceDisp32 && isByte(disp - shortSize)) {
+            emitByte(0xEB);
+            emitByte((int) ((disp - shortSize) & 0xFF));
+        } else {
+            emitByte(0xE9);
+            emitInt((int) (disp - longSize));
+        }
+    }
+
+    @Override
+    public final void jmp(Label l) {
+        if (l.isBound()) {
+            jmp(l.position(), false);
+        } else {
+            // By default, forward jumps are always 32-bit displacements, since
+            // we can't yet know where the label will be bound. If you're sure that
+            // the forward jump will not run beyond 256 bytes, use jmpb to
+            // force an 8-bit displacement.
+
+            l.addPatchAt(codeBuffer.position());
+            emitByte(0xE9);
+            emitInt(0);
+        }
+    }
+
+    public final void jmp(CiRegister entry) {
+        int encode = prefixAndEncode(entry.encoding);
+        emitByte(0xFF);
+        emitByte(0xE0 | encode);
+    }
+
+    public final void jmpb(Label l) {
+        if (l.isBound()) {
+            int shortSize = 2;
+            int entry = l.position();
+            assert isByte((entry - codeBuffer.position()) + shortSize) : "Dispacement too large for a short jmp";
+            long offs = entry - codeBuffer.position();
+            emitByte(0xEB);
+            emitByte((int) ((offs - shortSize) & 0xFF));
+        } else {
+
+            l.addPatchAt(codeBuffer.position());
+            emitByte(0xEB);
+            emitByte(0);
+        }
+    }
+
+    public final void leaq(CiRegister dst, CiAddress src) {
+        prefixq(src, dst);
+        emitByte(0x8D);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void enter(int imm16, int imm8) {
+        emitByte(0xC8);
+        emitShort(imm16);
+        emitByte(imm8);
+    }
+
+    public final void leave() {
+        emitByte(0xC9);
+    }
+
+    public final void lock() {
+        if ((AsmOptions.Atomics & 1) != 0) {
+            // Emit either nothing, a NOP, or a NOP: prefix
+            emitByte(0x90);
+        } else {
+            emitByte(0xF0);
+        }
+    }
+
+    // Emit mfence instruction
+    public final void mfence() {
+        emitByte(0x0F);
+        emitByte(0xAE);
+        emitByte(0xF0);
+    }
+
+    public final void mov(CiRegister dst, CiRegister src) {
+        movq(dst, src);
+    }
+
+    public final void movapd(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+        int dstenc = dst.encoding;
+        int srcenc = src.encoding;
+        emitByte(0x66);
+        if (dstenc < 8) {
+            if (srcenc >= 8) {
+                emitByte(Prefix.REXB);
+                srcenc -= 8;
+            }
+        } else {
+            if (srcenc < 8) {
+                emitByte(Prefix.REXR);
+            } else {
+                emitByte(Prefix.REXRB);
+                srcenc -= 8;
+            }
+            dstenc -= 8;
+        }
+        emitByte(0x0F);
+        emitByte(0x28);
+        emitByte(0xC0 | dstenc << 3 | srcenc);
+    }
+
+    public final void movaps(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+        int dstenc = dst.encoding;
+        int srcenc = src.encoding;
+        if (dstenc < 8) {
+            if (srcenc >= 8) {
+                emitByte(Prefix.REXB);
+                srcenc -= 8;
+            }
+        } else {
+            if (srcenc < 8) {
+                emitByte(Prefix.REXR);
+            } else {
+                emitByte(Prefix.REXRB);
+                srcenc -= 8;
+            }
+            dstenc -= 8;
+        }
+        emitByte(0x0F);
+        emitByte(0x28);
+        emitByte(0xC0 | dstenc << 3 | srcenc);
+    }
+
+    public final void movb(CiRegister dst, CiAddress src) {
+        prefix(src, dst); // , true)
+        emitByte(0x8A);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movb(CiAddress dst, int imm8) {
+        prefix(dst);
+        emitByte(0xC6);
+        emitOperandHelper(rax, dst);
+        emitByte(imm8);
+    }
+
+    public final void movb(CiAddress dst, CiRegister src) {
+        assert src.isByte() : "must have byte register";
+        prefix(dst, src); // , true)
+        emitByte(0x88);
+        emitOperandHelper(src, dst);
+    }
+
+    public final void movdl(CiRegister dst, CiRegister src) {
+        if (dst.isFpu()) {
+            assert !src.isFpu() : "does this hold?";
+            emitByte(0x66);
+            int encode = prefixAndEncode(dst.encoding, src.encoding);
+            emitByte(0x0F);
+            emitByte(0x6E);
+            emitByte(0xC0 | encode);
+        } else if (src.isFpu()) {
+            assert !dst.isFpu();
+            emitByte(0x66);
+            // swap src/dst to get correct prefix
+            int encode = prefixAndEncode(src.encoding, dst.encoding);
+            emitByte(0x0F);
+            emitByte(0x7E);
+            emitByte(0xC0 | encode);
+        }
+    }
+
+    public final void movdqa(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+        emitByte(0x66);
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x6F);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movdqa(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        emitByte(0x66);
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x6F);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void movdqa(CiAddress dst, CiRegister src) {
+        assert src.isFpu();
+        emitByte(0x66);
+        prefix(dst, src);
+        emitByte(0x0F);
+        emitByte(0x7F);
+        emitOperandHelper(src, dst);
+    }
+
+    public final void movdqu(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+        emitByte(0xF3);
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x6F);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movdqu(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+
+        emitByte(0xF3);
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x6F);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void movdqu(CiAddress dst, CiRegister src) {
+        assert src.isFpu();
+
+        emitByte(0xF3);
+        prefix(dst, src);
+        emitByte(0x0F);
+        emitByte(0x7F);
+        emitOperandHelper(src, dst);
+    }
+
+    public final void movl(CiRegister dst, int imm32) {
+        int encode = prefixAndEncode(dst.encoding);
+        emitByte(0xB8 | encode);
+        emitInt(imm32);
+    }
+
+    public final void movl(CiRegister dst, CiRegister src) {
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x8B);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void movl(CiRegister dst, CiAddress src) {
+        prefix(src, dst);
+        emitByte(0x8B);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movl(CiAddress dst, int imm32) {
+        prefix(dst);
+        emitByte(0xC7);
+        emitOperandHelper(rax, dst);
+        emitInt(imm32);
+    }
+
+    public final void movl(CiAddress dst, CiRegister src) {
+        prefix(dst, src);
+        emitByte(0x89);
+        emitOperandHelper(src, dst);
+    }
+
+    /**
+     * New CPUs require use of movsd and movss to avoid partial register stall
+     * when loading from memory. But for old Opteron use movlpd instead of movsd.
+     * The selection is done in {@link AMD64MacroAssembler#movdbl(CiRegister, CiAddress)}
+     * and {@link AMD64MacroAssembler#movflt(CiRegister, CiRegister)}.
+     */
+    public final void movlpd(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+        emitByte(0x66);
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x12);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movlpd(CiAddress dst, CiRegister src) {
+        assert src.isFpu();
+        emitByte(0x66);
+        prefix(dst, src);
+        emitByte(0x0F);
+        emitByte(0x13);
+        emitOperandHelper(src, dst);
+    }
+
+    public final void movq(CiRegister dst, CiAddress src) {
+        if (dst.isFpu()) {
+            emitByte(0xF3);
+            prefixq(src, dst);
+            emitByte(0x0F);
+            emitByte(0x7E);
+            emitOperandHelper(dst, src);
+        } else {
+            prefixq(src, dst);
+            emitByte(0x8B);
+            emitOperandHelper(dst, src);
+        }
+    }
+
+    public final void movq(CiRegister dst, CiRegister src) {
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x8B);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void movq(CiAddress dst, CiRegister src) {
+        if (src.isFpu()) {
+            emitByte(0x66);
+            prefixq(dst, src);
+            emitByte(0x0F);
+            emitByte(0xD6);
+            emitOperandHelper(src, dst);
+        } else {
+            prefixq(dst, src);
+            emitByte(0x89);
+            emitOperandHelper(src, dst);
+        }
+    }
+
+    public final void movsxb(CiRegister dst, CiAddress src) { // movsxb
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0xBE);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movsxb(CiRegister dst, CiRegister src) { // movsxb
+        int encode = prefixAndEncode(dst.encoding, src.encoding, true);
+        emitByte(0x0F);
+        emitByte(0xBE);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void movsd(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+        emitByte(0xF2);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x10);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void movsd(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+        emitByte(0xF2);
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x10);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movsd(CiAddress dst, CiRegister src) {
+        assert src.isFpu();
+        emitByte(0xF2);
+        prefix(dst, src);
+        emitByte(0x0F);
+        emitByte(0x11);
+        emitOperandHelper(src, dst);
+    }
+
+    public final void movss(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+        emitByte(0xF3);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x10);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void movss(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+        emitByte(0xF3);
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x10);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movss(CiAddress dst, CiRegister src) {
+        assert src.isFpu();
+        emitByte(0xF3);
+        prefix(dst, src);
+        emitByte(0x0F);
+        emitByte(0x11);
+        emitOperandHelper(src, dst);
+    }
+
+    public final void movswl(CiRegister dst, CiAddress src) {
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0xBF);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movsxw(CiRegister dst, CiRegister src) { // movsxw
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0xBF);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void movsxw(CiRegister dst, CiAddress src) { // movsxw
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0xBF);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movzxd(CiRegister dst, CiRegister src) { // movzxd
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x63);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void movzxd(CiRegister dst, CiAddress src) { // movzxd
+        prefix(src, dst);
+        emitByte(0x63);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movw(CiAddress dst, int imm16) {
+        emitByte(0x66); // switch to 16-bit mode
+        prefix(dst);
+        emitByte(0xC7);
+        emitOperandHelper(rax, dst);
+        emitShort(imm16);
+    }
+
+    public final void movw(CiRegister dst, CiAddress src) {
+        emitByte(0x66);
+        prefix(src, dst);
+        emitByte(0x8B);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movw(CiAddress dst, CiRegister src) {
+        emitByte(0x66);
+        prefix(dst, src);
+        emitByte(0x89);
+        emitOperandHelper(src, dst);
+    }
+
+    public final void movzxb(CiRegister dst, CiAddress src) { // movzxb
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0xB6);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movzxb(CiRegister dst, CiRegister src) { // movzxb
+        int encode = prefixAndEncode(dst.encoding, src.encoding, true);
+        emitByte(0x0F);
+        emitByte(0xB6);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void movzxl(CiRegister dst, CiAddress src) { // movzxw
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0xB7);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movzxl(CiRegister dst, CiRegister src) { // movzxw
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0xB7);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void mull(CiAddress src) {
+        prefix(src);
+        emitByte(0xF7);
+        emitOperandHelper(rsp, src);
+    }
+
+    public final void mulsd(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+        emitByte(0xF2);
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x59);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void mulsd(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+
+        emitByte(0xF2);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x59);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void mulss(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+
+        emitByte(0xF3);
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x59);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void mulss(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+        emitByte(0xF3);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x59);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void negl(CiRegister dst) {
+        int encode = prefixAndEncode(dst.encoding);
+        emitByte(0xF7);
+        emitByte(0xD8 | encode);
+    }
+
+    public final void ensureUniquePC() {
+        nop();
+    }
+
+    public final void nop() {
+        nop(1);
+    }
+
+    public void nop(int count) {
+        int i = count;
+        if (AsmOptions.UseNormalNop) {
+            assert i > 0 : " ";
+            // The fancy nops aren't currently recognized by debuggers making it a
+            // pain to disassemble code while debugging. If assert are on clearly
+            // speed is not an issue so simply use the single byte traditional nop
+            // to do alignment.
+
+            for (; i > 0; i--) {
+                emitByte(0x90);
+            }
+            return;
+        }
+
+        if (AsmOptions.UseAddressNop) {
+            //
+            // Using multi-bytes nops "0x0F 0x1F [Address]" for AMD.
+            // 1: 0x90
+            // 2: 0x66 0x90
+            // 3: 0x66 0x66 0x90 (don't use "0x0F 0x1F 0x00" - need patching safe padding)
+            // 4: 0x0F 0x1F 0x40 0x00
+            // 5: 0x0F 0x1F 0x44 0x00 0x00
+            // 6: 0x66 0x0F 0x1F 0x44 0x00 0x00
+            // 7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
+            // 8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
+            // 9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
+            // 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
+            // 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
+
+            // The rest coding is AMD specific - use consecutive Address nops
+
+            // 12: 0x66 0x0F 0x1F 0x44 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00
+            // 13: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00
+            // 14: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
+            // 15: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
+            // 16: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
+            // Size prefixes (0x66) are added for larger sizes
+
+            while (i >= 22) {
+                i -= 11;
+                emitByte(0x66); // size prefix
+                emitByte(0x66); // size prefix
+                emitByte(0x66); // size prefix
+                addrNop8();
+            }
+            // Generate first nop for size between 21-12
+            switch (i) {
+                case 21:
+                    i -= 1;
+                    emitByte(0x66); // size prefix
+                    // fall through
+                case 20:
+                    // fall through
+                case 19:
+                    i -= 1;
+                    emitByte(0x66); // size prefix
+                    // fall through
+                case 18:
+                    // fall through
+                case 17:
+                    i -= 1;
+                    emitByte(0x66); // size prefix
+                    // fall through
+                case 16:
+                    // fall through
+                case 15:
+                    i -= 8;
+                    addrNop8();
+                    break;
+                case 14:
+                case 13:
+                    i -= 7;
+                    addrNop7();
+                    break;
+                case 12:
+                    i -= 6;
+                    emitByte(0x66); // size prefix
+                    addrNop5();
+                    break;
+                default:
+                    assert i < 12;
+            }
+
+            // Generate second nop for size between 11-1
+            switch (i) {
+                case 11:
+                    emitByte(0x66); // size prefix
+                    emitByte(0x66); // size prefix
+                    emitByte(0x66); // size prefix
+                    addrNop8();
+                    break;
+                case 10:
+                    emitByte(0x66); // size prefix
+                    emitByte(0x66); // size prefix
+                    addrNop8();
+                    break;
+                case 9:
+                    emitByte(0x66); // size prefix
+                    addrNop8();
+                    break;
+                case 8:
+                    addrNop8();
+                    break;
+                case 7:
+                    addrNop7();
+                    break;
+                case 6:
+                    emitByte(0x66); // size prefix
+                    addrNop5();
+                    break;
+                case 5:
+                    addrNop5();
+                    break;
+                case 4:
+                    addrNop4();
+                    break;
+                case 3:
+                    // Don't use "0x0F 0x1F 0x00" - need patching safe padding
+                    emitByte(0x66); // size prefix
+                    emitByte(0x66); // size prefix
+                    emitByte(0x90); // nop
+                    break;
+                case 2:
+                    emitByte(0x66); // size prefix
+                    emitByte(0x90); // nop
+                    break;
+                case 1:
+                    emitByte(0x90); // nop
+                    break;
+                default:
+                    assert i == 0;
+            }
+            return;
+        }
+
+        // Using nops with size prefixes "0x66 0x90".
+        // From AMD Optimization Guide:
+        // 1: 0x90
+        // 2: 0x66 0x90
+        // 3: 0x66 0x66 0x90
+        // 4: 0x66 0x66 0x66 0x90
+        // 5: 0x66 0x66 0x90 0x66 0x90
+        // 6: 0x66 0x66 0x90 0x66 0x66 0x90
+        // 7: 0x66 0x66 0x66 0x90 0x66 0x66 0x90
+        // 8: 0x66 0x66 0x66 0x90 0x66 0x66 0x66 0x90
+        // 9: 0x66 0x66 0x90 0x66 0x66 0x90 0x66 0x66 0x90
+        // 10: 0x66 0x66 0x66 0x90 0x66 0x66 0x90 0x66 0x66 0x90
+        //
+        while (i > 12) {
+            i -= 4;
+            emitByte(0x66); // size prefix
+            emitByte(0x66);
+            emitByte(0x66);
+            emitByte(0x90); // nop
+        }
+        // 1 - 12 nops
+        if (i > 8) {
+            if (i > 9) {
+                i -= 1;
+                emitByte(0x66);
+            }
+            i -= 3;
+            emitByte(0x66);
+            emitByte(0x66);
+            emitByte(0x90);
+        }
+        // 1 - 8 nops
+        if (i > 4) {
+            if (i > 6) {
+                i -= 1;
+                emitByte(0x66);
+            }
+            i -= 3;
+            emitByte(0x66);
+            emitByte(0x66);
+            emitByte(0x90);
+        }
+        switch (i) {
+            case 4:
+                emitByte(0x66);
+                emitByte(0x66);
+                emitByte(0x66);
+                emitByte(0x90);
+                break;
+            case 3:
+                emitByte(0x66);
+                emitByte(0x66);
+                emitByte(0x90);
+                break;
+            case 2:
+                emitByte(0x66);
+                emitByte(0x90);
+                break;
+            case 1:
+                emitByte(0x90);
+                break;
+            default:
+                assert i == 0;
+        }
+    }
+
+    public final void notl(CiRegister dst) {
+        int encode = prefixAndEncode(dst.encoding);
+        emitByte(0xF7);
+        emitByte(0xD0 | encode);
+    }
+
+    public final void orl(CiAddress dst, int imm32) {
+        prefix(dst);
+        emitByte(0x81);
+        emitOperandHelper(rcx, dst);
+        emitInt(imm32);
+    }
+
+    public final void orl(CiRegister dst, int imm32) {
+        prefix(dst);
+        emitArith(0x81, 0xC8, dst, imm32);
+    }
+
+    public final void orl(CiRegister dst, CiAddress src) {
+        prefix(src, dst);
+        emitByte(0x0B);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void orl(CiRegister dst, CiRegister src) {
+        prefixAndEncode(dst.encoding, src.encoding);
+        emitArith(0x0B, 0xC0, dst, src);
+    }
+
+    // generic
+    public final void pop(CiRegister dst) {
+        int encode = prefixAndEncode(dst.encoding);
+        emitByte(0x58 | encode);
+    }
+
+    public final void prefetchPrefix(CiAddress src) {
+        prefix(src);
+        emitByte(0x0F);
+    }
+
+    public final void prefetchnta(CiAddress src) {
+        prefetchPrefix(src);
+        emitByte(0x18);
+        emitOperandHelper(rax, src); // 0, src
+    }
+
+    public final void prefetchr(CiAddress src) {
+        prefetchPrefix(src);
+        emitByte(0x0D);
+        emitOperandHelper(rax, src); // 0, src
+    }
+
+    public final void prefetcht0(CiAddress src) {
+        prefetchPrefix(src);
+        emitByte(0x18);
+        emitOperandHelper(rcx, src); // 1, src
+
+    }
+
+    public final void prefetcht1(CiAddress src) {
+        prefetchPrefix(src);
+        emitByte(0x18);
+        emitOperandHelper(rdx, src); // 2, src
+    }
+
+    public final void prefetcht2(CiAddress src) {
+        prefetchPrefix(src);
+        emitByte(0x18);
+        emitOperandHelper(rbx, src); // 3, src
+    }
+
+    public final void prefetchw(CiAddress src) {
+        prefetchPrefix(src);
+        emitByte(0x0D);
+        emitOperandHelper(rcx, src); // 1, src
+    }
+
+    public final void pshufd(CiRegister dst, CiRegister src, int mode) {
+        assert dst.isFpu();
+        assert src.isFpu();
+        assert isUByte(mode) : "invalid value";
+
+        emitByte(0x66);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x70);
+        emitByte(0xC0 | encode);
+        emitByte(mode & 0xFF);
+    }
+
+    public final void pshufd(CiRegister dst, CiAddress src, int mode) {
+        assert dst.isFpu();
+        assert isUByte(mode) : "invalid value";
+
+        emitByte(0x66);
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x70);
+        emitOperandHelper(dst, src);
+        emitByte(mode & 0xFF);
+
+    }
+
+    public final void pshuflw(CiRegister dst, CiRegister src, int mode) {
+        assert dst.isFpu();
+        assert src.isFpu();
+        assert isUByte(mode) : "invalid value";
+
+        emitByte(0xF2);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x70);
+        emitByte(0xC0 | encode);
+        emitByte(mode & 0xFF);
+    }
+
+    public final void pshuflw(CiRegister dst, CiAddress src, int mode) {
+        assert dst.isFpu();
+        assert isUByte(mode) : "invalid value";
+
+        emitByte(0xF2);
+        prefix(src, dst); // QQ new
+        emitByte(0x0F);
+        emitByte(0x70);
+        emitOperandHelper(dst, src);
+        emitByte(mode & 0xFF);
+    }
+
+    public final void psrlq(CiRegister dst, int shift) {
+        assert dst.isFpu();
+        // HMM Table D-1 says sse2 or mmx
+
+        int encode = prefixqAndEncode(xmm2.encoding, dst.encoding);
+        emitByte(0x66);
+        emitByte(0x0F);
+        emitByte(0x73);
+        emitByte(0xC0 | encode);
+        emitByte(shift);
+    }
+
+    public final void punpcklbw(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+        emitByte(0x66);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x60);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void push(int imm32) {
+        // in 64bits we push 64bits onto the stack but only
+        // take a 32bit immediate
+        emitByte(0x68);
+        emitInt(imm32);
+    }
+
+    public final void push(CiRegister src) {
+        int encode = prefixAndEncode(src.encoding);
+        emitByte(0x50 | encode);
+    }
+
+    public final void pushf() {
+        emitByte(0x9C);
+    }
+
+    public final void pxor(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+
+        emitByte(0x66);
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0xEF);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void pxor(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+
+        emitByte(0x66);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0xEF);
+        emitByte(0xC0 | encode);
+
+    }
+
+    public final void rcll(CiRegister dst, int imm8) {
+        assert isShiftCount(imm8) : "illegal shift count";
+        int encode = prefixAndEncode(dst.encoding);
+        if (imm8 == 1) {
+            emitByte(0xD1);
+            emitByte(0xD0 | encode);
+        } else {
+            emitByte(0xC1);
+            emitByte(0xD0 | encode);
+            emitByte(imm8);
+        }
+    }
+
+    public final void pause() {
+        emitByte(0xF3);
+        emitByte(0x90);
+    }
+
+    // Copies data from [X86.rsi] to [X86.rdi] using X86.rcx heap words.
+    public final void repeatMoveWords() {
+        emitByte(0xF3);
+        emitByte(Prefix.REXW);
+        emitByte(0xA5);
+    }
+
+    // Copies data from [X86.rsi] to [X86.rdi] using X86.rcx bytes.
+    public final void repeatMoveBytes() {
+        emitByte(0xF3);
+        emitByte(Prefix.REXW);
+        emitByte(0xA4);
+    }
+
+    // sets X86.rcx pointer sized words with X86.rax, value at [edi]
+    // generic
+    public final void repSet() { // repSet
+        emitByte(0xF3);
+        // STOSQ
+        emitByte(Prefix.REXW);
+        emitByte(0xAB);
+    }
+
+    // scans X86.rcx pointer sized words at [edi] for occurance of X86.rax,
+    // generic
+    public final void repneScan() { // repneScan
+        emitByte(0xF2);
+        // SCASQ
+        emitByte(Prefix.REXW);
+        emitByte(0xAF);
+    }
+
+    // scans X86.rcx 4 byte words at [edi] for occurance of X86.rax,
+    // generic
+    public final void repneScanl() { // repneScan
+        emitByte(0xF2);
+        // SCASL
+        emitByte(0xAF);
+    }
+
+    public final void ret(int imm16) {
+        if (imm16 == 0) {
+            emitByte(0xC3);
+        } else {
+            emitByte(0xC2);
+            emitShort(imm16);
+        }
+    }
+
+    public final void sarl(CiRegister dst, int imm8) {
+        int encode = prefixAndEncode(dst.encoding);
+        assert isShiftCount(imm8) : "illegal shift count";
+        if (imm8 == 1) {
+            emitByte(0xD1);
+            emitByte(0xF8 | encode);
+        } else {
+            emitByte(0xC1);
+            emitByte(0xF8 | encode);
+            emitByte(imm8);
+        }
+    }
+
+    public final void sarl(CiRegister dst) {
+        int encode = prefixAndEncode(dst.encoding);
+        emitByte(0xD3);
+        emitByte(0xF8 | encode);
+    }
+
+    public final void sbbl(CiAddress dst, int imm32) {
+        prefix(dst);
+        emitArithOperand(0x81, rbx, dst, imm32);
+    }
+
+    public final void sbbl(CiRegister dst, int imm32) {
+        prefix(dst);
+        emitArith(0x81, 0xD8, dst, imm32);
+    }
+
+    public final void sbbl(CiRegister dst, CiAddress src) {
+        prefix(src, dst);
+        emitByte(0x1B);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void sbbl(CiRegister dst, CiRegister src) {
+        prefixAndEncode(dst.encoding, src.encoding);
+        emitArith(0x1B, 0xC0, dst, src);
+    }
+
+    public final void setb(ConditionFlag cc, CiRegister dst) {
+        assert 0 <= cc.value && cc.value < 16 : "illegal cc";
+        int encode = prefixAndEncode(dst.encoding, true);
+        emitByte(0x0F);
+        emitByte(0x90 | cc.value);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void shll(CiRegister dst, int imm8) {
+        assert isShiftCount(imm8) : "illegal shift count";
+        int encode = prefixAndEncode(dst.encoding);
+        if (imm8 == 1) {
+            emitByte(0xD1);
+            emitByte(0xE0 | encode);
+        } else {
+            emitByte(0xC1);
+            emitByte(0xE0 | encode);
+            emitByte(imm8);
+        }
+    }
+
+    public final void shll(CiRegister dst) {
+        int encode = prefixAndEncode(dst.encoding);
+        emitByte(0xD3);
+        emitByte(0xE0 | encode);
+    }
+
+    public final void shrl(CiRegister dst, int imm8) {
+        assert isShiftCount(imm8) : "illegal shift count";
+        int encode = prefixAndEncode(dst.encoding);
+        emitByte(0xC1);
+        emitByte(0xE8 | encode);
+        emitByte(imm8);
+    }
+
+    public final void shrl(CiRegister dst) {
+        int encode = prefixAndEncode(dst.encoding);
+        emitByte(0xD3);
+        emitByte(0xE8 | encode);
+    }
+
+    // copies a single word from [esi] to [edi]
+    public final void smovl() {
+        emitByte(0xA5);
+    }
+
+    public final void sqrtsd(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+        // HMM Table D-1 says sse2
+        // assert is64 || target.supportsSSE();
+        emitByte(0xF2);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x51);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void subl(CiAddress dst, int imm32) {
+        prefix(dst);
+        if (isByte(imm32)) {
+            emitByte(0x83);
+            emitOperandHelper(rbp, dst);
+            emitByte(imm32 & 0xFF);
+        } else {
+            emitByte(0x81);
+            emitOperandHelper(rbp, dst);
+            emitInt(imm32);
+        }
+    }
+
+    public final void subl(CiRegister dst, int imm32) {
+        prefix(dst);
+        emitArith(0x81, 0xE8, dst, imm32);
+    }
+
+    public final void subl(CiAddress dst, CiRegister src) {
+        prefix(dst, src);
+        emitByte(0x29);
+        emitOperandHelper(src, dst);
+    }
+
+    public final void subl(CiRegister dst, CiAddress src) {
+        prefix(src, dst);
+        emitByte(0x2B);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void subl(CiRegister dst, CiRegister src) {
+        prefixAndEncode(dst.encoding, src.encoding);
+        emitArith(0x2B, 0xC0, dst, src);
+    }
+
+    public final void subsd(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+        emitByte(0xF2);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x5C);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void subsd(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+
+        emitByte(0xF2);
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x5C);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void subss(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+        emitByte(0xF3);
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x5C);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void subss(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+
+        emitByte(0xF3);
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x5C);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void testb(CiRegister dst, int imm8) {
+        prefixAndEncode(dst.encoding, true);
+        emitArithB(0xF6, 0xC0, dst, imm8);
+    }
+
+    public final void testl(CiRegister dst, int imm32) {
+        // not using emitArith because test
+        // doesn't support sign-extension of
+        // 8bit operands
+        int encode = dst.encoding;
+        if (encode == 0) {
+            emitByte(0xA9);
+        } else {
+            encode = prefixAndEncode(encode);
+            emitByte(0xF7);
+            emitByte(0xC0 | encode);
+        }
+        emitInt(imm32);
+    }
+
+    public final void testl(CiRegister dst, CiRegister src) {
+        prefixAndEncode(dst.encoding, src.encoding);
+        emitArith(0x85, 0xC0, dst, src);
+    }
+
+    public final void testl(CiRegister dst, CiAddress src) {
+        prefix(src, dst);
+        emitByte(0x85);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void ucomisd(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+        emitByte(0x66);
+        ucomiss(dst, src);
+    }
+
+    public final void ucomisd(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+        emitByte(0x66);
+        ucomiss(dst, src);
+    }
+
+    public final void ucomiss(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x2E);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void ucomiss(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        assert src.isFpu();
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x2E);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void xaddl(CiAddress dst, CiRegister src) {
+        assert src.isFpu();
+
+        prefix(dst, src);
+        emitByte(0x0F);
+        emitByte(0xC1);
+        emitOperandHelper(src, dst);
+    }
+
+    public final void xchgl(CiRegister dst, CiAddress src) { // xchg
+        prefix(src, dst);
+        emitByte(0x87);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void xchgl(CiRegister dst, CiRegister src) {
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x87);
+        emitByte(0xc0 | encode);
+    }
+
+    public final void xorl(CiRegister dst, int imm32) {
+        prefix(dst);
+        emitArith(0x81, 0xF0, dst, imm32);
+    }
+
+    public final void xorl(CiRegister dst, CiAddress src) {
+        prefix(src, dst);
+        emitByte(0x33);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void xorl(CiRegister dst, CiRegister src) {
+        prefixAndEncode(dst.encoding, src.encoding);
+        emitArith(0x33, 0xC0, dst, src);
+    }
+
+    public final void andpd(CiRegister dst, CiRegister src) {
+        emitByte(0x66);
+        andps(dst, src);
+    }
+
+    public final void andpd(CiRegister dst, CiAddress src) {
+        emitByte(0x66);
+        andps(dst, src);
+    }
+
+    public final void andps(CiRegister dst, CiRegister src) {
+        assert dst.isFpu() && src.isFpu();
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x54);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void andps(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x54);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void orpd(CiRegister dst, CiRegister src) {
+        emitByte(0x66);
+        orps(dst, src);
+    }
+
+    public final void orpd(CiRegister dst, CiAddress src) {
+        emitByte(0x66);
+        orps(dst, src);
+    }
+
+    public final void orps(CiRegister dst, CiRegister src) {
+        assert dst.isFpu() && src.isFpu();
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x56);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void orps(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x56);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void xorpd(CiRegister dst, CiRegister src) {
+        emitByte(0x66);
+        xorps(dst, src);
+    }
+
+    public final void xorpd(CiRegister dst, CiAddress src) {
+        emitByte(0x66);
+        xorps(dst, src);
+    }
+
+    public final void xorps(CiRegister dst, CiRegister src) {
+        assert dst.isFpu() && src.isFpu();
+        int encode = prefixAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x57);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void xorps(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x57);
+        emitOperandHelper(dst, src);
+    }
+
+    // 32bit only pieces of the assembler
+
+    public final void decl(CiRegister dst) {
+        // Don't use it directly. Use Macrodecrementl() instead.
+        // Use two-byte form (one-byte form is a REX prefix in 64-bit mode)
+        int encode = prefixAndEncode(dst.encoding);
+        emitByte(0xFF);
+        emitByte(0xC8 | encode);
+    }
+
+    public final void incl(CiRegister dst) {
+        // Don't use it directly. Use Macroincrementl() instead.
+        // Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
+        int encode = prefixAndEncode(dst.encoding);
+        emitByte(0xFF);
+        emitByte(0xC0 | encode);
+    }
+
+    int prefixAndEncode(int regEnc) {
+        return prefixAndEncode(regEnc, false);
+    }
+
+    int prefixAndEncode(int regEnc, boolean byteinst) {
+        if (regEnc >= 8) {
+            emitByte(Prefix.REXB);
+            return regEnc - 8;
+        } else if (byteinst && regEnc >= 4) {
+            emitByte(Prefix.REX);
+        }
+        return regEnc;
+    }
+
+    int prefixqAndEncode(int regEnc) {
+        if (regEnc < 8) {
+            emitByte(Prefix.REXW);
+            return regEnc;
+        } else {
+            emitByte(Prefix.REXWB);
+            return regEnc - 8;
+        }
+    }
+
+    int prefixAndEncode(int dstEnc, int srcEnc) {
+        return prefixAndEncode(dstEnc, srcEnc, false);
+    }
+
+    int prefixAndEncode(int dstEncoding, int srcEncoding, boolean byteinst) {
+        int srcEnc = srcEncoding;
+        int dstEnc = dstEncoding;
+        if (dstEnc < 8) {
+            if (srcEnc >= 8) {
+                emitByte(Prefix.REXB);
+                srcEnc -= 8;
+            } else if (byteinst && srcEnc >= 4) {
+                emitByte(Prefix.REX);
+            }
+        } else {
+            if (srcEnc < 8) {
+                emitByte(Prefix.REXR);
+            } else {
+                emitByte(Prefix.REXRB);
+                srcEnc -= 8;
+            }
+            dstEnc -= 8;
+        }
+        return dstEnc << 3 | srcEnc;
+    }
+
+    /**
+     * Creates prefix and the encoding of the lower 6 bits of the ModRM-Byte. It emits an operand prefix. If the given
+     * operands exceed 3 bits, the 4th bit is encoded in the prefix.
+     *
+     * @param regEnc the encoding of the register part of the ModRM-Byte
+     * @param rmEnc the encoding of the r/m part of the ModRM-Byte
+     * @return the lower 6 bits of the ModRM-Byte that should be emitted
+     */
+    private int prefixqAndEncode(int regEncoding, int rmEncoding) {
+        int rmEnc = rmEncoding;
+        int regEnc = regEncoding;
+        if (regEnc < 8) {
+            if (rmEnc < 8) {
+                emitByte(Prefix.REXW);
+            } else {
+                emitByte(Prefix.REXWB);
+                rmEnc -= 8;
+            }
+        } else {
+            if (rmEnc < 8) {
+                emitByte(Prefix.REXWR);
+            } else {
+                emitByte(Prefix.REXWRB);
+                rmEnc -= 8;
+            }
+            regEnc -= 8;
+        }
+        return regEnc << 3 | rmEnc;
+    }
+
+    private void prefix(CiRegister reg) {
+        if (reg.encoding >= 8) {
+            emitByte(Prefix.REXB);
+        }
+    }
+
+    private static boolean needsRex(CiValue value) {
+        return isRegister(value) && asRegister(value).encoding >= MinEncodingNeedsRex;
+    }
+
+
+    private void prefix(CiAddress adr) {
+        if (needsRex(adr.base)) {
+            if (needsRex(adr.index)) {
+                emitByte(Prefix.REXXB);
+            } else {
+                emitByte(Prefix.REXB);
+            }
+        } else {
+            if (needsRex(adr.index)) {
+                emitByte(Prefix.REXX);
+            }
+        }
+    }
+
+    private void prefixq(CiAddress adr) {
+        if (needsRex(adr.base)) {
+            if (needsRex(adr.index)) {
+                emitByte(Prefix.REXWXB);
+            } else {
+                emitByte(Prefix.REXWB);
+            }
+        } else {
+            if (needsRex(adr.index)) {
+                emitByte(Prefix.REXWX);
+            } else {
+                emitByte(Prefix.REXW);
+            }
+        }
+    }
+
+    private void prefix(CiAddress adr, CiRegister reg) {
+        if (reg.encoding < 8) {
+            if (needsRex(adr.base)) {
+                if (needsRex(adr.index)) {
+                    emitByte(Prefix.REXXB);
+                } else {
+                    emitByte(Prefix.REXB);
+                }
+            } else {
+                if (needsRex(adr.index)) {
+                    emitByte(Prefix.REXX);
+                } else if (reg.encoding >= 4) {
+                    emitByte(Prefix.REX);
+                }
+            }
+        } else {
+            if (needsRex(adr.base)) {
+                if (needsRex(adr.index)) {
+                    emitByte(Prefix.REXRXB);
+                } else {
+                    emitByte(Prefix.REXRB);
+                }
+            } else {
+                if (needsRex(adr.index)) {
+                    emitByte(Prefix.REXRX);
+                } else {
+                    emitByte(Prefix.REXR);
+                }
+            }
+        }
+    }
+
+    private void prefixq(CiAddress adr, CiRegister src) {
+        if (src.encoding < 8) {
+            if (needsRex(adr.base)) {
+                if (needsRex(adr.index)) {
+                    emitByte(Prefix.REXWXB);
+                } else {
+                    emitByte(Prefix.REXWB);
+                }
+            } else {
+                if (needsRex(adr.index)) {
+                    emitByte(Prefix.REXWX);
+                } else {
+                    emitByte(Prefix.REXW);
+                }
+            }
+        } else {
+            if (needsRex(adr.base)) {
+                if (needsRex(adr.index)) {
+                    emitByte(Prefix.REXWRXB);
+                } else {
+                    emitByte(Prefix.REXWRB);
+                }
+            } else {
+                if (needsRex(adr.index)) {
+                    emitByte(Prefix.REXWRX);
+                } else {
+                    emitByte(Prefix.REXWR);
+                }
+            }
+        }
+    }
+
+    public final void addq(CiAddress dst, int imm32) {
+        prefixq(dst);
+        emitArithOperand(0x81, rax, dst, imm32);
+    }
+
+    public final void addq(CiAddress dst, CiRegister src) {
+        prefixq(dst, src);
+        emitByte(0x01);
+        emitOperandHelper(src, dst);
+    }
+
+    public final void addq(CiRegister dst, int imm32) {
+        prefixqAndEncode(dst.encoding);
+        emitArith(0x81, 0xC0, dst, imm32);
+    }
+
+    public final void addq(CiRegister dst, CiAddress src) {
+        prefixq(src, dst);
+        emitByte(0x03);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void addq(CiRegister dst, CiRegister src) {
+        prefixqAndEncode(dst.encoding, src.encoding);
+        emitArith(0x03, 0xC0, dst, src);
+    }
+
+    public final void andq(CiRegister dst, int imm32) {
+        prefixqAndEncode(dst.encoding);
+        emitArith(0x81, 0xE0, dst, imm32);
+    }
+
+    public final void andq(CiRegister dst, CiAddress src) {
+        prefixq(src, dst);
+        emitByte(0x23);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void andq(CiRegister dst, CiRegister src) {
+        prefixqAndEncode(dst.encoding, src.encoding);
+        emitArith(0x23, 0xC0, dst, src);
+    }
+
+    public final void bswapq(CiRegister reg) {
+        int encode = prefixqAndEncode(reg.encoding);
+        emitByte(0x0F);
+        emitByte(0xC8 | encode);
+    }
+
+    public final void cdqq() {
+        emitByte(Prefix.REXW);
+        emitByte(0x99);
+    }
+
+    public final void cmovq(ConditionFlag cc, CiRegister dst, CiRegister src) {
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x40 | cc.value);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void cmovq(ConditionFlag cc, CiRegister dst, CiAddress src) {
+        prefixq(src, dst);
+        emitByte(0x0F);
+        emitByte(0x40 | cc.value);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void cmpq(CiAddress dst, int imm32) {
+        prefixq(dst);
+        emitByte(0x81);
+        emitOperandHelper(rdi, dst);
+        emitInt(imm32);
+    }
+
+    public final void cmpq(CiRegister dst, int imm32) {
+        prefixqAndEncode(dst.encoding);
+        emitArith(0x81, 0xF8, dst, imm32);
+    }
+
+    public final void cmpq(CiAddress dst, CiRegister src) {
+        prefixq(dst, src);
+        emitByte(0x3B);
+        emitOperandHelper(src, dst);
+    }
+
+    public final void cmpq(CiRegister dst, CiRegister src) {
+        prefixqAndEncode(dst.encoding, src.encoding);
+        emitArith(0x3B, 0xC0, dst, src);
+    }
+
+    public final void cmpq(CiRegister dst, CiAddress src) {
+        prefixq(src, dst);
+        emitByte(0x3B);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void cmpxchgq(CiRegister reg, CiAddress adr) {
+        prefixq(adr, reg);
+        emitByte(0x0F);
+        emitByte(0xB1);
+        emitOperandHelper(reg, adr);
+    }
+
+    public final void cvtsi2sdq(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        emitByte(0xF2);
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x2A);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void cvtsi2ssq(CiRegister dst, CiRegister src) {
+        assert dst.isFpu();
+        emitByte(0xF3);
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x2A);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void cvttsd2siq(CiRegister dst, CiRegister src) {
+        assert src.isFpu();
+        emitByte(0xF2);
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x2C);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void cvttss2siq(CiRegister dst, CiRegister src) {
+        assert src.isFpu();
+        emitByte(0xF3);
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0x2C);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void decq(CiRegister dst) {
+        // Don't use it directly. Use Macrodecrementq() instead.
+        // Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
+        int encode = prefixqAndEncode(dst.encoding);
+        emitByte(0xFF);
+        emitByte(0xC8 | encode);
+    }
+
+    public final void decq(CiAddress dst) {
+        // Don't use it directly. Use Macrodecrementq() instead.
+        prefixq(dst);
+        emitByte(0xFF);
+        emitOperandHelper(rcx, dst);
+    }
+
+    public final void divq(CiRegister src) {
+        int encode = prefixqAndEncode(src.encoding);
+        emitByte(0xF7);
+        emitByte(0xF0 | encode);
+    }
+
+    public final void idivq(CiRegister src) {
+        int encode = prefixqAndEncode(src.encoding);
+        emitByte(0xF7);
+        emitByte(0xF8 | encode);
+    }
+
+    public final void imulq(CiRegister dst, CiRegister src) {
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0xAF);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void imulq(CiRegister dst, CiRegister src, int value) {
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        if (isByte(value)) {
+            emitByte(0x6B);
+            emitByte(0xC0 | encode);
+            emitByte(value);
+        } else {
+            emitByte(0x69);
+            emitByte(0xC0 | encode);
+            emitInt(value);
+        }
+    }
+
+    public final void incq(CiRegister dst) {
+        // Don't use it directly. Use Macroincrementq() instead.
+        // Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
+        int encode = prefixqAndEncode(dst.encoding);
+        emitByte(0xFF);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void incq(CiAddress dst) {
+        // Don't use it directly. Use Macroincrementq() instead.
+        prefixq(dst);
+        emitByte(0xFF);
+        emitOperandHelper(rax, dst);
+    }
+
+    public final void movq(CiRegister dst, long imm64) {
+        int encode = prefixqAndEncode(dst.encoding);
+        emitByte(0xB8 | encode);
+        emitLong(imm64);
+    }
+
+    public final void movdq(CiRegister dst, CiRegister src) {
+
+        // table D-1 says MMX/SSE2
+        emitByte(0x66);
+
+        if (dst.isFpu()) {
+            assert dst.isFpu();
+            int encode = prefixqAndEncode(dst.encoding, src.encoding);
+            emitByte(0x0F);
+            emitByte(0x6E);
+            emitByte(0xC0 | encode);
+        } else if (src.isFpu()) {
+
+            // swap src/dst to get correct prefix
+            int encode = prefixqAndEncode(src.encoding, dst.encoding);
+            emitByte(0x0F);
+            emitByte(0x7E);
+            emitByte(0xC0 | encode);
+        } else {
+            throw new InternalError("should not reach here");
+        }
+    }
+
+    public final void movsbq(CiRegister dst, CiAddress src) {
+        prefixq(src, dst);
+        emitByte(0x0F);
+        emitByte(0xBE);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movsbq(CiRegister dst, CiRegister src) {
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0xBE);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void movslq(CiRegister dst, int imm32) {
+        int encode = prefixqAndEncode(dst.encoding);
+        emitByte(0xC7 | encode);
+        emitInt(imm32);
+        // dbx shows movslq(X86.rcx, 3) as movq $0x0000000049000000,(%X86.rbx)
+        // and movslq(X86.r8, 3); as movl $0x0000000048000000,(%X86.rbx)
+        // as a result we shouldn't use until tested at runtime...
+        throw new InternalError("untested");
+    }
+
+    public final void movslq(CiAddress dst, int imm32) {
+        prefixq(dst);
+        emitByte(0xC7);
+        emitOperandHelper(rax, dst);
+        emitInt(imm32);
+    }
+
+    public final void movslq(CiRegister dst, CiAddress src) {
+        prefixq(src, dst);
+        emitByte(0x63);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movslq(CiRegister dst, CiRegister src) {
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x63);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void movswq(CiRegister dst, CiAddress src) {
+        prefixq(src, dst);
+        emitByte(0x0F);
+        emitByte(0xBF);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movswq(CiRegister dst, CiRegister src) {
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0xBF);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void movzbq(CiRegister dst, CiAddress src) {
+        prefixq(src, dst);
+        emitByte(0x0F);
+        emitByte(0xB6);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movzbq(CiRegister dst, CiRegister src) {
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0xB6);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void movzwq(CiRegister dst, CiAddress src) {
+        prefixq(src, dst);
+        emitByte(0x0F);
+        emitByte(0xB7);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void movzwq(CiRegister dst, CiRegister src) {
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x0F);
+        emitByte(0xB7);
+        emitByte(0xC0 | encode);
+    }
+
+    public final void negq(CiRegister dst) {
+        int encode = prefixqAndEncode(dst.encoding);
+        emitByte(0xF7);
+        emitByte(0xD8 | encode);
+    }
+
+    public final void notq(CiRegister dst) {
+        int encode = prefixqAndEncode(dst.encoding);
+        emitByte(0xF7);
+        emitByte(0xD0 | encode);
+    }
+
+    public final void orq(CiAddress dst, int imm32) {
+        prefixq(dst);
+        emitByte(0x81);
+        emitOperandHelper(rcx, dst);
+        emitInt(imm32);
+    }
+
+    public final void orq(CiRegister dst, int imm32) {
+        prefixqAndEncode(dst.encoding);
+        emitArith(0x81, 0xC8, dst, imm32);
+    }
+
+    public final void orq(CiRegister dst, CiAddress src) {
+        prefixq(src, dst);
+        emitByte(0x0B);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void orq(CiRegister dst, CiRegister src) {
+        prefixqAndEncode(dst.encoding, src.encoding);
+        emitArith(0x0B, 0xC0, dst, src);
+    }
+
+    public final void popq(CiAddress dst) {
+        prefixq(dst);
+        emitByte(0x8F);
+        emitOperandHelper(rax, dst);
+    }
+
+    public final void pushq(CiAddress src) {
+        prefixq(src);
+        emitByte(0xFF);
+        emitOperandHelper(rsi, src);
+    }
+
+    public final void rclq(CiRegister dst, int imm8) {
+        assert isShiftCount(imm8 >> 1) : "illegal shift count";
+        int encode = prefixqAndEncode(dst.encoding);
+        if (imm8 == 1) {
+            emitByte(0xD1);
+            emitByte(0xD0 | encode);
+        } else {
+            emitByte(0xC1);
+            emitByte(0xD0 | encode);
+            emitByte(imm8);
+        }
+    }
+
+    public final void sarq(CiRegister dst, int imm8) {
+        assert isShiftCount(imm8 >> 1) : "illegal shift count";
+        int encode = prefixqAndEncode(dst.encoding);
+        if (imm8 == 1) {
+            emitByte(0xD1);
+            emitByte(0xF8 | encode);
+        } else {
+            emitByte(0xC1);
+            emitByte(0xF8 | encode);
+            emitByte(imm8);
+        }
+    }
+
+    public final void sarq(CiRegister dst) {
+        int encode = prefixqAndEncode(dst.encoding);
+        emitByte(0xD3);
+        emitByte(0xF8 | encode);
+    }
+
+    public final void shlq(CiRegister dst, int imm8) {
+        assert isShiftCount(imm8 >> 1) : "illegal shift count";
+        int encode = prefixqAndEncode(dst.encoding);
+        if (imm8 == 1) {
+            emitByte(0xD1);
+            emitByte(0xE0 | encode);
+        } else {
+            emitByte(0xC1);
+            emitByte(0xE0 | encode);
+            emitByte(imm8);
+        }
+    }
+
+    public final void shlq(CiRegister dst) {
+        int encode = prefixqAndEncode(dst.encoding);
+        emitByte(0xD3);
+        emitByte(0xE0 | encode);
+    }
+
+    public final void shrq(CiRegister dst, int imm8) {
+        assert isShiftCount(imm8 >> 1) : "illegal shift count";
+        int encode = prefixqAndEncode(dst.encoding);
+        emitByte(0xC1);
+        emitByte(0xE8 | encode);
+        emitByte(imm8);
+    }
+
+    public final void shrq(CiRegister dst) {
+        int encode = prefixqAndEncode(dst.encoding);
+        emitByte(0xD3);
+        emitByte(0xE8 | encode);
+    }
+
+    public final void sqrtsd(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+
+        emitByte(0xF2);
+        prefix(src, dst);
+        emitByte(0x0F);
+        emitByte(0x51);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void subq(CiAddress dst, int imm32) {
+        prefixq(dst);
+        if (isByte(imm32)) {
+            emitByte(0x83);
+            emitOperandHelper(rbp, dst);
+            emitByte(imm32 & 0xFF);
+        } else {
+            emitByte(0x81);
+            emitOperandHelper(rbp, dst);
+            emitInt(imm32);
+        }
+    }
+
+    public final void subq(CiRegister dst, int imm32) {
+        prefixqAndEncode(dst.encoding);
+        emitArith(0x81, 0xE8, dst, imm32);
+    }
+
+    public final void subq(CiAddress dst, CiRegister src) {
+        prefixq(dst, src);
+        emitByte(0x29);
+        emitOperandHelper(src, dst);
+    }
+
+    public final void subq(CiRegister dst, CiAddress src) {
+        prefixq(src, dst);
+        emitByte(0x2B);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void subq(CiRegister dst, CiRegister src) {
+        prefixqAndEncode(dst.encoding, src.encoding);
+        emitArith(0x2B, 0xC0, dst, src);
+    }
+
+    public final void testq(CiRegister dst, int imm32) {
+        // not using emitArith because test
+        // doesn't support sign-extension of
+        // 8bit operands
+        int encode = dst.encoding;
+        if (encode == 0) {
+            emitByte(Prefix.REXW);
+            emitByte(0xA9);
+        } else {
+            encode = prefixqAndEncode(encode);
+            emitByte(0xF7);
+            emitByte(0xC0 | encode);
+        }
+        emitInt(imm32);
+    }
+
+    public final void testq(CiRegister dst, CiRegister src) {
+        prefixqAndEncode(dst.encoding, src.encoding);
+        emitArith(0x85, 0xC0, dst, src);
+    }
+
+    public final void xaddq(CiAddress dst, CiRegister src) {
+        prefixq(dst, src);
+        emitByte(0x0F);
+        emitByte(0xC1);
+        emitOperandHelper(src, dst);
+    }
+
+    public final void xchgq(CiRegister dst, CiAddress src) {
+        prefixq(src, dst);
+        emitByte(0x87);
+        emitOperandHelper(dst, src);
+    }
+
+    public final void xchgq(CiRegister dst, CiRegister src) {
+        int encode = prefixqAndEncode(dst.encoding, src.encoding);
+        emitByte(0x87);
+        emitByte(0xc0 | encode);
+    }
+
+    public final void xorq(CiRegister dst, int imm32) {
+        prefixqAndEncode(dst.encoding);
+        emitArith(0x81, 0xF0, dst, imm32);
+    }
+
+    public final void xorq(CiRegister dst, CiRegister src) {
+        prefixqAndEncode(dst.encoding, src.encoding);
+        emitArith(0x33, 0xC0, dst, src);
+    }
+
+    public final void xorq(CiRegister dst, CiAddress src) {
+
+        prefixq(src, dst);
+        emitByte(0x33);
+        emitOperandHelper(dst, src);
+
+    }
+
+    public final void membar(int barriers) {
+        if (target.isMP) {
+            // We only have to handle StoreLoad
+            if ((barriers & STORE_LOAD) != 0) {
+                // All usable chips support "locked" instructions which suffice
+                // as barriers, and are much faster than the alternative of
+                // using cpuid instruction. We use here a locked add [rsp],0.
+                // This is conveniently otherwise a no-op except for blowing
+                // flags.
+                // Any change to this code may need to revisit other places in
+                // the code where this idiom is used, in particular the
+                // orderAccess code.
+                lock();
+                addl(new CiAddress(Word, RSP, 0), 0); // Assert the lock# signal here
+            }
+        }
+    }
+
+    @Override
+    protected final void patchJumpTarget(int branch, int branchTarget) {
+        int op = codeBuffer.getByte(branch);
+        assert op == 0xE8 // call
+            || op == 0x00 // jump table entry
+            || op == 0xE9 // jmp
+            || op == 0xEB // short jmp
+            || (op & 0xF0) == 0x70 // short jcc
+            || op == 0x0F && (codeBuffer.getByte(branch + 1) & 0xF0) == 0x80 // jcc
+        : "Invalid opcode at patch point branch=" + branch + ", branchTarget=" + branchTarget + ", op=" + op;
+
+        if (op == 0x00) {
+            int offsetToJumpTableBase = codeBuffer.getShort(branch + 1);
+            int jumpTableBase = branch - offsetToJumpTableBase;
+            int imm32 = branchTarget - jumpTableBase;
+            codeBuffer.emitInt(imm32, branch);
+        } else if (op == 0xEB || (op & 0xF0) == 0x70) {
+
+            // short offset operators (jmp and jcc)
+            int imm8 = branchTarget - (branch + 2);
+            codeBuffer.emitByte(imm8, branch + 1);
+
+        } else {
+
+            int off = 1;
+            if (op == 0x0F) {
+                off = 2;
+            }
+
+            int imm32 = branchTarget - (branch + 4 + off);
+            codeBuffer.emitInt(imm32, branch + off);
+        }
+    }
+
+    public void nullCheck(CiRegister r) {
+        testl(AMD64.rax, new CiAddress(Word, r.asValue(Word), 0));
+    }
+
+    @Override
+    public void align(int modulus) {
+        if (codeBuffer.position() % modulus != 0) {
+            nop(modulus - (codeBuffer.position() % modulus));
+        }
+    }
+
+    public void pushfq() {
+        emitByte(0x9c);
+    }
+
+    public void popfq() {
+        emitByte(0x9D);
+    }
+
+    /**
+     * Makes sure that a subsequent {@linkplain #call} does not fail the alignment check.
+     */
+    public final void alignForPatchableDirectCall() {
+        int dispStart = codeBuffer.position() + 1;
+        int mask = target.wordSize - 1;
+        if ((dispStart & ~mask) != ((dispStart + 3) & ~mask)) {
+            nop(target.wordSize - (dispStart & mask));
+            assert ((codeBuffer.position() + 1) & mask) == 0;
+        }
+    }
+
+    /**
+     * Emits a direct call instruction. Note that the actual call target is not specified, because all calls
+     * need patching anyway. Therefore, 0 is emitted as the call target, and the user is responsible
+     * to add the call address to the appropriate patching tables.
+     */
+    public final void call() {
+        emitByte(0xE8);
+        emitInt(0);
+    }
+
+    public final void call(CiRegister src) {
+        int encode = prefixAndEncode(src.encoding);
+        emitByte(0xFF);
+        emitByte(0xD0 | encode);
+    }
+
+    public void int3() {
+        emitByte(0xCC);
+    }
+
+    public void enter(short imm16, byte imm8) {
+        emitByte(0xC8);
+        // appended:
+        emitByte(imm16 & 0xff);
+        emitByte((imm16 >> 8) & 0xff);
+        emitByte(imm8);
+    }
+
+    private void emitx87(int b1, int b2, int i) {
+        assert 0 <= i && i < 8 : "illegal stack offset";
+        emitByte(b1);
+        emitByte(b2 + i);
+    }
+
+    public void fld(CiAddress src) {
+        emitByte(0xDD);
+        emitOperandHelper(rax, src);
+    }
+
+    public void fld(int i) {
+        emitx87(0xD9, 0xC0, i);
+    }
+
+    public void fldln2() {
+        emitByte(0xD9);
+        emitByte(0xED);
+    }
+
+    public void fldlg2() {
+        emitByte(0xD9);
+        emitByte(0xEC);
+    }
+
+    public void fyl2x() {
+        emitByte(0xD9);
+        emitByte(0xF1);
+    }
+
+    public void fstp(CiAddress src) {
+        emitByte(0xDD);
+        emitOperandHelper(rbx, src);
+    }
+
+    public void fsin() {
+        emitByte(0xD9);
+        emitByte(0xFE);
+    }
+
+    public void fcos() {
+        emitByte(0xD9);
+        emitByte(0xFF);
+    }
+
+    public void fptan() {
+        emitByte(0xD9);
+        emitByte(0xF2);
+    }
+
+    public void fstp(int i) {
+        emitx87(0xDD, 0xD8, i);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.asm/src/com/oracle/max/asm/target/amd64/AMD64MacroAssembler.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2009, 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.max.asm.target.amd64;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+
+/**
+ * This class implements commonly used X86 code patterns.
+ */
+public class AMD64MacroAssembler extends AMD64Assembler {
+
+    public AMD64MacroAssembler(CiTarget target, RiRegisterConfig registerConfig) {
+        super(target, registerConfig);
+    }
+
+    public void pushptr(CiAddress src) {
+        pushq(src);
+    }
+
+    public void popptr(CiAddress src) {
+        popq(src);
+    }
+
+    public void xorptr(CiRegister dst, CiRegister src) {
+        xorq(dst, src);
+    }
+
+    public void xorptr(CiRegister dst, CiAddress src) {
+        xorq(dst, src);
+    }
+
+    // 64 bit versions
+
+
+    public void decrementq(CiRegister reg, int value) {
+        if (value == Integer.MIN_VALUE) {
+            subq(reg, value);
+            return;
+        }
+        if (value < 0) {
+            incrementq(reg, -value);
+            return;
+        }
+        if (value == 0) {
+            return;
+        }
+        if (value == 1 && AsmOptions.UseIncDec) {
+            decq(reg);
+        } else {
+            subq(reg, value);
+        }
+    }
+
+    public void incrementq(CiRegister reg, int value) {
+        if (value == Integer.MIN_VALUE) {
+            addq(reg, value);
+            return;
+        }
+        if (value < 0) {
+            decrementq(reg, -value);
+            return;
+        }
+        if (value == 0) {
+            return;
+        }
+        if (value == 1 && AsmOptions.UseIncDec) {
+            incq(reg);
+        } else {
+            addq(reg, value);
+        }
+    }
+
+    // These are mostly for initializing null
+    public void movptr(CiAddress dst, int src) {
+        movslq(dst, src);
+    }
+
+    public final void cmp32(CiRegister src1, int imm) {
+        cmpl(src1, imm);
+    }
+
+    public final void cmp32(CiRegister src1, CiAddress src2) {
+        cmpl(src1, src2);
+    }
+
+    public void cmpsd2int(CiRegister opr1, CiRegister opr2, CiRegister dst, boolean unorderedIsLess) {
+        assert opr1.isFpu() && opr2.isFpu();
+        ucomisd(opr1, opr2);
+
+        Label l = new Label();
+        if (unorderedIsLess) {
+            movl(dst, -1);
+            jcc(AMD64Assembler.ConditionFlag.parity, l);
+            jcc(AMD64Assembler.ConditionFlag.below, l);
+            movl(dst, 0);
+            jcc(AMD64Assembler.ConditionFlag.equal, l);
+            incrementl(dst, 1);
+        } else { // unordered is greater
+            movl(dst, 1);
+            jcc(AMD64Assembler.ConditionFlag.parity, l);
+            jcc(AMD64Assembler.ConditionFlag.above, l);
+            movl(dst, 0);
+            jcc(AMD64Assembler.ConditionFlag.equal, l);
+            decrementl(dst, 1);
+        }
+        bind(l);
+    }
+
+    public void cmpss2int(CiRegister opr1, CiRegister opr2, CiRegister dst, boolean unorderedIsLess) {
+        assert opr1.isFpu();
+        assert opr2.isFpu();
+        ucomiss(opr1, opr2);
+
+        Label l = new Label();
+        if (unorderedIsLess) {
+            movl(dst, -1);
+            jcc(AMD64Assembler.ConditionFlag.parity, l);
+            jcc(AMD64Assembler.ConditionFlag.below, l);
+            movl(dst, 0);
+            jcc(AMD64Assembler.ConditionFlag.equal, l);
+            incrementl(dst, 1);
+        } else { // unordered is greater
+            movl(dst, 1);
+            jcc(AMD64Assembler.ConditionFlag.parity, l);
+            jcc(AMD64Assembler.ConditionFlag.above, l);
+            movl(dst, 0);
+            jcc(AMD64Assembler.ConditionFlag.equal, l);
+            decrementl(dst, 1);
+        }
+        bind(l);
+    }
+
+    public void cmpptr(CiRegister src1, CiRegister src2) {
+        cmpq(src1, src2);
+    }
+
+    public void cmpptr(CiRegister src1, CiAddress src2) {
+        cmpq(src1, src2);
+    }
+
+    public void cmpptr(CiRegister src1, int src2) {
+        cmpq(src1, src2);
+    }
+
+    public void cmpptr(CiAddress src1, int src2) {
+        cmpq(src1, src2);
+    }
+
+    public void decrementl(CiRegister reg, int value) {
+        if (value == Integer.MIN_VALUE) {
+            subl(reg, value);
+            return;
+        }
+        if (value < 0) {
+            incrementl(reg, -value);
+            return;
+        }
+        if (value == 0) {
+            return;
+        }
+        if (value == 1 && AsmOptions.UseIncDec) {
+            decl(reg);
+        } else {
+            subl(reg, value);
+        }
+    }
+
+    public void decrementl(CiAddress dst, int value) {
+        if (value == Integer.MIN_VALUE) {
+            subl(dst, value);
+            return;
+        }
+        if (value < 0) {
+            incrementl(dst, -value);
+            return;
+        }
+        if (value == 0) {
+            return;
+        }
+        if (value == 1 && AsmOptions.UseIncDec) {
+            decl(dst);
+        } else {
+            subl(dst, value);
+        }
+    }
+
+    public void incrementl(CiRegister reg, int value) {
+        if (value == Integer.MIN_VALUE) {
+            addl(reg, value);
+            return;
+        }
+        if (value < 0) {
+            decrementl(reg, -value);
+            return;
+        }
+        if (value == 0) {
+            return;
+        }
+        if (value == 1 && AsmOptions.UseIncDec) {
+            incl(reg);
+        } else {
+            addl(reg, value);
+        }
+    }
+
+    public void incrementl(CiAddress dst, int value) {
+        if (value == Integer.MIN_VALUE) {
+            addl(dst, value);
+            return;
+        }
+        if (value < 0) {
+            decrementl(dst, -value);
+            return;
+        }
+        if (value == 0) {
+            return;
+        }
+        if (value == 1 && AsmOptions.UseIncDec) {
+            incl(dst);
+        } else {
+            addl(dst, value);
+        }
+    }
+
+    public void signExtendByte(CiRegister reg) {
+        if (reg.isByte()) {
+            movsxb(reg, reg); // movsxb
+        } else {
+            shll(reg, 24);
+            sarl(reg, 24);
+        }
+    }
+
+    public void signExtendShort(CiRegister reg) {
+        movsxw(reg, reg); // movsxw
+    }
+
+    // Support optimal SSE move instructions.
+    public void movflt(CiRegister dst, CiRegister src) {
+        assert dst.isFpu() && src.isFpu();
+        if (AsmOptions.UseXmmRegToRegMoveAll) {
+            movaps(dst, src);
+        } else {
+            movss(dst, src);
+        }
+    }
+
+    public void movflt(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+        movss(dst, src);
+    }
+
+    public void movflt(CiAddress dst, CiRegister src) {
+        assert src.isFpu();
+        movss(dst, src);
+    }
+
+    public void movdbl(CiRegister dst, CiRegister src) {
+        assert dst.isFpu() && src.isFpu();
+        if (AsmOptions.UseXmmRegToRegMoveAll) {
+            movapd(dst, src);
+        } else {
+            movsd(dst, src);
+        }
+    }
+
+    public void movdbl(CiRegister dst, CiAddress src) {
+        assert dst.isFpu();
+        if (AsmOptions.UseXmmLoadAndClearUpper) {
+            movsd(dst, src);
+        } else {
+            movlpd(dst, src);
+        }
+    }
+
+    public void movdbl(CiAddress dst, CiRegister src) {
+        assert src.isFpu();
+        movsd(dst, src);
+    }
+
+    /**
+     * Non-atomic write of a 64-bit constant to memory. Do not use
+     * if the address might be a volatile field!
+     */
+    public void movlong(CiAddress dst, long src) {
+        CiAddress high = new CiAddress(dst.kind, dst.base, dst.index, dst.scale, dst.displacement + 4);
+        movl(dst, (int) (src & 0xFFFFFFFF));
+        movl(high, (int) (src >> 32));
+    }
+
+    public void xchgptr(CiRegister src1, CiRegister src2) {
+        xchgq(src1, src2);
+    }
+
+    public void flog(CiRegister dest, CiRegister value, boolean base10) {
+        assert value.spillSlotSize == dest.spillSlotSize;
+
+        CiAddress tmp = new CiAddress(CiKind.Double, AMD64.RSP);
+        if (base10) {
+            fldlg2();
+        } else {
+            fldln2();
+        }
+        subq(AMD64.rsp, value.spillSlotSize);
+        movsd(tmp, value);
+        fld(tmp);
+        fyl2x();
+        fstp(tmp);
+        movsd(dest, tmp);
+        addq(AMD64.rsp, dest.spillSlotSize);
+    }
+
+    public void fsin(CiRegister dest, CiRegister value) {
+        ftrig(dest, value, 's');
+    }
+
+    public void fcos(CiRegister dest, CiRegister value) {
+        ftrig(dest, value, 'c');
+    }
+
+    public void ftan(CiRegister dest, CiRegister value) {
+        ftrig(dest, value, 't');
+    }
+
+    private void ftrig(CiRegister dest, CiRegister value, char op) {
+        assert value.spillSlotSize == dest.spillSlotSize;
+
+        CiAddress tmp = new CiAddress(CiKind.Double, AMD64.RSP);
+        subq(AMD64.rsp, value.spillSlotSize);
+        movsd(tmp, value);
+        fld(tmp);
+        if (op == 's') {
+            fsin();
+        } else if (op == 'c') {
+            fcos();
+        } else if (op == 't') {
+            fptan();
+            fstp(0); // ftan pushes 1.0 in addition to the actual result, pop
+        } else {
+            throw new InternalError("should not reach here");
+        }
+        fstp(tmp);
+        movsd(dest, tmp);
+        addq(AMD64.rsp, dest.spillSlotSize);
+    }
+
+    /**
+     * Emit code to save a given set of callee save registers in the
+     * {@linkplain CiCalleeSaveLayout CSA} within the frame.
+     * @param csl the description of the CSA
+     * @param frameToCSA offset from the frame pointer to the CSA
+     */
+    public void save(CiCalleeSaveLayout csl, int frameToCSA) {
+        CiRegisterValue frame = frameRegister.asValue();
+        for (CiRegister r : csl.registers) {
+            int offset = csl.offsetOf(r);
+            movq(new CiAddress(target.wordKind, frame, frameToCSA + offset), r);
+        }
+    }
+
+    public void restore(CiCalleeSaveLayout csl, int frameToCSA) {
+        CiRegisterValue frame = frameRegister.asValue();
+        for (CiRegister r : csl.registers) {
+            int offset = csl.offsetOf(r);
+            movq(r, new CiAddress(target.wordKind, frame, frameToCSA + offset));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.asm/src/com/oracle/max/asm/target/amd64/X86InstructionDecoder.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,507 @@
+/*
+ * Copyright (c) 2009, 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.max.asm.target.amd64;
+
+
+public final class X86InstructionDecoder {
+
+    private boolean targetIs64Bit;
+    private byte[] code;
+    private int currentEndOfInstruction;
+    private int currentDisplacementPosition;
+
+    private static class Prefix {
+
+        // segment overrides
+        public static final int CSSegment = 0x2e;
+        public static final int SSSegment = 0x36;
+        public static final int DSSegment = 0x3e;
+        public static final int ESSegment = 0x26;
+        public static final int FSSegment = 0x64;
+        public static final int GSSegment = 0x65;
+        public static final int REX = 0x40;
+        public static final int REXB = 0x41;
+        public static final int REXX = 0x42;
+        public static final int REXXB = 0x43;
+        public static final int REXR = 0x44;
+        public static final int REXRB = 0x45;
+        public static final int REXRX = 0x46;
+        public static final int REXRXB = 0x47;
+        public static final int REXW = 0x48;
+        public static final int REXWB = 0x49;
+        public static final int REXWX = 0x4A;
+        public static final int REXWXB = 0x4B;
+        public static final int REXWR = 0x4C;
+        public static final int REXWRB = 0x4D;
+        public static final int REXWRX = 0x4E;
+        public static final int REXWRXB = 0x4F;
+    }
+
+    private X86InstructionDecoder(byte[] code, boolean targetIs64Bit) {
+        this.code = code;
+        this.targetIs64Bit = targetIs64Bit;
+    }
+
+    public int currentEndOfInstruction() {
+        return currentEndOfInstruction;
+    }
+
+    public int currentDisplacementPosition() {
+        return currentDisplacementPosition;
+    }
+
+    public void decodePosition(int inst) {
+
+        assert inst >= 0 && inst < code.length;
+
+        // Decode the given instruction, and return the Pointer of
+        // an embedded 32-bit operand word.
+
+        // If "which" is WhichOperand.disp32operand, selects the displacement portion
+        // of an effective Pointer specifier.
+        // If "which" is imm64Operand, selects the trailing immediate constant.
+        // If "which" is WhichOperand.call32operand, selects the displacement of a call or jump.
+        // Caller is responsible for ensuring that there is such an operand,
+        // and that it is 32/64 bits wide.
+
+        // If "which" is endPcOperand, find the end of the instruction.
+
+        int ip = inst;
+        boolean is64bit = false;
+
+        boolean hasDisp32 = false;
+        int tailSize = 0; // other random bytes (#32, #16, etc.) at end of insn
+
+        boolean againAfterPrefix = true;
+
+        while (againAfterPrefix) {
+            againAfterPrefix = false;
+            switch (0xFF & code[ip++]) {
+
+                // These convenience macros generate groups of "case" labels for the switch.
+
+                case Prefix.CSSegment:
+                case Prefix.SSSegment:
+                case Prefix.DSSegment:
+                case Prefix.ESSegment:
+                case Prefix.FSSegment:
+                case Prefix.GSSegment:
+                    // Seems dubious
+                    assert !targetIs64Bit : "shouldn't have that prefix";
+                    assert ip == inst + 1 : "only one prefix allowed";
+                    againAfterPrefix = true;
+                    break;
+
+                case 0x67:
+                case Prefix.REX:
+                case Prefix.REXB:
+                case Prefix.REXX:
+                case Prefix.REXXB:
+                case Prefix.REXR:
+                case Prefix.REXRB:
+                case Prefix.REXRX:
+                case Prefix.REXRXB:
+                    assert targetIs64Bit : "64bit prefixes";
+                    againAfterPrefix = true;
+                    break;
+
+                case Prefix.REXW:
+                case Prefix.REXWB:
+                case Prefix.REXWX:
+                case Prefix.REXWXB:
+                case Prefix.REXWR:
+                case Prefix.REXWRB:
+                case Prefix.REXWRX:
+                case Prefix.REXWRXB:
+                    assert targetIs64Bit : "64bit prefixes";
+                    is64bit = true;
+                    againAfterPrefix = true;
+                    break;
+
+                case 0xFF: // pushq a; decl a; incl a; call a; jmp a
+                case 0x88: // movb a, r
+                case 0x89: // movl a, r
+                case 0x8A: // movb r, a
+                case 0x8B: // movl r, a
+                case 0x8F: // popl a
+                    hasDisp32 = true;
+                    break;
+
+                case 0x68: // pushq #32
+                    currentEndOfInstruction = ip + 4;
+                    currentDisplacementPosition = ip;
+                    return; // not produced by emitOperand
+
+                case 0x66: // movw ... (size prefix)
+                    boolean againAfterSizePrefix2 = true;
+                    while (againAfterSizePrefix2) {
+                        againAfterSizePrefix2 = false;
+                        switch (0xFF & code[ip++]) {
+                            case Prefix.REX:
+                            case Prefix.REXB:
+                            case Prefix.REXX:
+                            case Prefix.REXXB:
+                            case Prefix.REXR:
+                            case Prefix.REXRB:
+                            case Prefix.REXRX:
+                            case Prefix.REXRXB:
+                            case Prefix.REXW:
+                            case Prefix.REXWB:
+                            case Prefix.REXWX:
+                            case Prefix.REXWXB:
+                            case Prefix.REXWR:
+                            case Prefix.REXWRB:
+                            case Prefix.REXWRX:
+                            case Prefix.REXWRXB:
+                                assert targetIs64Bit : "64bit prefix found";
+                                againAfterSizePrefix2 = true;
+                                break;
+                            case 0x8B: // movw r, a
+                            case 0x89: // movw a, r
+                                hasDisp32 = true;
+                                break;
+                            case 0xC7: // movw a, #16
+                                hasDisp32 = true;
+                                tailSize = 2; // the imm16
+                                break;
+                            case 0x0F: // several SSE/SSE2 variants
+                                ip--; // reparse the 0x0F
+                                againAfterPrefix = true;
+                                break;
+                            default:
+                                throw new InternalError("should not reach here");
+                        }
+                    }
+                    break;
+
+                case 0xB8: // movl/q r, #32/#64(oop?)
+                case 0xB9:
+                case 0xBA:
+                case 0xBB:
+                case 0xBC:
+                case 0xBD:
+                case 0xBE:
+                case 0xBF:
+                    currentEndOfInstruction = ip + (is64bit ? 8 : 4);
+                    currentDisplacementPosition = ip;
+                    return;
+
+                case 0x69: // imul r, a, #32
+                case 0xC7: // movl a, #32(oop?)
+                    tailSize = 4;
+                    hasDisp32 = true; // has both kinds of operands!
+                    break;
+
+                case 0x0F: // movx..., etc.
+                    switch (0xFF & code[ip++]) {
+                        case 0x12: // movlps
+                        case 0x28: // movaps
+                        case 0x2E: // ucomiss
+                        case 0x2F: // comiss
+                        case 0x54: // andps
+                        case 0x55: // andnps
+                        case 0x56: // orps
+                        case 0x57: // xorps
+                        case 0x6E: // movd
+                        case 0x7E: // movd
+                        case 0xAE: // ldmxcsr a
+                            // 64bit side says it these have both operands but that doesn't
+                            // appear to be true
+                            hasDisp32 = true;
+                            break;
+
+                        case 0xAD: // shrd r, a, %cl
+                        case 0xAF: // imul r, a
+                        case 0xBE: // movsbl r, a (movsxb)
+                        case 0xBF: // movswl r, a (movsxw)
+                        case 0xB6: // movzbl r, a (movzxb)
+                        case 0xB7: // movzwl r, a (movzxw)
+                        case 0x40: // cmovl cc, r, a
+                        case 0x41:
+                        case 0x42:
+                        case 0x43:
+                        case 0x44:
+                        case 0x45:
+                        case 0x46:
+                        case 0x47:
+                        case 0x48:
+                        case 0x49:
+                        case 0x4A:
+                        case 0x4B:
+                        case 0x4C:
+                        case 0x4D:
+                        case 0x4E:
+                        case 0x4F:
+                        case 0xB0: // cmpxchgb
+                        case 0xB1: // cmpxchg
+                        case 0xC1: // xaddl
+                        case 0xC7: // cmpxchg8
+                        case 0x90: // setcc a
+                        case 0x91:
+                        case 0x92:
+                        case 0x93:
+                        case 0x94:
+                        case 0x95:
+                        case 0x96:
+                        case 0x97:
+                        case 0x98:
+                        case 0x99:
+                        case 0x9A:
+                        case 0x9B:
+                        case 0x9C:
+                        case 0x9D:
+                        case 0x9E:
+                        case 0x9F:
+                            hasDisp32 = true;
+                            // fall out of the switch to decode the Pointer
+                            break;
+
+                        case 0xAC: // shrd r, a, #8
+                            hasDisp32 = true;
+                            tailSize = 1; // the imm8
+                            break;
+
+                        case 0x80: // jcc rdisp32
+                        case 0x81:
+                        case 0x82:
+                        case 0x83:
+                        case 0x84:
+                        case 0x85:
+                        case 0x86:
+                        case 0x87:
+                        case 0x88:
+                        case 0x89:
+                        case 0x8A:
+                        case 0x8B:
+                        case 0x8C:
+                        case 0x8D:
+                        case 0x8E:
+                        case 0x8F:
+                            currentEndOfInstruction = ip + 4;
+                            currentDisplacementPosition = ip;
+                            return;
+                        default:
+                            throw new InternalError("should not reach here");
+                    }
+                    break;
+
+                case 0x81: // addl a, #32; addl r, #32
+                    // also: orl, adcl, sbbl, andl, subl, xorl, cmpl
+                    // on 32bit in the case of cmpl, the imm might be an oop
+                    tailSize = 4;
+                    hasDisp32 = true; // has both kinds of operands!
+                    break;
+
+                case 0x83: // addl a, #8; addl r, #8
+                    // also: orl, adcl, sbbl, andl, subl, xorl, cmpl
+                    hasDisp32 = true; // has both kinds of operands!
+                    tailSize = 1;
+                    break;
+
+                case 0x9B:
+                    switch (0xFF & code[ip++]) {
+                        case 0xD9: // fnstcw a
+                            hasDisp32 = true;
+                            break;
+                        default:
+                            throw new InternalError("should not reach here");
+                    }
+                    break;
+
+                case 0x00: // addb a, r; addl a, r; addb r, a; addl r, a
+                case 0x01:
+                case 0x02:
+                case 0x03:
+                case 0x10: // adc...
+                case 0x11:
+                case 0x12:
+                case 0x13:
+                case 0x20: // and...
+                case 0x21:
+                case 0x22:
+                case 0x23:
+                case 0x30: // xor...
+                case 0x31:
+                case 0x32:
+                case 0x33:
+                case 0x08: // or...
+                case 0x09:
+                case 0x0a:
+                case 0x0b:
+                case 0x18: // sbb...
+                case 0x19:
+                case 0x1a:
+                case 0x1b:
+                case 0x28: // sub...
+                case 0x29:
+                case 0x2a:
+                case 0x2b:
+                case 0xF7: // mull a
+                case 0x8D: // lea r, a
+                case 0x87: // xchg r, a
+                case 0x38: // cmp...
+                case 0x39:
+                case 0x3a:
+                case 0x3b:
+                case 0x85: // test r, a
+                    hasDisp32 = true; // has both kinds of operands!
+                    break;
+
+                case 0xC1: // sal a, #8; sar a, #8; shl a, #8; shr a, #8
+                case 0xC6: // movb a, #8
+                case 0x80: // cmpb a, #8
+                case 0x6B: // imul r, a, #8
+                    hasDisp32 = true; // has both kinds of operands!
+                    tailSize = 1; // the imm8
+                    break;
+
+                case 0xE8: // call rdisp32
+                case 0xE9: // jmp rdisp32
+                    currentEndOfInstruction = ip + 4;
+                    currentDisplacementPosition = ip;
+                    return;
+
+                case 0xD1: // sal a, 1; sar a, 1; shl a, 1; shr a, 1
+                case 0xD3: // sal a, %cl; sar a, %cl; shl a, %cl; shr a, %cl
+                case 0xD9: // fldS a; fstS a; fstpS a; fldcw a
+                case 0xDD: // fldD a; fstD a; fstpD a
+                case 0xDB: // fildS a; fistpS a; fldX a; fstpX a
+                case 0xDF: // fildD a; fistpD a
+                case 0xD8: // faddS a; fsubrS a; fmulS a; fdivrS a; fcompS a
+                case 0xDC: // faddD a; fsubrD a; fmulD a; fdivrD a; fcompD a
+                case 0xDE: // faddpD a; fsubrpD a; fmulpD a; fdivrpD a; fcomppD a
+                    hasDisp32 = true;
+                    break;
+
+                case 0xF0: // Lock
+                    againAfterPrefix = true;
+                    break;
+
+                case 0xF3: // For SSE
+                case 0xF2: // For SSE2
+                    switch (0xFF & code[ip++]) {
+                        case Prefix.REX:
+                        case Prefix.REXB:
+                        case Prefix.REXX:
+                        case Prefix.REXXB:
+                        case Prefix.REXR:
+                        case Prefix.REXRB:
+                        case Prefix.REXRX:
+                        case Prefix.REXRXB:
+                        case Prefix.REXW:
+                        case Prefix.REXWB:
+                        case Prefix.REXWX:
+                        case Prefix.REXWXB:
+                        case Prefix.REXWR:
+                        case Prefix.REXWRB:
+                        case Prefix.REXWRX:
+                        case Prefix.REXWRXB:
+                            assert targetIs64Bit : "found 64bit prefix";
+                            ip++;
+                            // fall through
+                        default:
+                            ip++;
+                    }
+                    hasDisp32 = true; // has both kinds of operands!
+                    break;
+
+                default:
+                    throw new InternalError("should not reach here");
+            }
+        }
+
+        assert hasDisp32 : "(tw) not sure if this holds: instruction has no disp32 field";
+
+        // parse the output of emitOperand
+        int op2 = 0xFF & code[ip++];
+        int base = op2 & 0x07;
+        int op3 = -1;
+        int b100 = 4;
+        int b101 = 5;
+        if (base == b100 && (op2 >> 6) != 3) {
+            op3 = 0xFF & code[ip++];
+            base = op3 & 0x07; // refetch the base
+        }
+        // now ip points at the disp (if any)
+
+        switch (op2 >> 6) {
+            case 0:
+                // [00 reg 100][ss index base]
+                // [00 reg 100][00 100 esp]
+                // [00 reg base]
+                // [00 reg 100][ss index 101][disp32]
+                // [00 reg 101] [disp32]
+
+                if (base == b101) {
+
+                    currentDisplacementPosition = ip;
+                    ip += 4; // skip the disp32
+                }
+                break;
+
+            case 1:
+                // [01 reg 100][ss index base][disp8]
+                // [01 reg 100][00 100 esp][disp8]
+                // [01 reg base] [disp8]
+                ip += 1; // skip the disp8
+                break;
+
+            case 2:
+                // [10 reg 100][ss index base][disp32]
+                // [10 reg 100][00 100 esp][disp32]
+                // [10 reg base] [disp32]
+                currentDisplacementPosition = ip;
+                ip += 4; // skip the disp32
+                break;
+
+            case 3:
+                // [11 reg base] (not a memory addressing mode)
+                break;
+        }
+
+        currentEndOfInstruction = ip + tailSize;
+    }
+
+    public static void patchRelativeInstruction(byte[] code, int codePos, int relative) {
+        X86InstructionDecoder decoder = new X86InstructionDecoder(code, true);
+        decoder.decodePosition(codePos);
+        int patchPos = decoder.currentDisplacementPosition();
+        int endOfInstruction = decoder.currentEndOfInstruction();
+        int offset = relative - endOfInstruction + codePos;
+        patchDisp32(code, patchPos, offset);
+    }
+
+    private static void patchDisp32(byte[] code, int pos, int offset) {
+        assert pos + 4 <= code.length;
+
+        assert code[pos] == 0;
+        assert code[pos + 1] == 0;
+        assert code[pos + 2] == 0;
+        assert code[pos + 3] == 0;
+
+        code[pos] = (byte) (offset & 0xFF);
+        code[pos + 1] = (byte) ((offset >> 8) & 0xFF);
+        code[pos + 2] = (byte) ((offset >> 16) & 0xFF);
+        code[pos + 3] = (byte) ((offset >> 24) & 0xFF);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiAddress.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2010, 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.max.cri.ci;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+/**
+ * Represents an address in target machine memory, specified via some combination of a base register, an index register,
+ * a displacement and a scale. Note that the base and index registers may be a variable that will get a register assigned
+ * later by the register allocator.
+ */
+public final class CiAddress extends CiValue {
+    private static final long serialVersionUID = -1003772042519945089L;
+
+    /**
+     * A sentinel value used as a place holder in an instruction stream for an address that will be patched.
+     */
+    public static final CiAddress Placeholder = new CiAddress(CiKind.Illegal, CiValue.IllegalValue);
+
+    /**
+     * Base register that defines the start of the address computation.
+     * If not present, is denoted by {@link CiValue#IllegalValue}.
+     */
+    public CiValue base;
+
+    /**
+     * Index register, the value of which (possibly scaled by {@link #scale}) is added to {@link #base}.
+     * If not present, is denoted by {@link CiValue#IllegalValue}.
+     */
+    public CiValue index;
+
+    /**
+     * Scaling factor for indexing, dependent on target operand size.
+     */
+    public final Scale scale;
+
+    /**
+     * Optional additive displacement.
+     */
+    public final int displacement;
+
+    /**
+     * Creates a {@code CiAddress} with given base register, no scaling and no displacement.
+     * @param kind the kind of the value being addressed
+     * @param base the base register
+     */
+    public CiAddress(CiKind kind, CiValue base) {
+        this(kind, base, IllegalValue, Scale.Times1, 0);
+    }
+
+    /**
+     * Creates a {@code CiAddress} with given base register, no scaling and a given displacement.
+     * @param kind the kind of the value being addressed
+     * @param base the base register
+     * @param displacement the displacement
+     */
+    public CiAddress(CiKind kind, CiValue base, int displacement) {
+        this(kind, base, IllegalValue, Scale.Times1, displacement);
+    }
+
+    /**
+     * Creates a {@code CiAddress} with given base and index registers, scaling and displacement.
+     * This is the most general constructor..
+     * @param kind the kind of the value being addressed
+     * @param base the base register
+     * @param index the index register
+     * @param scale the scaling factor
+     * @param displacement the displacement
+     */
+    public CiAddress(CiKind kind, CiValue base, CiValue index, Scale scale, int displacement) {
+        super(kind);
+        this.base = base;
+        this.index = index;
+        this.scale = scale;
+        this.displacement = displacement;
+
+        assert !isConstant(base) && !isStackSlot(base);
+        assert !isConstant(index) && !isStackSlot(index);
+    }
+
+    /**
+     * A scaling factor used in complex addressing modes such as those supported by x86 platforms.
+     */
+    public enum Scale {
+        Times1(1, 0),
+        Times2(2, 1),
+        Times4(4, 2),
+        Times8(8, 3);
+
+        private Scale(int value, int log2) {
+            this.value = value;
+            this.log2 = log2;
+        }
+
+        /**
+         * The value (or multiplier) of this scale.
+         */
+        public final int value;
+
+        /**
+         * The {@linkplain #value value} of this scale log 2.
+         */
+        public final int log2;
+
+        public static Scale fromInt(int scale) {
+            switch (scale) {
+                case 1:  return Times1;
+                case 2:  return Times2;
+                case 4:  return Times4;
+                case 8:  return Times8;
+                default: throw new IllegalArgumentException(String.valueOf(scale));
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        if (this == Placeholder) {
+            return "[<placeholder>]";
+        }
+
+        StringBuilder s = new StringBuilder();
+        s.append(kind.javaName).append("[");
+        String sep = "";
+        if (isLegal(base)) {
+            s.append(base);
+            sep = " + ";
+        }
+        if (isLegal(index)) {
+            s.append(sep).append(index).append(" * ").append(scale.value);
+            sep = " + ";
+        }
+        if (displacement < 0) {
+            s.append(" - ").append(-displacement);
+        } else if (displacement > 0) {
+            s.append(sep).append(displacement);
+        }
+        s.append("]");
+        return s.toString();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof CiAddress) {
+            CiAddress addr = (CiAddress) obj;
+            return kind == addr.kind && displacement == addr.displacement && base.equals(addr.base) && scale == addr.scale && index.equals(addr.index);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return base.hashCode() ^ index.hashCode() ^ (displacement << 4) ^ (scale.value << 8) ^ (kind.ordinal() << 12);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiArchitecture.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ci;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.CiRegister.*;
+import com.oracle.max.cri.util.*;
+
+
+/**
+ * Represents a CPU architecture, including information such as its endianness, CPU
+ * registers, word width, etc.
+ */
+public abstract class CiArchitecture {
+
+    /**
+     * The endianness of the architecture.
+     */
+    public static enum ByteOrder {
+        LittleEndian,
+        BigEndian
+    }
+
+    /**
+     * The number of bits required in a bit map covering all the registers that may store references.
+     * The bit position of a register in the map is the register's {@linkplain CiRegister#number number}.
+     */
+    public final int registerReferenceMapBitCount;
+
+    /**
+     * Represents the natural size of words (typically registers and pointers) of this architecture, in bytes.
+     */
+    public final int wordSize;
+
+    /**
+     * The name of this architecture (e.g. "AMD64", "SPARCv9").
+     */
+    public final String name;
+
+    /**
+     * Array of all available registers on this architecture. The index of each register in this
+     * array is equal to its {@linkplain CiRegister#number number}.
+     */
+    public final CiRegister[] registers;
+
+    /**
+     * Map of all registers keyed by their {@linkplain CiRegister#name names}.
+     */
+    public final HashMap<String, CiRegister> registersByName;
+
+    /**
+     * The byte ordering can be either little or big endian.
+     */
+    public final ByteOrder byteOrder;
+
+    /**
+     * Mask of the barrier constants defined in {@link MemoryBarriers} denoting the barriers that
+     * are not required to be explicitly inserted under this architecture.
+     */
+    public final int implicitMemoryBarriers;
+
+    /**
+     * Determines the barriers in a given barrier mask that are explicitly required on this architecture.
+     *
+     * @param barriers a mask of the barrier constants defined in {@link MemoryBarriers}
+     * @return the value of {@code barriers} minus the barriers unnecessary on this architecture
+     */
+    public final int requiredBarriers(int barriers) {
+        return barriers & ~implicitMemoryBarriers;
+    }
+
+    /**
+     * Offset in bytes from the beginning of a call instruction to the displacement.
+     */
+    public final int machineCodeCallDisplacementOffset;
+
+    /**
+     * The size of the return address pushed to the stack by a call instruction.
+     * A value of 0 denotes that call linkage uses registers instead (e.g. SPARC).
+     */
+    public final int returnAddressSize;
+
+    private final EnumMap<RegisterFlag, CiRegister[]> registersByTypeAndEncoding;
+
+    /**
+     * Gets the register for a given {@linkplain CiRegister#encoding encoding} and type.
+     *
+     * @param encoding a register value as used in a machine instruction
+     * @param type the type of the register
+     */
+    public CiRegister registerFor(int encoding, RegisterFlag type) {
+        CiRegister[] regs = registersByTypeAndEncoding.get(type);
+        assert encoding >= 0 && encoding < regs.length;
+        CiRegister reg = regs[encoding];
+        assert reg != null;
+        return reg;
+    }
+
+    protected CiArchitecture(String name,
+                    int wordSize,
+                    ByteOrder byteOrder,
+                    CiRegister[] registers,
+                    int implicitMemoryBarriers,
+                    int nativeCallDisplacementOffset,
+                    int registerReferenceMapBitCount,
+                    int returnAddressSize) {
+        this.name = name;
+        this.registers = registers;
+        this.wordSize = wordSize;
+        this.byteOrder = byteOrder;
+        this.implicitMemoryBarriers = implicitMemoryBarriers;
+        this.machineCodeCallDisplacementOffset = nativeCallDisplacementOffset;
+        this.registerReferenceMapBitCount = registerReferenceMapBitCount;
+        this.returnAddressSize = returnAddressSize;
+
+        registersByName = new HashMap<>(registers.length);
+        for (CiRegister register : registers) {
+            registersByName.put(register.name, register);
+            assert registers[register.number] == register;
+        }
+
+        registersByTypeAndEncoding = new EnumMap<>(RegisterFlag.class);
+        EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = CiRegister.categorize(registers);
+        for (RegisterFlag type : RegisterFlag.values()) {
+            CiRegister[] regs = categorizedRegs.get(type);
+            int max = CiRegister.maxRegisterEncoding(regs);
+            CiRegister[] regsByEnc = new CiRegister[max + 1];
+            for (CiRegister reg : regs) {
+                regsByEnc[reg.encoding] = reg;
+            }
+            registersByTypeAndEncoding.put(type, regsByEnc);
+        }
+    }
+
+    /**
+     * Converts this architecture to a string.
+     * @return the string representation of this architecture
+     */
+    @Override
+    public final String toString() {
+        return name.toLowerCase();
+    }
+
+    /**
+     * Checks whether this is a 32-bit architecture.
+     * @return {@code true} if this architecture is 32-bit
+     */
+    public final boolean is32bit() {
+        return wordSize == 4;
+    }
+
+    /**
+     * Checks whether this is a 64-bit architecture.
+     * @return {@code true} if this architecture is 64-bit
+     */
+    public final boolean is64bit() {
+        return wordSize == 8;
+    }
+
+    // The following methods are architecture specific and not dependent on state
+    // stored in this class. They have convenient default implementations.
+
+    /**
+     * Checks whether this architecture's normal arithmetic instructions use a two-operand form
+     * (e.g. x86 which overwrites one operand register with the result when adding).
+     * @return {@code true} if this architecture uses two-operand mode
+     */
+    public boolean twoOperandMode() {
+        return false;
+    }
+
+    // TODO: Why enumerate the concrete subclasses here rather
+    // than use instanceof comparisons in code that cares?
+
+    /**
+     * Checks whether the architecture is x86.
+     * @return {@code true} if the architecture is x86
+     */
+    public boolean isX86() {
+        return false;
+    }
+
+    /**
+     * Checks whether the architecture is SPARC.
+     * @return {@code true} if the architecture is SPARC
+     */
+    public boolean isSPARC() {
+        return false;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiAssumptions.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,262 @@
+/*
+ * 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.max.cri.ci;
+
+import java.io.*;
+import java.util.*;
+
+import com.oracle.max.cri.ri.*;
+
+/**
+ * Class for recording optimistic assumptions made during compilation.
+ * Recorded assumption can be visited for subsequent processing using
+ * an implementation of the {@link CiAssumptionProcessor} interface.
+ */
+public final class CiAssumptions implements Serializable, Iterable<CiAssumptions.Assumption> {
+
+    private static final long serialVersionUID = 5152062717588239131L;
+
+    public abstract static class Assumption implements Serializable {
+
+        private static final long serialVersionUID = -1936652569665112915L;
+    }
+
+    /**
+     * An assumption about a unique subtype of a given type.
+     */
+    public static final class ConcreteSubtype extends Assumption {
+
+        private static final long serialVersionUID = -1457173265437676252L;
+
+        /**
+         * Type the assumption is made about.
+         */
+        public final RiResolvedType context;
+
+        /**
+         * Assumed unique concrete sub-type of the context type.
+         */
+        public final RiResolvedType subtype;
+
+        public ConcreteSubtype(RiResolvedType context, RiResolvedType subtype) {
+            this.context = context;
+            this.subtype = subtype;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + context.hashCode();
+            result = prime * result + subtype.hashCode();
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof ConcreteSubtype) {
+                ConcreteSubtype other = (ConcreteSubtype) obj;
+                return other.context == context && other.subtype == subtype;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * An assumption about a unique implementation of a virtual method.
+     */
+    public static final class ConcreteMethod extends Assumption {
+
+        private static final long serialVersionUID = -7636746737947390059L;
+
+        /**
+         * A virtual (or interface) method whose unique implementation for the receiver type
+         * in {@link #context} is {@link #impl}.
+         */
+        public final RiResolvedMethod method;
+
+        /**
+         * A receiver type.
+         */
+        public final RiResolvedType context;
+
+        /**
+         * The unique implementation of {@link #method} for {@link #context}.
+         */
+        public final RiResolvedMethod impl;
+
+        public ConcreteMethod(RiResolvedMethod method, RiResolvedType context, RiResolvedMethod impl) {
+            this.method = method;
+            this.context = context;
+            this.impl = impl;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + method.hashCode();
+            result = prime * result + context.hashCode();
+            result = prime * result + impl.hashCode();
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof ConcreteMethod) {
+                ConcreteMethod other = (ConcreteMethod) obj;
+                return other.method == method && other.context == context && other.impl == impl;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * An assumption that specified that a method was used during the compilation.
+     */
+    public static final class MethodContents extends Assumption {
+
+        private static final long serialVersionUID = -4821594103928571659L;
+
+        public final RiResolvedMethod method;
+
+        public MethodContents(RiResolvedMethod method) {
+            this.method = method;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + method.hashCode();
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof ConcreteMethod) {
+                ConcreteMethod other = (ConcreteMethod) obj;
+                return other.method == method;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Array with the assumptions. This field is directly accessed from C++ code in the Graal/HotSpot implementation.
+     */
+    private Assumption[] list;
+
+    private int count;
+
+    /**
+     * Returns whether any assumptions have been registered.
+     * @return {@code true} if at least one assumption has been registered, {@code false} otherwise.
+     */
+    public boolean isEmpty() {
+        return count == 0;
+    }
+
+    @Override
+    public Iterator<Assumption> iterator() {
+        return new Iterator<CiAssumptions.Assumption>() {
+            int index;
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+            public Assumption next() {
+                if (index >= count) {
+                    throw new NoSuchElementException();
+                }
+                return list[index++];
+            }
+            public boolean hasNext() {
+                return index < count;
+            }
+        };
+    }
+
+    /**
+     * Records an assumption that the specified type has no finalizable subclasses.
+     *
+     * @param receiverType the type that is assumed to have no finalizable subclasses
+     * @return {@code true} if the assumption was recorded and can be assumed; {@code false} otherwise
+     */
+    @SuppressWarnings("static-method")
+    public boolean recordNoFinalizableSubclassAssumption(RiResolvedType receiverType) {
+        // TODO(tw): Record that assumption correctly.
+        return false;
+    }
+
+    /**
+     * Records that {@code subtype} is the only concrete subtype in the class hierarchy below {@code context}.
+     * @param context the root of the subtree of the class hierarchy that this assumptions is about
+     * @param subtype the one concrete subtype
+     */
+    public void recordConcreteSubtype(RiResolvedType context, RiResolvedType subtype) {
+        record(new ConcreteSubtype(context, subtype));
+    }
+
+    /**
+     * Records that {@code impl} is the only possible concrete target for a virtual call to
+     * {@code method} with a receiver of type {@code context}.
+     *
+     * @param method a method that is the target of a virtual call
+     * @param context the receiver type of a call to {@code method}
+     * @param impl the concrete method that is the only possible target for the virtual call
+     */
+    public void recordConcreteMethod(RiResolvedMethod method, RiResolvedType context, RiResolvedMethod impl) {
+        record(new ConcreteMethod(method, context, impl));
+    }
+
+    /**
+     * Records that {@code method} was used during the compilation.
+     *
+     * @param method a method whose contents were used
+     */
+    public void recordMethodContents(RiResolvedMethod method) {
+        record(new MethodContents(method));
+    }
+
+    private void record(Assumption assumption) {
+        if (list == null) {
+            list = new Assumption[4];
+        } else {
+            for (int i = 0; i < count; ++i) {
+                if (assumption.equals(list[i])) {
+                    return;
+                }
+            }
+        }
+        if (list.length == count) {
+            Assumption[] newList = new Assumption[list.length * 2];
+            for (int i = 0; i < list.length; ++i) {
+                newList[i] = list[i];
+            }
+            list = newList;
+        }
+        list[count] = assumption;
+        count++;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiBailout.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ci;
+
+import java.util.*;
+
+/**
+ * {@code CiBailout} is thrown when the compiler refuses to compile a method because of problems with the method.
+ * e.g. bytecode wouldn't verify, too big, JSR/ret too complicated, etc. This exception is <i>not</i>
+ * meant to indicate problems with the compiler itself.
+ */
+public class CiBailout extends RuntimeException {
+
+    public static final long serialVersionUID = 8974598793458772L;
+
+    /**
+     * Create a new {@code CiBailout}.
+     * @param reason a message indicating the reason
+     */
+    public CiBailout(String reason) {
+        super(reason);
+    }
+
+    /**
+     * Create a new {@code CiBailout}.
+     * @param reason a message indicating the reason with a String.format - syntax
+     * @param args parameters to the formatter
+     */
+    public CiBailout(String format, Object... args) {
+        this(String.format(Locale.ENGLISH, format, args));
+    }
+
+    /**
+     * Create a new {@code CiBailout} t due to an internal exception being thrown.
+     * @param reason a message indicating the reason
+     * @param cause the throwable that was the cause of the bailout
+     */
+    public CiBailout(String reason, Throwable cause) {
+        super(reason);
+        initCause(cause);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiBitMap.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,682 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ci;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Implements a bitmap that stores a single bit for a range of integers (0-n).
+ */
+public final class CiBitMap implements Serializable {
+
+    private static final long serialVersionUID = 2471441272241401105L;
+    private static final int ADDRESS_BITS_PER_WORD = 6;
+    private static final int BITS_PER_WORD = 1 << ADDRESS_BITS_PER_WORD;
+    private static final int BIT_INDEX_MASK = BITS_PER_WORD - 1;
+
+    public static final int DEFAULT_LENGTH = BITS_PER_WORD;
+
+    public static int roundUpLength(int length) {
+        return ((length + (BITS_PER_WORD - 1)) >> ADDRESS_BITS_PER_WORD) << ADDRESS_BITS_PER_WORD;
+    }
+
+    private int size;
+    private long low;
+    private long[] extra;
+
+    /**
+     * Constructs a new bit map with the {@linkplain #DEFAULT_LENGTH default length}.
+     */
+    public CiBitMap() {
+        this(DEFAULT_LENGTH);
+    }
+
+    /**
+     * Constructs a new bit map from a byte array encoded bit map.
+     *
+     * @param bitmap the bit map to convert
+     */
+    public CiBitMap(byte[] bitmap) {
+        this(bitmap, 0, bitmap.length);
+    }
+
+    /**
+     * Constructs a copy of the given bit map.
+     *
+     * @param bitmap the bit map to copy.
+     */
+    public CiBitMap(CiBitMap bitmap) {
+        this.size = bitmap.size;
+        this.low = bitmap.low;
+        if (bitmap.extra != null) {
+            this.extra = Arrays.copyOf(bitmap.extra, bitmap.extra.length);
+        }
+    }
+
+    /**
+     * Constructs a new bit map from a byte array encoded bit map.
+     *
+     * @param arr the byte array containing the bit map to convert
+     * @param off the byte index in {@code arr} at which the bit map starts
+     * @param numberOfBytes the number of bytes worth of bits to copy from {@code arr}
+     */
+    public CiBitMap(byte[] arr, int off, int numberOfBytes) {
+        this(numberOfBytes * 8);
+        int byteIndex = off;
+        int end = off + numberOfBytes;
+        assert end <= arr.length;
+        while (byteIndex < end && (byteIndex - off) < 8) {
+            long bite = (long) arr[byteIndex] & 0xff;
+            low |= bite << ((byteIndex - off) * 8);
+            byteIndex++;
+        }
+        if (byteIndex < end) {
+            assert (byteIndex - off) == 8;
+            int remBytes = end - byteIndex;
+            int remWords = (remBytes + 7) / 8;
+            for (int word = 0; word < remWords; word++) {
+                long w = 0L;
+                for (int i = 0; i < 8 && byteIndex < end; i++) {
+                    long bite = (long) arr[byteIndex] & 0xff;
+                    w |= bite << (i * 8);
+                    byteIndex++;
+                }
+                extra[word] = w;
+            }
+        }
+    }
+
+    /**
+     * Converts a {@code long} to a {@link CiBitMap}.
+     */
+    public static CiBitMap fromLong(long bitmap) {
+        CiBitMap bm = new CiBitMap(64);
+        bm.low = bitmap;
+        return bm;
+    }
+
+    /**
+     * Constructs a new bit map with the specified length.
+     *
+     * @param length the length of the bitmap
+     */
+    public CiBitMap(int length) {
+        assert length >= 0;
+        this.size = length;
+        if (length > BITS_PER_WORD) {
+            extra = new long[length >> ADDRESS_BITS_PER_WORD];
+        }
+    }
+
+    /**
+     * Sets the bit at the specified index.
+     *
+     * @param i the index of the bit to set
+     */
+    public void set(int i) {
+        if (checkIndex(i) < BITS_PER_WORD) {
+            low |= 1L << i;
+        } else {
+            int pos = wordIndex(i);
+            int index = bitInWord(i);
+            extra[pos] |= 1L << index;
+        }
+    }
+
+    /**
+     * Grows this bitmap to a new size, appending necessary zero bits.
+     *
+     * @param newLength the new length of the bitmap
+     */
+    public void grow(int newLength) {
+        if (newLength > size) {
+            // grow this bitmap to the new length
+            int newSize = newLength >> ADDRESS_BITS_PER_WORD;
+            if (newLength > 0) {
+                if (extra == null) {
+                    // extra just needs to be allocated now
+                    extra = new long[newSize];
+                } else {
+                    if (extra.length < newSize) {
+                        // extra needs to be copied
+                        long[] newExtra = new long[newSize];
+                        for (int i = 0; i < extra.length; i++) {
+                            newExtra[i] = extra[i];
+                        }
+                        extra = newExtra;
+                    } else {
+                        // nothing to do, extra is already the right size
+                    }
+                }
+            }
+            size = newLength;
+        }
+    }
+
+    private static int bitInWord(int i) {
+        return i & BIT_INDEX_MASK;
+    }
+
+    private static int wordIndex(int i) {
+        return (i >> ADDRESS_BITS_PER_WORD) - 1;
+    }
+
+    /**
+     * Clears the bit at the specified index.
+     * @param i the index of the bit to clear
+     */
+    public void clear(int i) {
+        if (checkIndex(i) < BITS_PER_WORD) {
+            low &= ~(1L << i);
+        } else {
+            int pos = wordIndex(i);
+            int index = bitInWord(i);
+            extra[pos] &= ~(1L << index);
+        }
+    }
+
+    /**
+     * Sets all the bits in this bitmap.
+     */
+    public void setAll() {
+        low = -1;
+        if (extra != null) {
+            for (int i = 0; i < extra.length; i++) {
+                extra[i] = -1;
+            }
+        }
+    }
+
+    /**
+     * Clears all the bits in this bitmap.
+     */
+    public void clearAll() {
+        low = 0;
+        if (extra != null) {
+            for (int i = 0; i < extra.length; i++) {
+                extra[i] = 0;
+            }
+        }
+    }
+
+    /**
+     * Gets the value of the bit at the specified index.
+     *
+     * @param i the index of the bit to get
+     * @return {@code true} if the bit at the specified position is {@code 1}
+     */
+    public boolean get(int i) {
+        if (checkIndex(i) < BITS_PER_WORD) {
+            return ((low >> i) & 1) != 0;
+        }
+        int pos = wordIndex(i);
+        int index = bitInWord(i);
+        long bits = extra[pos];
+        return ((bits >> index) & 1) != 0;
+    }
+
+    /**
+     * Gets the value of the bit at the specified index, returning {@code false} if the
+     * bitmap does not cover the specified index.
+     *
+     * @param i the index of the bit to get
+     * @return {@code true} if the bit at the specified position is {@code 1}
+     */
+    public boolean getDefault(int i) {
+        if (i < 0 || i >= size) {
+            return false;
+        }
+        if (i < BITS_PER_WORD) {
+            return ((low >> i) & 1) != 0;
+        }
+        int pos = wordIndex(i);
+        int index = bitInWord(i);
+        long bits = extra[pos];
+        return ((bits >> index) & 1) != 0;
+    }
+
+    /**
+     * Performs the union operation on this bitmap with the specified bitmap. That is, all bits set in either of the two
+     * bitmaps will be set in this bitmap following this operation.
+     *
+     * @param other the other bitmap for the union operation
+     */
+    public void setUnion(CiBitMap other) {
+        low |= other.low;
+        if (extra != null && other.extra != null) {
+            for (int i = 0; i < extra.length && i < other.extra.length; i++) {
+                extra[i] |= other.extra[i];
+            }
+        }
+    }
+
+    /**
+     * Performs the union operation on this bitmap with the specified bitmap. That is, a bit is set in this
+     * bitmap if and only if it is set in both this bitmap and the specified bitmap.
+     *
+     * @param other the other bitmap for this operation
+     * @return {@code true} if any bits were cleared as a result of this operation
+     */
+    public boolean setIntersect(CiBitMap other) {
+        boolean same = true;
+        long intx = low & other.low;
+        if (low != intx) {
+            same = false;
+            low = intx;
+        }
+        long[] oxtra = other.extra;
+        if (extra != null && oxtra != null) {
+            for (int i = 0; i < extra.length; i++) {
+                long a = extra[i];
+                if (i < oxtra.length) {
+                    // zero bits out of this map
+                    long ax = a & oxtra[i];
+                    if (a != ax) {
+                        same = false;
+                        extra[i] = ax;
+                    }
+                } else {
+                    // this bitmap is larger than the specified bitmap; zero remaining bits
+                    if (a != 0) {
+                        same = false;
+                        extra[i] = 0;
+                    }
+                }
+            }
+        }
+        return !same;
+    }
+
+    /**
+     * Gets the number of addressable bits in this bitmap.
+     *
+     * @return the size of this bitmap
+     */
+    public int size() {
+        return size;
+    }
+
+    private int checkIndex(int i) {
+        if (i < 0 || i >= size) {
+            throw new IndexOutOfBoundsException();
+        }
+        return i;
+    }
+
+    public void setFrom(CiBitMap other) {
+        assert this.size == other.size : "must have same size";
+
+        low = other.low;
+        if (extra != null) {
+            for (int i = 0; i < extra.length; i++) {
+                extra[i] = other.extra[i];
+            }
+        }
+    }
+
+    public void setDifference(CiBitMap other) {
+        assert this.size == other.size : "must have same size";
+
+        low &= ~other.low;
+        if (extra != null) {
+            for (int i = 0; i < extra.length; i++) {
+                extra[i] &= ~other.extra[i];
+            }
+        }
+    }
+
+    public boolean isSame(CiBitMap other) {
+        if (this.size != other.size || this.low != other.low) {
+            return false;
+        }
+
+        if (extra != null) {
+            for (int i = 0; i < extra.length; i++) {
+                if (extra[i] != other.extra[i]) {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns the index of the first set bit that occurs on or after a specified start index.
+     * If no such bit exists then -1 is returned.
+     * <p>
+     * To iterate over the set bits in a {@code BitMap}, use the following loop:
+     *
+     * <pre>
+     * for (int i = bitMap.nextSetBit(0); i &gt;= 0; i = bitMap.nextSetBit(i + 1)) {
+     *     // operate on index i here
+     * }
+     * </pre>
+     *
+     * @param fromIndex the index to start checking from (inclusive)
+     * @return the index of the lowest set bit between {@code [fromIndex .. size())} or -1 if there is no set bit in this range
+     * @throws IndexOutOfBoundsException if the specified index is negative.
+     */
+    public int nextSetBit(int fromIndex) {
+        return nextSetBit(fromIndex, size());
+    }
+
+    /**
+     * Returns the index of the first set bit that occurs on or after a specified start index
+     * and before a specified end index. If no such bit exists then -1 is returned.
+     * <p>
+     * To iterate over the set bits in a {@code BitMap}, use the following loop:
+     *
+     * <pre>
+     * for (int i = bitMap.nextSetBit(0, bitMap.size()); i &gt;= 0; i = bitMap.nextSetBit(i + 1, bitMap.size())) {
+     *     // operate on index i here
+     * }
+     * </pre>
+     *
+     * @param fromIndex the index to start checking from (inclusive)
+     * @param toIndex the index at which to stop checking (exclusive)
+     * @return the index of the lowest set bit between {@code [fromIndex .. toIndex)} or -1 if there is no set bit in this range
+     * @throws IndexOutOfBoundsException if the specified index is negative.
+     */
+    public int nextSetBit(int fromIndex, int toIndex) {
+        assert fromIndex <= size() : "index out of bounds";
+        assert toIndex <= size() : "index out of bounds";
+        assert fromIndex <= toIndex : "fromIndex > toIndex";
+
+        if (fromIndex == toIndex) {
+            return -1;
+        }
+        int fromWordIndex = wordIndex(fromIndex);
+        int toWordIndex = wordIndex(toIndex - 1) + 1;
+        int resultIndex = fromIndex;
+
+        // check bits including and to the left_ of offset's position
+        int pos = bitInWord(resultIndex);
+        long res = map(fromWordIndex) >> pos;
+        if (res != 0) {
+            resultIndex += Long.numberOfTrailingZeros(res);
+            assert resultIndex >= fromIndex && resultIndex < toIndex : "just checking";
+            if (resultIndex < toIndex) {
+                return resultIndex;
+            }
+            return -1;
+        }
+        // skip over all word length 0-bit runs
+        for (fromWordIndex++; fromWordIndex < toWordIndex; fromWordIndex++) {
+            res = map(fromWordIndex);
+            if (res != 0) {
+                // found a 1, return the offset
+                resultIndex = bitIndex(fromWordIndex) + Long.numberOfTrailingZeros(res);
+                assert resultIndex >= fromIndex : "just checking";
+                if (resultIndex < toIndex) {
+                    return resultIndex;
+                }
+                return -1;
+            }
+        }
+        return -1;
+    }
+
+    private static int bitIndex(int index) {
+        return (index + 1) << ADDRESS_BITS_PER_WORD;
+    }
+
+    private long map(int index) {
+        if (index == -1) {
+            return low;
+        }
+        return extra[index];
+    }
+
+    private static boolean allZeros(int start, long[] arr) {
+        for (int i = start; i < arr.length; i++) {
+            if (arr[i] != 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Compares this object against the specified object.
+     * The result is {@code true} if and only if {@code obj} is
+     * not {@code null} and is a {@code CiBitMap} object that has
+     * exactly the same set of bits set to {@code true} as this bit
+     * set.
+     *
+     * @param   obj   the object to compare with.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof CiBitMap) {
+            CiBitMap bm = (CiBitMap) obj;
+            if (bm.low == low) {
+                if (bm.extra == null) {
+                    if (extra == null) {
+                        // Common case
+                        return true;
+                    }
+                    return allZeros(0, extra);
+                }
+                if (extra == null) {
+                    return allZeros(0, bm.extra);
+                }
+                // both 'extra' array non null:
+                int i = 0;
+                int length = Math.min(extra.length, bm.extra.length);
+                while (i < length) {
+                    if (extra[i] != bm.extra[i]) {
+                        return false;
+                    }
+                    i++;
+                }
+                if (extra.length > bm.extra.length) {
+                    return allZeros(length, extra);
+                }
+                if (extra.length < bm.extra.length) {
+                    return allZeros(length, bm.extra);
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return (int) low ^ size;
+    }
+
+    /**
+     * Returns a string representation of this bit map
+     * that is the same as the string returned by {@link BitSet#toString()}
+     * for a bit set with the same bits set as this bit map.
+     */
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(size * 2);
+        sb.append('{');
+
+        int bit = nextSetBit(0);
+        if (bit != -1) {
+            sb.append(bit);
+            for (bit = nextSetBit(bit + 1); bit >= 0; bit = nextSetBit(bit + 1)) {
+                sb.append(", ").append(bit);
+            }
+        }
+
+        sb.append('}');
+        return sb.toString();
+    }
+
+    public static int highestOneBitIndex(long value) {
+        int bit = Long.numberOfTrailingZeros(Long.highestOneBit(value));
+        if (bit == 64) {
+            return -1;
+        }
+        return bit;
+    }
+
+    /**
+     * Returns the number of bits set to {@code true} in this bit map.
+     */
+    public int cardinality() {
+        int sum = Long.bitCount(low);
+        if (extra != null) {
+            for (long word : extra) {
+                sum += Long.bitCount(word);
+            }
+        }
+        return sum;
+    }
+
+    /**
+     * Returns the "logical size" of this bit map: the index of
+     * the highest set bit in the bit map plus one. Returns zero
+     * if the bit map contains no set bits.
+     *
+     * @return  the logical size of this bit map
+     */
+    public int length() {
+        if (extra != null) {
+            for (int i = extra.length - 1; i >= 0; i--) {
+                if (extra[i] != 0) {
+                    return (highestOneBitIndex(extra[i]) + ((i + 1) * 64)) + 1;
+                }
+            }
+        }
+        return highestOneBitIndex(low) + 1;
+    }
+
+    /**
+     * Returns a string representation of this bit map with every set bit represented as {@code '1'}
+     * and every unset bit represented as {@code '0'}. The first character in the returned string represents
+     * bit 0 in this bit map.
+     *
+     * @param length the number of bits represented in the returned string. If {@code length < 0 || length > size()},
+     *            then the value of {@link #length()} is used.
+     */
+    public String toBinaryString() {
+        int length = length();
+        if (length == 0) {
+            return "";
+        }
+        StringBuilder sb = new StringBuilder(length);
+        for (int i = 0; i < length; ++i) {
+            sb.append(get(i) ? '1' : '0');
+        }
+        return sb.toString();
+    }
+
+    static final char[] hexDigits = {
+        '0', '1', '2', '3', '4', '5', '6', '7',
+        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+    };
+
+    /**
+     * Returns a string representation of this bit map in hex.
+     */
+    public String toHexString() {
+        if (size == 0) {
+            return "";
+        }
+        int hexSize = CiUtil.align(this.size, 4);
+        StringBuilder sb = new StringBuilder(hexSize / 4);
+        for (int i = 0; i < hexSize; i += 4) {
+            int nibble = get(i) ? 1 : 0;
+            if (get(i + 1)) {
+                nibble |= 2;
+            }
+            if (get(i + 2)) {
+                nibble |= 4;
+            }
+            if (get(i + 3)) {
+                nibble |= 8;
+            }
+
+            sb.append(hexDigits[nibble]);
+        }
+        return sb.toString();
+    }
+
+    public CiBitMap copy() {
+        CiBitMap n = new CiBitMap(BITS_PER_WORD);
+        n.low = low;
+        if (extra != null) {
+            n.extra = Arrays.copyOf(extra, extra.length);
+        }
+        n.size = size;
+        return n;
+    }
+
+    /**
+     * Copies this bit map into a given byte array.
+     *
+     * @param arr the destination
+     * @param off the byte index in {@code arr} at which to start writing
+     * @param numberOfBytes the number of bytes worth of bits to copy from this bit map.
+     *        The number of bits copied is {@code numberOfBytes * 8}. If {@code numberOfBytes}
+     *        is -1, then {@code ((size() + 7) / 8)} is used instead.
+     * @return the number of bytes written to {@code arr}
+     */
+    public int copyTo(byte[] arr, int off, int numberOfBytes) {
+        for (int i = 0; i < numberOfBytes; ++i) {
+            long word = low;
+            int byteInWord;
+            if (i >= 8) {
+                int wordIndex = (i - 8) / 8;
+                word = extra[wordIndex];
+                byteInWord = i & 0x7;
+            } else {
+                byteInWord = i;
+            }
+            assert byteInWord < 8;
+            byte b = (byte) (word >> (byteInWord * 8));
+            arr[off + i] = b;
+        }
+        return numberOfBytes;
+    }
+
+    /**
+     * Converts this bit map to a byte array. The length of the returned
+     * byte array is {@code ((size() + 7) / 8)}.
+     */
+    public byte[] toByteArray() {
+        byte[] arr = new byte[(size + 7) / 8];
+        copyTo(arr, 0, arr.length);
+        return arr;
+    }
+
+    /**
+     * Converts this bit map to a long.
+     *
+     * @throws IllegalArgumentException if {@code (size() > 64)}
+     */
+    public long toLong() {
+        if (size > 64) {
+            throw new IllegalArgumentException("bit map of size " + size + " cannot be converted to long");
+        }
+        return low;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiCalleeSaveLayout.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2010, 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.max.cri.ci;
+
+import java.util.*;
+
+
+/**
+ * The callee save area (CSA) is a contiguous space in a stack frame
+ * used to save (and restore) the values of the caller's registers.
+ * This class describes the layout of a CSA in terms of its
+ * {@linkplain #size size}, {@linkplain #slotSize slot size} and
+ * the {@linkplain #registers callee save registers} covered by the CSA.
+ */
+public class CiCalleeSaveLayout {
+
+    /**
+     * The size (in bytes) of the CSA.
+     */
+    public final int size;
+
+    /**
+     * The size (in bytes) of an {@linkplain #registerAtIndex(int) indexable} slot in the CSA.
+     */
+    public final int slotSize;
+
+    /**
+     * Map from {@linkplain CiRegister#number register numbers} to slot indexes in the CSA.
+     */
+    private final int[] regNumToIndex;
+
+    private final CiRegister[] indexToReg;
+
+    /**
+     * The list of registers {@linkplain #contains(CiRegister) contained} by this CSA.
+     */
+    public final CiRegister[] registers;
+
+    /**
+     * The offset from the frame pointer to the CSA. If this is not known, then this field
+     * will have the value {@link Integer#MAX_VALUE}.
+     */
+    public final int frameOffsetToCSA;
+
+    /**
+     * Creates a CSA layout.
+     *
+     * @param size size (in bytes) of the CSA. If this is {@code -1}, then the CSA size will be computed from {@code registers}.
+     * @param slotSize the size (in bytes) of an {@linkplain #registerAtIndex(int) indexable} slot in the CSA
+     * @param registers the registers that can be saved in the CSA
+     */
+    public CiCalleeSaveLayout(int frameOffsetToCSA, int size, int slotSize, CiRegister... registers) {
+        this.frameOffsetToCSA = frameOffsetToCSA;
+        assert slotSize == 0 || CiUtil.isPowerOf2(slotSize);
+        this.slotSize = slotSize;
+        int maxRegNum = -1;
+        int maxOffset = 0;
+        this.registers = registers;
+        int offset = 0;
+        for (CiRegister reg : registers) {
+            assert offset % slotSize == 0;
+            assert reg.number >= 0;
+            if (reg.number > maxRegNum) {
+                maxRegNum = reg.number;
+            }
+            if (offset > maxOffset) {
+                maxOffset = offset;
+            }
+            offset += reg.spillSlotSize;
+        }
+        if (size == -1) {
+            this.size = offset;
+        } else {
+            assert offset <= size;
+            this.size = size;
+        }
+
+        this.regNumToIndex = new int[maxRegNum + 1];
+        this.indexToReg = offset == 0 ? new CiRegister[0] : new CiRegister[offset / slotSize];
+        Arrays.fill(regNumToIndex, -1);
+        offset = 0;
+        for (CiRegister reg : registers) {
+            int index = offset / slotSize;
+            regNumToIndex[reg.number] = index;
+            indexToReg[index] = reg;
+            offset += reg.spillSlotSize;
+        }
+    }
+
+    /**
+     * Gets the offset of a given register in the CSA.
+     *
+     * @return the offset (in bytes) of {@code reg} in the CSA
+     * @throws IllegalArgumentException if {@code reg} does not have a slot in the CSA
+     */
+    public int offsetOf(int reg) {
+        return indexOf(reg) * slotSize;
+    }
+
+    /**
+     * Gets the index of a given register in the CSA.
+     *
+     * @return the index of {@code reg} in the CSA
+     * @throws IllegalArgumentException if {@code reg} does not have a slot in the CSA
+     */
+    public int indexOf(int reg) {
+        if (!contains(reg)) {
+            throw new IllegalArgumentException(String.valueOf(reg));
+        }
+        return regNumToIndex[reg];
+    }
+
+    /**
+     * Gets the offset of a given register in the CSA.
+     *
+     * @return the offset (in bytes) of {@code reg} in the CSA
+     * @throws IllegalArgumentException if {@code reg} does not have a slot in the CSA
+     */
+    public int offsetOf(CiRegister reg) {
+        return offsetOf(reg.number);
+    }
+
+    /**
+     * Determines if the CSA includes a slot for a given register.
+     *
+     * @param reg the register to test
+     * @return true if the CSA contains a slot for {@code reg}
+     */
+    public boolean contains(int reg) {
+        return reg >= 0 && reg < regNumToIndex.length && regNumToIndex[reg] != -1;
+    }
+
+    /**
+     * Gets the register whose slot in the CSA is at a given index.
+     *
+     * @param index an index of a slot in the CSA
+     * @return the register whose slot in the CSA is at  {@code index} or {@code null} if {@code index} does not denote a
+     *         slot in the CSA aligned with a register
+     */
+    public CiRegister registerAt(int index) {
+        if (index < 0 || index >= indexToReg.length) {
+            return null;
+        }
+        return indexToReg[index];
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("[");
+        for (CiRegister reg : registers) {
+            if (sb.length() != 1) {
+                sb.append(", ");
+            }
+            sb.append(reg).append("{+").append(offsetOf(reg)).append('}');
+        }
+        return sb.append("] size=").append(size).toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiCallingConvention.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.cri.ci;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import com.oracle.max.cri.ri.*;
+
+
+/**
+ * A calling convention describes the locations in which the arguments for a call are placed.
+ */
+public class CiCallingConvention {
+
+    /**
+     * Constants denoting the type of a call for which a calling convention is
+     * {@linkplain RiRegisterConfig#getCallingConvention(Type, CiKind[], CiTarget, boolean) requested}.
+     */
+    public enum Type {
+        /**
+         * A request for the outgoing argument locations at a call site to Java code.
+         */
+        JavaCall(true),
+
+        /**
+         * A request for the incoming argument locations.
+         */
+        JavaCallee(false),
+
+        /**
+         * A request for the outgoing argument locations at a call site to the runtime (which may be Java or native code).
+         */
+        RuntimeCall(true),
+
+        /**
+         * A request for the outgoing argument locations at a call site to
+         * external native code that complies with the platform ABI.
+         */
+        NativeCall(true);
+
+        /**
+         * Determines if this is a request for the outgoing argument locations at a call site.
+         */
+        public final boolean out;
+
+        public static final Type[] VALUES = values();
+
+        private Type(boolean out) {
+            this.out = out;
+        }
+    }
+
+    /**
+     * The amount of stack space (in bytes) required for the stack-based arguments of the call.
+     */
+    public final int stackSize;
+
+    /**
+     * The locations in which the arguments are placed. This array ordered by argument index.
+     */
+    public final CiValue[] locations;
+
+    public CiCallingConvention(CiValue[] locations, int stackSize) {
+        this.locations = locations;
+        this.stackSize = stackSize;
+        assert verify();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder result = new StringBuilder();
+        result.append("CallingConvention[");
+        for (CiValue op : locations) {
+            result.append(op.toString()).append(" ");
+        }
+        result.append("]");
+        return result.toString();
+    }
+
+    private boolean verify() {
+        for (int i = 0; i < locations.length; i++) {
+            CiValue location = locations[i];
+            assert isStackSlot(location) || isRegister(location);
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiCodePos.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ci;
+
+import java.io.*;
+
+import com.oracle.max.cri.ri.*;
+
+/**
+ * Represents a code position, that is, a chain of inlined methods with bytecode
+ * locations, that is communicated from the compiler to the runtime system. A code position
+ * can be used by the runtime system to reconstruct a source-level stack trace
+ * for exceptions and to create {@linkplain CiFrame frames} for deoptimization.
+ */
+public class CiCodePos implements Serializable {
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 8633885274526033515L;
+
+    /**
+     * The position where this position has been called, {@code null} if none.
+     */
+    public final CiCodePos caller;
+
+    /**
+     * The runtime interface method for this position.
+     */
+    public final RiResolvedMethod method;
+
+    /**
+     * The location within the method, as a bytecode index. The constant
+     * {@code -1} may be used to indicate the location is unknown, for example
+     * within code synthesized by the compiler.
+     */
+    public final int bci;
+
+    /**
+     * Constructs a new object representing a given parent/caller, a given method, and a given BCI.
+     *
+     * @param caller the parent position
+     * @param method the method
+     * @param bci a BCI within the method
+     */
+    public CiCodePos(CiCodePos caller, RiResolvedMethod method, int bci) {
+        assert method != null;
+        this.caller = caller;
+        this.method = method;
+        this.bci = bci;
+    }
+
+    /**
+     * Converts this code position to a string representation.
+     * @return a string representation of this code position
+     */
+    @Override
+    public String toString() {
+        return CiUtil.append(new StringBuilder(100), this).toString();
+    }
+
+    /**
+     * Deep equality test.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof CiCodePos) {
+            CiCodePos other = (CiCodePos) obj;
+            if (other.method.equals(method) && other.bci == bci) {
+                if (caller == null) {
+                    return other.caller == null;
+                }
+                return caller.equals(other.caller);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return bci;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiConstant.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,496 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.cri.ci;
+
+/**
+ * Represents a constant (boxed) value, such as an integer, floating point number, or object reference,
+ * within the compiler and across the compiler/runtime interface. Exports a set of {@code CiConstant}
+ * instances that represent frequently used constant values, such as {@link #ZERO}.
+ */
+public final class CiConstant extends CiValue {
+    private static final long serialVersionUID = -6355452536852663986L;
+
+    private static final CiConstant[] INT_CONSTANT_CACHE = new CiConstant[100];
+    static {
+        for (int i = 0; i < INT_CONSTANT_CACHE.length; ++i) {
+            INT_CONSTANT_CACHE[i] = new CiConstant(CiKind.Int, i);
+        }
+    }
+
+    public static final CiConstant NULL_OBJECT = new CiConstant(CiKind.Object, null);
+    public static final CiConstant INT_MINUS_1 = new CiConstant(CiKind.Int, -1);
+    public static final CiConstant INT_0 = forInt(0);
+    public static final CiConstant INT_1 = forInt(1);
+    public static final CiConstant INT_2 = forInt(2);
+    public static final CiConstant INT_3 = forInt(3);
+    public static final CiConstant INT_4 = forInt(4);
+    public static final CiConstant INT_5 = forInt(5);
+    public static final CiConstant LONG_0 = new CiConstant(CiKind.Long, 0L);
+    public static final CiConstant LONG_1 = new CiConstant(CiKind.Long, 1L);
+    public static final CiConstant FLOAT_0 = new CiConstant(CiKind.Float, Float.floatToRawIntBits(0.0F));
+    public static final CiConstant FLOAT_1 = new CiConstant(CiKind.Float, Float.floatToRawIntBits(1.0F));
+    public static final CiConstant FLOAT_2 = new CiConstant(CiKind.Float, Float.floatToRawIntBits(2.0F));
+    public static final CiConstant DOUBLE_0 = new CiConstant(CiKind.Double, Double.doubleToRawLongBits(0.0D));
+    public static final CiConstant DOUBLE_1 = new CiConstant(CiKind.Double, Double.doubleToRawLongBits(1.0D));
+    public static final CiConstant TRUE = new CiConstant(CiKind.Boolean, 1L);
+    public static final CiConstant FALSE = new CiConstant(CiKind.Boolean, 0L);
+
+    static {
+        assert NULL_OBJECT.isDefaultValue();
+        assert INT_0.isDefaultValue();
+        assert FLOAT_0.isDefaultValue();
+        assert DOUBLE_0.isDefaultValue();
+        assert FALSE.isDefaultValue();
+
+        // Ensure difference between 0.0f and -0.0f is preserved
+        assert FLOAT_0 != forFloat(-0.0F);
+        assert !forFloat(-0.0F).isDefaultValue();
+
+        // Ensure difference between 0.0d and -0.0d is preserved
+        assert DOUBLE_0 != forDouble(-0.0d);
+        assert !forDouble(-0.0D).isDefaultValue();
+
+        assert NULL_OBJECT.isNull();
+    }
+
+    /**
+     * The boxed object value. This is ignored iff {@code !kind.isObject()}.
+     */
+    private final Object object;
+
+    /**
+     * The boxed primitive value as a {@code long}. This is ignored iff {@code kind.isObject()}.
+     * For {@code float} and {@code double} values, this value is the result of
+     * {@link Float#floatToRawIntBits(float)} and {@link Double#doubleToRawLongBits(double)} respectively.
+     */
+    private final long primitive;
+
+    /**
+     * Create a new constant represented by the specified object reference.
+     *
+     * @param kind the type of this constant
+     * @param object the value of this constant
+     */
+    private CiConstant(CiKind kind, Object object) {
+        super(kind);
+        this.object = object;
+        this.primitive = 0L;
+    }
+
+    /**
+     * Create a new constant represented by the specified primitive.
+     *
+     * @param kind the type of this constant
+     * @param primitive the value of this constant
+     */
+    public CiConstant(CiKind kind, long primitive) {
+        super(kind);
+        this.object = null;
+        this.primitive = primitive;
+    }
+
+    /**
+     * Checks whether this constant is non-null.
+     * @return {@code true} if this constant is a primitive, or an object constant that is not null
+     */
+    public boolean isNonNull() {
+        return !kind.isObject() || object != null;
+    }
+
+    /**
+     * Checks whether this constant is null.
+     * @return {@code true} if this constant is the null constant
+     */
+    public boolean isNull() {
+        return kind.isObject() && object == null;
+    }
+
+    @Override
+    public String toString() {
+        return kind.javaName + "[" + kind.format(boxedValue()) + (kind != CiKind.Object ? "|0x" + Long.toHexString(primitive) : "") + "]";
+    }
+
+    /**
+     * Gets this constant's value as a string.
+     *
+     * @return this constant's value as a string
+     */
+    public String valueString() {
+        if (kind.isPrimitive()) {
+            return boxedValue().toString();
+        } else if (kind.isObject()) {
+            if (object == null) {
+                return "null";
+            } else if (object instanceof String) {
+                return "\"" + object + "\"";
+            } else {
+                return "<object: " + kind.format(object) + ">";
+            }
+        } else if (kind.isJsr()) {
+            return "bci:" + boxedValue().toString();
+        } else {
+            return "???";
+        }
+    }
+
+    /**
+     * Returns the value of this constant as a boxed Java value.
+     * @return the value of this constant
+     */
+    public Object boxedValue() {
+        // Checkstyle: stop
+        switch (kind) {
+            case Byte: return (byte) asInt();
+            case Boolean: return asInt() == 0 ? Boolean.FALSE : Boolean.TRUE;
+            case Short: return (short) asInt();
+            case Char: return (char) asInt();
+            case Jsr: return (int) primitive;
+            case Int: return asInt();
+            case Long: return asLong();
+            case Float: return asFloat();
+            case Double: return asDouble();
+            case Object: return object;
+        }
+        // Checkstyle: resume
+        throw new IllegalArgumentException();
+    }
+
+    private boolean valueEqual(CiConstant other, boolean ignoreKind) {
+        // must have equivalent kinds to be equal
+        if (!ignoreKind && kind != other.kind) {
+            return false;
+        }
+        if (kind.isObject()) {
+            return object == other.object;
+        }
+        return primitive == other.primitive;
+    }
+
+    /**
+     * Converts this constant to a primitive int.
+     * @return the int value of this constant
+     */
+    public int asInt() {
+        if (kind.stackKind().isInt() || kind.isJsr()) {
+            return (int) primitive;
+        }
+        throw new Error("Constant is not int: " + this);
+    }
+
+    /**
+     * Converts this constant to a primitive boolean.
+     * @return the boolean value of this constant
+     */
+    public boolean asBoolean() {
+        if (kind == CiKind.Boolean) {
+            return primitive != 0L;
+        }
+        throw new Error("Constant is not boolean: " + this);
+    }
+
+    /**
+     * Converts this constant to a primitive long.
+     * @return the long value of this constant
+     */
+    public long asLong() {
+        // Checkstyle: stop
+        switch (kind.stackKind()) {
+            case Jsr:
+            case Int:
+            case Long: return primitive;
+            case Float: return (long) asFloat();
+            case Double: return (long) asDouble();
+            default: throw new Error("Constant is not long: " + this);
+        }
+        // Checkstyle: resume
+    }
+
+    /**
+     * Converts this constant to a primitive float.
+     * @return the float value of this constant
+     */
+    public float asFloat() {
+        if (kind.isFloat()) {
+            return Float.intBitsToFloat((int) primitive);
+        }
+        throw new Error("Constant is not float: " + this);
+    }
+
+    /**
+     * Converts this constant to a primitive double.
+     * @return the double value of this constant
+     */
+    public double asDouble() {
+        if (kind.isFloat()) {
+            return Float.intBitsToFloat((int) primitive);
+        }
+        if (kind.isDouble()) {
+            return Double.longBitsToDouble(primitive);
+        }
+        throw new Error("Constant is not double: " + this);
+    }
+
+    /**
+     * Converts this constant to the object reference it represents.
+     * @return the object which this constant represents
+     */
+    public Object asObject() {
+        if (kind.isObject()) {
+            return object;
+        }
+        throw new Error("Constant is not object: " + this);
+    }
+
+    /**
+     * Converts this constant to the jsr reference it represents.
+     * @return the object which this constant represents
+     */
+    public int asJsr() {
+        if (kind.isJsr()) {
+            return (int) primitive;
+        }
+        throw new Error("Constant is not jsr: " + this);
+    }
+
+    /**
+     * Unchecked access to a primitive value.
+     * @return
+     */
+    public long asPrimitive() {
+        if (kind.isObject()) {
+            throw new Error("Constant is not primitive: " + this);
+        }
+        return primitive;
+    }
+
+    /**
+     * Computes the hashcode of this constant.
+     * @return a suitable hashcode for this constant
+     */
+    @Override
+    public int hashCode() {
+        if (kind.isObject()) {
+            return System.identityHashCode(object);
+        }
+        return (int) primitive;
+    }
+
+    /**
+     * Checks whether this constant equals another object. This is only
+     * true if the other object is a constant and has the same value.
+     * @param o the object to compare equality
+     * @return {@code true} if this constant is equivalent to the specified object
+     */
+    @Override
+    public boolean equals(Object o) {
+        return o == this || o instanceof CiConstant && valueEqual((CiConstant) o, false);
+    }
+
+    /**
+     * Checks whether this constant is identical to another constant or has the same value as it.
+     * @param other the constant to compare for equality against this constant
+     * @return {@code true} if this constant is equivalent to {@code other}
+     */
+    public boolean equivalent(CiConstant other) {
+        return other == this || valueEqual(other, false);
+    }
+
+    /**
+     * Checks whether this constant is the default value for its type.
+     * @return {@code true} if the value is the default value for its type; {@code false} otherwise
+     */
+    public boolean isDefaultValue() {
+        // Checkstyle: stop
+        switch (kind.stackKind()) {
+            case Int: return asInt() == 0;
+            case Long: return asLong() == 0;
+            case Float: return this == FLOAT_0;
+            case Double: return this == DOUBLE_0;
+            case Object: return object == null;
+        }
+        // Checkstyle: resume
+        throw new IllegalArgumentException("Cannot det default CiConstant for kind " + kind);
+    }
+
+    /**
+     * Gets the default value for a given kind.
+     *
+     * @return the default value for {@code kind}'s {@linkplain CiKind#stackKind() stack kind}
+     */
+    public static CiConstant defaultValue(CiKind kind) {
+        // Checkstyle: stop
+        switch (kind.stackKind()) {
+            case Int: return INT_0;
+            case Long: return LONG_0;
+            case Float: return FLOAT_0;
+            case Double: return DOUBLE_0;
+            case Object: return NULL_OBJECT;
+        }
+        // Checkstyle: resume
+        throw new IllegalArgumentException("Cannot get default CiConstant for kind " + kind);
+    }
+
+    /**
+     * Creates a boxed double constant.
+     * @param d the double value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static CiConstant forDouble(double d) {
+        if (Double.compare(0.0D, d) == 0) {
+            return DOUBLE_0;
+        }
+        if (Double.compare(d, 1.0D) == 0) {
+            return DOUBLE_1;
+        }
+        return new CiConstant(CiKind.Double, Double.doubleToRawLongBits(d));
+    }
+
+    /**
+     * Creates a boxed float constant.
+     * @param f the float value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static CiConstant forFloat(float f) {
+        if (Float.compare(f, 0.0F) == 0) {
+            return FLOAT_0;
+        }
+        if (Float.compare(f, 1.0F) == 0) {
+            return FLOAT_1;
+        }
+        if (Float.compare(f, 2.0F) == 0) {
+            return FLOAT_2;
+        }
+        return new CiConstant(CiKind.Float, Float.floatToRawIntBits(f));
+    }
+
+    /**
+     * Creates a boxed long constant.
+     * @param i the long value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static CiConstant forLong(long i) {
+        return i == 0 ? LONG_0 : i == 1 ? LONG_1 : new CiConstant(CiKind.Long, i);
+    }
+
+    /**
+     * Creates a boxed integer constant.
+     * @param i the integer value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static CiConstant forInt(int i) {
+        if (i == -1) {
+            return INT_MINUS_1;
+        }
+        if (i >= 0 && i < INT_CONSTANT_CACHE.length) {
+            return INT_CONSTANT_CACHE[i];
+        }
+        return new CiConstant(CiKind.Int, i);
+    }
+
+    /**
+     * Creates a boxed byte constant.
+     * @param i the byte value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static CiConstant forByte(byte i) {
+        return new CiConstant(CiKind.Byte, i);
+    }
+
+    /**
+     * Creates a boxed boolean constant.
+     * @param i the boolean value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static CiConstant forBoolean(boolean i) {
+        return i ? TRUE : FALSE;
+    }
+
+    /**
+     * Creates a boxed char constant.
+     * @param i the char value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static CiConstant forChar(char i) {
+        return new CiConstant(CiKind.Char, i);
+    }
+
+    /**
+     * Creates a boxed short constant.
+     * @param i the short value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static CiConstant forShort(short i) {
+        return new CiConstant(CiKind.Short, i);
+    }
+
+    /**
+     * Creates a boxed address (jsr/ret address) constant.
+     * @param i the address value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static CiConstant forJsr(int i) {
+        return new CiConstant(CiKind.Jsr, i);
+    }
+
+    /**
+     * Creates a boxed object constant.
+     * @param o the object value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static CiConstant forObject(Object o) {
+        if (o == null) {
+            return NULL_OBJECT;
+        }
+        return new CiConstant(CiKind.Object, o);
+    }
+
+    /**
+     * Creates a boxed constant for the given kind from an Object.
+     * The object needs to be of the Java boxed type corresponding to the kind.
+     * @param kind the kind of the constant to create
+     * @param value the Java boxed value: a Byte instance for CiKind Byte, etc.
+     * @return the boxed copy of {@code value}
+     */
+    public static CiConstant forBoxed(CiKind kind, Object value) {
+        switch (kind) {
+            case Byte:
+                return forByte((Byte) value);
+            case Char:
+                return forChar((Character) value);
+            case Short:
+                return forShort((Short) value);
+            case Int:
+                return forInt((Integer) value);
+            case Long:
+                return forLong((Long) value);
+            case Float:
+                return forFloat((Float) value);
+            case Double:
+                return forDouble((Double) value);
+            case Object:
+                return forObject(value);
+            default:
+                throw new RuntimeException("cannot create CiConstant for boxed " + kind + " value");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiDebugInfo.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ci;
+
+import java.io.*;
+
+/**
+ * Represents the debugging information for a particular place in the code,
+ * which includes the code position, a reference map, and deoptimization information.
+ */
+public class CiDebugInfo implements Serializable {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -6047206624915812516L;
+
+    /**
+     * The code position (including all inlined methods) of this debug info.
+     * If this is a {@link CiFrame} instance, then it is also the deoptimization information for each inlined frame.
+     */
+    public final CiCodePos codePos;
+
+    /**
+     * The reference map for the registers at this point. The reference map is <i>packed</i> in that
+     * for bit {@code k} in byte {@code n}, it refers to the register whose
+     * {@linkplain CiRegister#number number} is {@code (k + n * 8)}.
+     */
+    public final CiBitMap registerRefMap;
+
+    /**
+     * The reference map for the stack frame at this point. A set bit at {@code k} in the map
+     * represents stack slot number {@code k}.
+     */
+    public final CiBitMap frameRefMap;
+
+    /**
+     * Creates a new {@code CiDebugInfo} from the given values.
+     *
+     * @param codePos the {@linkplain CiCodePos code position} or {@linkplain CiFrame frame} info
+     * @param registerRefMap the register map
+     * @param frameRefMap the reference map for {@code frame}, which may be {@code null}
+     */
+    public CiDebugInfo(CiCodePos codePos, CiBitMap registerRefMap, CiBitMap frameRefMap) {
+        this.codePos = codePos;
+        this.registerRefMap = registerRefMap;
+        this.frameRefMap = frameRefMap;
+    }
+
+    /**
+     * @return {@code true} if this debug information has a frame
+     */
+    public boolean hasFrame() {
+        return codePos instanceof CiFrame;
+    }
+
+    /**
+     * @return {@code true} if this debug info has a reference map for the registers
+     */
+    public boolean hasRegisterRefMap() {
+        return registerRefMap != null && registerRefMap.size() > 0;
+    }
+
+    /**
+     * @return {@code true} if this debug info has a reference map for the stack
+     */
+    public boolean hasStackRefMap() {
+        return frameRefMap != null && frameRefMap.size() > 0;
+    }
+
+
+    /**
+     * Gets the deoptimization information for each inlined frame (if available).
+     *
+     * @return {@code null} if no frame de-opt info is {@linkplain #hasDebugFrame available}
+     */
+    public CiFrame frame() {
+        if (hasFrame()) {
+            return (CiFrame) codePos;
+        }
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return CiUtil.append(new StringBuilder(100), this, null).toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiExceptionHandler.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ci;
+
+import com.oracle.max.cri.ri.*;
+
+/**
+ * An implementation of the {@link RiExceptionHandler} interface.
+ */
+public class CiExceptionHandler implements RiExceptionHandler {
+
+    public static final CiExceptionHandler[] NONE = {};
+
+    public final int startBCI;
+    public final int endBCI;
+    public final int handlerBCI;
+    public final int catchTypeCPI;
+    public final RiType catchType;
+
+    /**
+     * Creates a new exception handler with the specified ranges.
+     * @param startBCI the start index of the protected range
+     * @param endBCI the end index of the protected range
+     * @param catchBCI the index of the handler
+     * @param catchTypeCPI the index of the throwable class in the constant pool
+     * @param catchType the type caught by this exception handler
+     */
+    public CiExceptionHandler(int startBCI, int endBCI, int catchBCI, int catchTypeCPI, RiType catchType) {
+        this.startBCI = startBCI;
+        this.endBCI = endBCI;
+        this.handlerBCI = catchBCI;
+        this.catchTypeCPI = catchTypeCPI;
+        this.catchType = catchType;
+    }
+
+    public int startBCI() {
+        return startBCI;
+    }
+
+    public int endBCI() {
+        return endBCI;
+    }
+
+    public int handlerBCI() {
+        return handlerBCI;
+    }
+
+    public int catchTypeCPI() {
+        return catchTypeCPI;
+    }
+
+    public boolean isCatchAll() {
+        return catchTypeCPI == 0;
+    }
+
+    public RiType catchType() {
+        return catchType;
+    }
+
+    @Override
+    public String toString() {
+        return new StringBuilder(20).
+            append('[').
+            append(startBCI).
+            append(" - ").
+            append(endBCI).
+            append(") -> ").
+            append(handlerBCI).
+            append(" type=").
+            append(catchType == null ? "*any*" : catchType.name()).
+            toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiFrame.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.cri.ci;
+
+import java.io.*;
+
+import com.oracle.max.cri.ri.*;
+
+/**
+ * Represents the Java bytecode frame state(s) at a given position
+ * including {@link CiValue locations} where to find the local variables,
+ * operand stack values and locked objects of the bytecode frame(s).
+ */
+public class CiFrame extends CiCodePos implements Serializable {
+    private static final long serialVersionUID = -345025397165977565L;
+
+    /**
+     * An array of values representing how to reconstruct the state of the Java frame.
+     * This is array is partitioned as follows:
+     * <p>
+     * <table border="1" cellpadding="5" frame="void", rules="all">
+     * <tr><th>Start index (inclusive)</th><th>End index (exclusive)</th><th>Description</th></tr>
+     * <tr><td>0</td>                   <td>numLocals</td>           <td>Local variables</td></tr>
+     * <tr><td>numLocals</td>           <td>numLocals + numStack</td><td>Operand stack</td></tr>
+     * <tr><td>numLocals + numStack</td><td>values.length</td>       <td>Locked objects</td></tr>
+     * </table>
+     * <p>
+     * Note that the number of locals and the number of stack slots may be smaller than the
+     * maximum number of locals and stack slots as specified in the compiled method.
+     */
+    public final CiValue[] values;
+
+    /**
+     * The number of locals in the values array.
+     */
+    public final int numLocals;
+
+    /**
+     * The number of stack slots in the values array.
+     */
+    public final int numStack;
+
+    /**
+     * The number of locks in the values array.
+     */
+    public final int numLocks;
+
+    public final boolean rethrowException;
+
+    public final boolean duringCall;
+
+    /**
+     * Creates a new frame object.
+     *
+     * @param caller the caller frame (which may be {@code null})
+     * @param method the method
+     * @param bci a BCI within the method
+     * @param rethrowException specifies if the VM should re-throw the pending exception when deopt'ing using this frame
+     * @param values the frame state {@link #values}
+     * @param numLocals the number of local variables
+     * @param numStack the depth of the stack
+     * @param numLocks the number of locked objects
+     */
+    public CiFrame(CiFrame caller, RiResolvedMethod method, int bci, boolean rethrowException, boolean duringCall, CiValue[] values, int numLocals, int numStack, int numLocks) {
+        super(caller, method, bci);
+        assert values != null;
+        this.rethrowException = rethrowException;
+        this.values = values;
+        this.numLocks = numLocks;
+        this.numLocals = numLocals;
+        this.numStack = numStack;
+        this.duringCall = duringCall;
+        assert !rethrowException || numStack == 1 : "must have exception on top of the stack";
+    }
+
+    /**
+     * Gets the value representing the specified local variable.
+     * @param i the local variable index
+     * @return the value that can be used to reconstruct the local's current value
+     */
+    public CiValue getLocalValue(int i) {
+        return values[i];
+    }
+
+    /**
+     * Gets the value representing the specified stack slot.
+     * @param i the stack index
+     * @return the value that can be used to reconstruct the stack slot's current value
+     */
+    public CiValue getStackValue(int i) {
+        return values[i + numLocals];
+    }
+
+    /**
+     * Gets the value representing the specified lock.
+     * @param i the lock index
+     * @return the value that can be used to reconstruct the lock's current value
+     */
+    public CiValue getLockValue(int i) {
+        return values[i + numLocals + numStack];
+    }
+
+    /**
+     * Gets the caller of this frame.
+     *
+     * @return {@code null} if this frame has no caller
+     */
+    public CiFrame caller() {
+        return (CiFrame) caller;
+    }
+
+    @Override
+    public String toString() {
+        return CiUtil.append(new StringBuilder(100), this).toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiGenericCallback.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,41 @@
+/*
+ * 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.max.cri.ci;
+
+/**
+ * This interface is used for {@link CiRuntimeCall#GenericCallback} runtime calls.
+ */
+public abstract class CiGenericCallback {
+
+    @SuppressWarnings("unused")
+    private Object callbackInternal(Object arg) {
+        try {
+            return callback(arg);
+        } catch (Throwable t) {
+            t.printStackTrace();
+            return null;
+        }
+    }
+
+    public abstract Object callback(Object arg);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiKind.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ci;
+
+import static com.oracle.max.cri.ci.CiKind.Flags.*;
+import sun.misc.*;
+
+import com.oracle.max.cri.ri.*;
+
+/**
+ * Denotes the basic kinds of types in CRI, including the all the Java primitive types,
+ * for example, {@link CiKind#Int} for {@code int} and {@link CiKind#Object}
+ * for all object types.
+ * A kind has a single character short name, a Java name, and a set of flags
+ * further describing its behavior.
+ */
+public enum CiKind {
+    Boolean('z', "boolean", FIELD_TYPE | RETURN_TYPE | PRIMITIVE | STACK_INT),
+    Byte   ('b', "byte",    FIELD_TYPE | RETURN_TYPE | PRIMITIVE | STACK_INT),
+    Short  ('s', "short",   FIELD_TYPE | RETURN_TYPE | PRIMITIVE | STACK_INT),
+    Char   ('c', "char",    FIELD_TYPE | RETURN_TYPE | PRIMITIVE | STACK_INT),
+    Int    ('i', "int",     FIELD_TYPE | RETURN_TYPE | PRIMITIVE | STACK_INT),
+    Float  ('f', "float",   FIELD_TYPE | RETURN_TYPE | PRIMITIVE),
+    Long   ('j', "long",    FIELD_TYPE | RETURN_TYPE | PRIMITIVE),
+    Double ('d', "double",  FIELD_TYPE | RETURN_TYPE | PRIMITIVE),
+    Object ('a', "Object",  FIELD_TYPE | RETURN_TYPE),
+    Void   ('v', "void",    RETURN_TYPE),
+    /** Denote a bytecode address in a {@code JSR} bytecode. */
+    Jsr    ('r', "jsr",     0),
+    /** The non-type. */
+    Illegal('-', "illegal", 0);
+
+    public static final CiKind[] VALUES = values();
+    public static final CiKind[] JAVA_VALUES = new CiKind[] {CiKind.Boolean, CiKind.Byte, CiKind.Short, CiKind.Char, CiKind.Int, CiKind.Float, CiKind.Long, CiKind.Double, CiKind.Object};
+
+    CiKind(char ch, String name, int flags) {
+        this.typeChar = ch;
+        this.javaName = name;
+        this.flags = flags;
+    }
+
+    static class Flags {
+        /**
+         * Can be an object field type.
+         */
+        public static final int FIELD_TYPE  = 0x0001;
+        /**
+         * Can be result type of a method.
+         */
+        public static final int RETURN_TYPE = 0x0002;
+        /**
+         * Behaves as an integer when on Java evaluation stack.
+         */
+        public static final int STACK_INT   = 0x0004;
+        /**
+         * Represents a Java primitive type.
+         */
+        public static final int PRIMITIVE   = 0x0008;
+    }
+
+    /**
+     * The flags for this kind.
+     */
+    private final int flags;
+
+    /**
+     * The name of the kind as a single character.
+     */
+    public final char typeChar;
+
+    /**
+     * The name of this kind which will also be it Java programming language name if
+     * it is {@linkplain #isPrimitive() primitive} or {@code void}.
+     */
+    public final String javaName;
+
+    /**
+     * Checks whether this kind is valid as the type of a field.
+     * @return {@code true} if this kind is valid as the type of a Java field
+     */
+    public boolean isValidFieldType() {
+        return (flags & FIELD_TYPE) != 0;
+    }
+
+    /**
+     * Checks whether this kind is valid as the return type of a method.
+     * @return {@code true} if this kind is valid as the return type of a Java method
+     */
+    public boolean isValidReturnType() {
+        return (flags & RETURN_TYPE) != 0;
+    }
+
+    /**
+     * Checks whether this type is valid as an {@code int} on the Java operand stack.
+     * @return {@code true} if this type is represented by an {@code int} on the operand stack
+     */
+    public boolean isInt() {
+        return (flags & STACK_INT) != 0;
+    }
+
+    /**
+     * Checks whether this type is a Java primitive type.
+     * @return {@code true} if this is {@link #Boolean}, {@link #Byte}, {@link #Char}, {@link #Short},
+     *                                 {@link #Int}, {@link #Long}, {@link #Float} or {@link #Double}.
+     */
+    public boolean isPrimitive() {
+        return (flags & PRIMITIVE) != 0;
+    }
+
+    /**
+     * Gets the kind that represents this kind when on the Java operand stack.
+     * @return the kind used on the operand stack
+     */
+    public CiKind stackKind() {
+        if (isInt()) {
+            return Int;
+        }
+        return this;
+    }
+
+    public static CiKind fromTypeString(String typeString) {
+        assert typeString.length() > 0;
+        final char first = typeString.charAt(0);
+        if (first == '[' || first == 'L') {
+            return CiKind.Object;
+        }
+        return CiKind.fromPrimitiveOrVoidTypeChar(first);
+    }
+
+    /**
+     * Gets the kind from the character describing a primitive or void.
+     * @param ch the character
+     * @return the kind
+     */
+    public static CiKind fromPrimitiveOrVoidTypeChar(char ch) {
+        // Checkstyle: stop
+        switch (ch) {
+            case 'Z': return Boolean;
+            case 'C': return Char;
+            case 'F': return Float;
+            case 'D': return Double;
+            case 'B': return Byte;
+            case 'S': return Short;
+            case 'I': return Int;
+            case 'J': return Long;
+            case 'V': return Void;
+        }
+        // Checkstyle: resume
+        throw new IllegalArgumentException("unknown primitive or void type character: " + ch);
+    }
+
+    public Class< ? > toJavaClass() {
+        // Checkstyle: stop
+        switch(this) {
+            case Void:      return java.lang.Void.TYPE;
+            case Long:      return java.lang.Long.TYPE;
+            case Int:       return java.lang.Integer.TYPE;
+            case Byte:      return java.lang.Byte.TYPE;
+            case Char:      return java.lang.Character.TYPE;
+            case Double:    return java.lang.Double.TYPE;
+            case Float:     return java.lang.Float.TYPE;
+            case Short:     return java.lang.Short.TYPE;
+            case Boolean:   return java.lang.Boolean.TYPE;
+            default:        return null;
+        }
+        // Checkstyle: resume
+    }
+
+    public Class< ? > toUnboxedJavaClass() {
+        // Checkstyle: stop
+        switch(this) {
+            case Void:      return null;
+            case Long:      return java.lang.Long.class;
+            case Int:       return java.lang.Integer.class;
+            case Byte:      return java.lang.Byte.class;
+            case Char:      return java.lang.Character.class;
+            case Double:    return java.lang.Double.class;
+            case Float:     return java.lang.Float.class;
+            case Short:     return java.lang.Short.class;
+            case Boolean:   return java.lang.Boolean.class;
+            default:        return null;
+        }
+        // Checkstyle: resume
+    }
+
+    /**
+     * Checks whether this value type is void.
+     * @return {@code true} if this type is void
+     */
+    public final boolean isVoid() {
+        return this == CiKind.Void;
+    }
+
+    /**
+     * Checks whether this value type is long.
+     * @return {@code true} if this type is long
+     */
+    public final boolean isLong() {
+        return this == CiKind.Long;
+    }
+
+    /**
+     * Checks whether this value type is float.
+     * @return {@code true} if this type is float
+     */
+    public final boolean isFloat() {
+        return this == CiKind.Float;
+    }
+
+    /**
+     * Checks whether this value type is double.
+     * @return {@code true} if this type is double
+     */
+    public final boolean isDouble() {
+        return this == CiKind.Double;
+    }
+
+    /**
+     * Checks whether this value type is float or double.
+     * @return {@code true} if this type is float or double
+     */
+    public final boolean isFloatOrDouble() {
+        return this == CiKind.Double || this == CiKind.Float;
+    }
+
+   /**
+     * Checks whether this value type is an object type.
+     * @return {@code true} if this type is an object
+     */
+    public final boolean isObject() {
+        return this == CiKind.Object;
+    }
+
+    /**
+     * Checks whether this value type is an address type.
+     * @return {@code true} if this type is an address
+     */
+    public boolean isJsr() {
+        return this == CiKind.Jsr;
+    }
+
+    /**
+     * Converts this value type to a string.
+     */
+    @Override
+    public String toString() {
+        return javaName;
+    }
+
+    /**
+     * Marker interface for types that should be {@linkplain CiKind#format(Object) formatted}
+     * with their {@link Object#toString()} value.
+     */
+    public interface FormatWithToString {}
+
+    /**
+     * Gets a formatted string for a given value of this kind.
+     *
+     * @param value a value of this kind
+     * @return a formatted string for {@code value} based on this kind
+     */
+    public String format(Object value) {
+        if (isObject()) {
+            if (value == null) {
+                return "null";
+            } else {
+                if (value instanceof String) {
+                    String s = (String) value;
+                    if (s.length() > 50) {
+                        return "\"" + s.substring(0, 30) + "...\"";
+                    } else {
+                        return " \"" + s + '"';
+                    }
+                } else if (value instanceof RiType) {
+                    return "class " + CiUtil.toJavaName((RiType) value);
+                } else if (value instanceof Enum || value instanceof FormatWithToString) {
+                    return String.valueOf(value);
+                } else if (value instanceof Class< ? >) {
+                    return ((Class< ? >) value).getName() + ".class";
+                } else {
+                    return CiUtil.getSimpleName(value.getClass(), true) + "@" + System.identityHashCode(value);
+                }
+            }
+        } else {
+            return value.toString();
+        }
+    }
+
+    public final char signatureChar() {
+        return Character.toUpperCase(typeChar);
+    }
+
+    public CiConstant readUnsafeConstant(Object value, long displacement) {
+        assert value != null;
+        Unsafe u = Unsafe.getUnsafe();
+        switch(this) {
+            case Boolean:
+                return CiConstant.forBoolean(u.getBoolean(value, displacement));
+            case Byte:
+                return CiConstant.forByte(u.getByte(value, displacement));
+            case Char:
+                return CiConstant.forChar(u.getChar(value, displacement));
+            case Short:
+                return CiConstant.forShort(u.getShort(value, displacement));
+            case Int:
+                return CiConstant.forInt(u.getInt(value, displacement));
+            case Long:
+                return CiConstant.forLong(u.getLong(value, displacement));
+            case Float:
+                return CiConstant.forFloat(u.getFloat(value, displacement));
+            case Double:
+                return CiConstant.forDouble(u.getDouble(value, displacement));
+            case Object:
+                return CiConstant.forObject(u.getObject(value, displacement));
+            default:
+                assert false : "unexpected kind: " + this;
+                return null;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiMonitorValue.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011, 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.max.cri.ci;
+
+public final class CiMonitorValue extends CiValue {
+    private static final long serialVersionUID = 8241681800464483691L;
+
+    public CiValue owner;
+    public final CiValue lockData;
+    public final boolean eliminated;
+
+    public CiMonitorValue(CiValue owner, CiValue lockData, boolean eliminated) {
+        super(CiKind.Illegal);
+        this.owner = owner;
+        this.lockData = lockData;
+        this.eliminated = eliminated;
+    }
+
+    @Override
+    public String toString() {
+        return "monitor[" + owner + (lockData != null ? ", " + lockData : "") + (eliminated ? ", eliminated" : "") + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiRegister.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ci;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Represents a target machine register.
+ */
+public final class CiRegister implements Comparable<CiRegister>, Serializable {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -7213269157816016300L;
+
+    /**
+     * Invalid register.
+     */
+    public static final CiRegister None = new CiRegister(-1, -1, 0, "noreg");
+
+    /**
+     * Frame pointer of the current method. All spill slots and outgoing stack-based arguments
+     * are addressed relative to this register.
+     */
+    public static final CiRegister Frame = new CiRegister(-2, -2, 0, "framereg", RegisterFlag.CPU);
+
+    public static final CiRegister CallerFrame = new CiRegister(-3, -3, 0, "callerframereg", RegisterFlag.CPU);
+
+    /**
+     * The identifier for this register that is unique across all the registers in a {@link CiArchitecture}.
+     * A valid register has {@code number > 0}.
+     */
+    public final int number;
+
+    /**
+     * The mnemonic of this register.
+     */
+    public final String name;
+
+    /**
+     * The actual encoding in a target machine instruction for this register, which may or
+     * may not be the same as {@link #number}.
+     */
+    public final int encoding;
+
+    /**
+     * The size of the stack slot used to spill the value of this register.
+     */
+    public final int spillSlotSize;
+
+    /**
+     * The set of {@link RegisterFlag} values associated with this register.
+     */
+    private final int flags;
+
+    /**
+     * An array of {@link CiRegisterValue} objects, for this register, with one entry
+     * per {@link CiKind}, indexed by {@link CiKind#ordinal}.
+     */
+    private final CiRegisterValue[] values;
+
+    /**
+     * Attributes that characterize a register in a useful way.
+     *
+     */
+    public enum RegisterFlag {
+        /**
+         * Denotes an integral (i.e. non floating point) register.
+         */
+        CPU,
+
+        /**
+         * Denotes a register whose lowest order byte can be addressed separately.
+         */
+        Byte,
+
+        /**
+         * Denotes a floating point register.
+         */
+        FPU;
+
+        public final int mask = 1 << (ordinal() + 1);
+    }
+
+    /**
+     * Creates a {@code CiRegister} instance.
+     *
+     * @param number unique identifier for the register
+     * @param encoding the target machine encoding for the register
+     * @param spillSlotSize the size of the stack slot used to spill the value of the register
+     * @param name the mnemonic name for the register
+     * @param flags the set of {@link RegisterFlag} values for the register
+     */
+    public CiRegister(int number, int encoding, int spillSlotSize, String name, RegisterFlag... flags) {
+        this.number = number;
+        this.name = name;
+        this.spillSlotSize = spillSlotSize;
+        this.flags = createMask(flags);
+        this.encoding = encoding;
+
+        values = new CiRegisterValue[CiKind.VALUES.length];
+        for (CiKind kind : CiKind.VALUES) {
+            values[kind.ordinal()] = new CiRegisterValue(kind, this);
+        }
+    }
+
+    private static int createMask(RegisterFlag... flags) {
+        int result = 0;
+        for (RegisterFlag f : flags) {
+            result |= f.mask;
+        }
+        return result;
+    }
+
+    public boolean isSet(RegisterFlag f) {
+        return (flags & f.mask) != 0;
+    }
+
+    /**
+     * Gets this register as a {@linkplain CiRegisterValue value} with a specified kind.
+     * @param kind the specified kind
+     * @return the {@link CiRegisterValue}
+     */
+    public CiRegisterValue asValue(CiKind kind) {
+        return values[kind.ordinal()];
+    }
+
+    /**
+     * Gets this register as a {@linkplain CiRegisterValue value} with no particular kind.
+     * @return a {@link CiRegisterValue} with {@link CiKind#Illegal} kind.
+     */
+    public CiRegisterValue asValue() {
+        return asValue(CiKind.Illegal);
+    }
+
+    /**
+     * Determines if this is a valid register.
+     * @return {@code true} iff this register is valid
+     */
+    public boolean isValid() {
+        return number >= 0;
+    }
+
+    /**
+     * Determines if this a floating point register.
+     */
+    public boolean isFpu() {
+        return isSet(RegisterFlag.FPU);
+    }
+
+    /**
+     * Determines if this a general purpose register.
+     */
+    public boolean isCpu() {
+        return isSet(RegisterFlag.CPU);
+    }
+
+    /**
+     * Determines if this register has the {@link RegisterFlag#Byte} attribute set.
+     * @return {@code true} iff this register has the {@link RegisterFlag#Byte} attribute set.
+     */
+    public boolean isByte() {
+        return isSet(RegisterFlag.Byte);
+    }
+
+    /**
+     * Categorizes a set of registers by {@link RegisterFlag}.
+     *
+     * @param registers a list of registers to be categorized
+     * @return a map from each {@link RegisterFlag} constant to the list of registers for which the flag is
+     *         {@linkplain #isSet(RegisterFlag) set}
+     */
+    public static EnumMap<RegisterFlag, CiRegister[]> categorize(CiRegister[] registers) {
+        EnumMap<RegisterFlag, CiRegister[]> result = new EnumMap<>(RegisterFlag.class);
+        for (RegisterFlag flag : RegisterFlag.values()) {
+            ArrayList<CiRegister> list = new ArrayList<>();
+            for (CiRegister r : registers) {
+                if (r.isSet(flag)) {
+                    list.add(r);
+                }
+            }
+            result.put(flag, list.toArray(new CiRegister[list.size()]));
+        }
+        return result;
+    }
+
+    /**
+     * Gets the maximum register {@linkplain #number number} in a given set of registers.
+     *
+     * @param registers the set of registers to process
+     * @return the maximum register number for any register in {@code registers}
+     */
+    public static int maxRegisterNumber(CiRegister[] registers) {
+        int max = Integer.MIN_VALUE;
+        for (CiRegister r : registers) {
+            if (r.number > max) {
+                max = r.number;
+            }
+        }
+        return max;
+    }
+
+    /**
+     * Gets the maximum register {@linkplain #encoding encoding} in a given set of registers.
+     *
+     * @param registers the set of registers to process
+     * @return the maximum register encoding for any register in {@code registers}
+     */
+    public static int maxRegisterEncoding(CiRegister[] registers) {
+        int max = Integer.MIN_VALUE;
+        for (CiRegister r : registers) {
+            if (r.encoding > max) {
+                max = r.encoding;
+            }
+        }
+        return max;
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    @Override
+    public int compareTo(CiRegister o) {
+        if (number < o.number) {
+            return -1;
+        }
+        if (number > o.number) {
+            return 1;
+        }
+        return 0;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiRegisterConfig.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2010, 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.max.cri.ci;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.CiCallingConvention.*;
+import com.oracle.max.cri.ci.CiRegister.*;
+import com.oracle.max.cri.ri.*;
+
+/**
+ * A default implementation of {@link RiRegisterConfig}.
+ */
+public class CiRegisterConfig implements RiRegisterConfig {
+
+    /**
+     * The object describing the callee save area of this register configuration.
+     */
+    public CiCalleeSaveLayout csl;
+
+    /**
+     * The minimum register role identifier.
+     */
+    public final int minRole;
+
+    /**
+     * The map from register role IDs to registers.
+     */
+    public final CiRegister[] registersRoleMap;
+
+    /**
+     * The set of registers that can be used by the register allocator.
+     */
+    public final CiRegister[] allocatable;
+
+    /**
+     * The set of registers that can be used by the register allocator,
+     * {@linkplain CiRegister#categorize(CiRegister[]) categorized} by register
+     * {@linkplain RegisterFlag flags}.
+     */
+    public final EnumMap<RegisterFlag, CiRegister[]> categorized;
+
+    /**
+     * The ordered set of registers used to pass integral arguments.
+     */
+    public final CiRegister[] cpuParameters;
+
+    /**
+     * The ordered set of registers used to pass floating point arguments.
+     */
+    public final CiRegister[] fpuParameters;
+
+    /**
+     * The caller saved registers.
+     */
+    public final CiRegister[] callerSave;
+
+    /**
+     * The register to which {@link CiRegister#Frame} and {@link CiRegister#CallerFrame} are bound.
+     */
+    public final CiRegister frame;
+
+    /**
+     * Register for returning an integral value.
+     */
+    public final CiRegister integralReturn;
+
+    /**
+     * Register for returning a floating point value.
+     */
+    public final CiRegister floatingPointReturn;
+
+    /**
+     * The map from register {@linkplain CiRegister#number numbers} to register
+     * {@linkplain RiRegisterAttributes attributes} for this register configuration.
+     */
+    public final RiRegisterAttributes[] attributesMap;
+
+    /**
+     * The scratch register.
+     */
+    public final CiRegister scratch;
+
+    /**
+     * The frame offset of the first stack argument for each calling convention {@link CiCallingConvention.Type}.
+     */
+    public final int[] stackArg0Offsets = new int[CiCallingConvention.Type.VALUES.length];
+
+    public CiRegisterConfig(
+                    CiRegister frame,
+                    CiRegister integralReturn,
+                    CiRegister floatingPointReturn,
+                    CiRegister scratch,
+                    CiRegister[] allocatable,
+                    CiRegister[] callerSave,
+                    CiRegister[] parameters,
+                    CiCalleeSaveLayout csl,
+                    CiRegister[] allRegisters,
+                    Map<Integer, CiRegister> roles) {
+        this.frame = frame;
+        this.csl = csl;
+        this.allocatable = allocatable;
+        this.callerSave = callerSave;
+        assert !Arrays.asList(allocatable).contains(scratch);
+        this.scratch = scratch;
+        EnumMap<RegisterFlag, CiRegister[]> categorizedParameters = CiRegister.categorize(parameters);
+        this.cpuParameters = categorizedParameters.get(RegisterFlag.CPU);
+        this.fpuParameters = categorizedParameters.get(RegisterFlag.FPU);
+        categorized = CiRegister.categorize(allocatable);
+        attributesMap = RiRegisterAttributes.createMap(this, allRegisters);
+        this.floatingPointReturn = floatingPointReturn;
+        this.integralReturn = integralReturn;
+        int minRoleId = Integer.MAX_VALUE;
+        int maxRoleId = Integer.MIN_VALUE;
+        for (Map.Entry<Integer, CiRegister> e : roles.entrySet()) {
+            int id = e.getKey();
+            assert id >= 0;
+            if (minRoleId > id) {
+                minRoleId = id;
+            }
+            if (maxRoleId < id) {
+                maxRoleId = id;
+            }
+        }
+        registersRoleMap = new CiRegister[(maxRoleId - minRoleId) + 1];
+        for (Map.Entry<Integer, CiRegister> e : roles.entrySet()) {
+            int id = e.getKey();
+            registersRoleMap[id] = e.getValue();
+        }
+        minRole = minRoleId;
+    }
+
+    public CiRegisterConfig(CiRegisterConfig src, CiCalleeSaveLayout csl) {
+        this.frame = src.frame;
+        this.csl = csl;
+        this.allocatable = src.allocatable;
+        this.callerSave = src.callerSave;
+        this.scratch = src.scratch;
+        this.cpuParameters = src.cpuParameters;
+        this.fpuParameters = src.fpuParameters;
+        this.categorized = src.categorized;
+        this.attributesMap = src.attributesMap;
+        this.floatingPointReturn = src.floatingPointReturn;
+        this.integralReturn = src.integralReturn;
+        this.registersRoleMap = src.registersRoleMap;
+        this.minRole = src.minRole;
+        System.arraycopy(src.stackArg0Offsets, 0, stackArg0Offsets, 0, stackArg0Offsets.length);
+    }
+
+    public CiRegister getReturnRegister(CiKind kind) {
+        if (kind.isDouble() || kind.isFloat()) {
+            return floatingPointReturn;
+        }
+        return integralReturn;
+    }
+
+    public CiRegister getFrameRegister() {
+        return frame;
+    }
+
+    public CiRegister getScratchRegister() {
+        return scratch;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * This implementation assigns all available registers to parameters before assigning
+     * any stack slots to parameters.
+     */
+    public CiCallingConvention getCallingConvention(Type type, CiKind[] parameters, CiTarget target, boolean stackOnly) {
+        CiValue[] locations = new CiValue[parameters.length];
+
+        int currentGeneral = 0;
+        int currentXMM = 0;
+        int currentStackOffset = stackArg0Offsets[type.ordinal()];
+
+        for (int i = 0; i < parameters.length; i++) {
+            final CiKind kind = parameters[i];
+
+            switch (kind) {
+                case Byte:
+                case Boolean:
+                case Short:
+                case Char:
+                case Int:
+                case Long:
+                case Object:
+                    if (!stackOnly && currentGeneral < cpuParameters.length) {
+                        CiRegister register = cpuParameters[currentGeneral++];
+                        locations[i] = register.asValue(kind);
+                    }
+                    break;
+
+                case Float:
+                case Double:
+                    if (!stackOnly && currentXMM < fpuParameters.length) {
+                        CiRegister register = fpuParameters[currentXMM++];
+                        locations[i] = register.asValue(kind);
+                    }
+                    break;
+
+                default:
+                    throw new InternalError("Unexpected parameter kind: " + kind);
+            }
+
+            if (locations[i] == null) {
+                locations[i] = CiStackSlot.get(kind.stackKind(), currentStackOffset, !type.out);
+                currentStackOffset += Math.max(target.sizeInBytes(kind), target.wordSize);
+            }
+        }
+
+        return new CiCallingConvention(locations, currentStackOffset);
+    }
+
+    public CiRegister[] getCallingConventionRegisters(Type type, RegisterFlag flag) {
+        if (flag == RegisterFlag.CPU) {
+            return cpuParameters;
+        }
+        assert flag == RegisterFlag.FPU;
+        return fpuParameters;
+    }
+
+    public CiRegister[] getAllocatableRegisters() {
+        return allocatable;
+    }
+
+    public EnumMap<RegisterFlag, CiRegister[]> getCategorizedAllocatableRegisters() {
+        return categorized;
+    }
+
+    public CiRegister[] getCallerSaveRegisters() {
+        return callerSave;
+    }
+
+    public CiCalleeSaveLayout getCalleeSaveLayout() {
+        return csl;
+    }
+
+    public RiRegisterAttributes[] getAttributesMap() {
+        return attributesMap;
+    }
+
+    public CiRegister getRegisterForRole(int id) {
+        return registersRoleMap[id - minRole];
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder roleMap = new StringBuilder();
+        for (int i = 0; i < registersRoleMap.length; ++i) {
+            CiRegister reg = registersRoleMap[i];
+            if (reg != null) {
+                if (roleMap.length() != 0) {
+                    roleMap.append(", ");
+                }
+                roleMap.append(i + minRole).append(" -> ").append(reg);
+            }
+        }
+        StringBuilder stackArg0OffsetsMap = new StringBuilder();
+        for (Type t : Type.VALUES) {
+            if (stackArg0OffsetsMap.length() != 0) {
+                stackArg0OffsetsMap.append(", ");
+            }
+            stackArg0OffsetsMap.append(t).append(" -> ").append(stackArg0Offsets[t.ordinal()]);
+        }
+        String res = String.format(
+             "Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" +
+             "CallerSave:  " + Arrays.toString(getCallerSaveRegisters()) + "%n" +
+             "CalleeSave:  " + getCalleeSaveLayout() + "%n" +
+             "CPU Params:  " + Arrays.toString(cpuParameters) + "%n" +
+             "FPU Params:  " + Arrays.toString(fpuParameters) + "%n" +
+             "VMRoles:     " + roleMap + "%n" +
+             "stackArg0:   " + stackArg0OffsetsMap + "%n" +
+             "Scratch:     " + getScratchRegister() + "%n");
+        return res;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiRegisterValue.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.cri.ci;
+
+/**
+ * Denotes a register that stores a value of a fixed kind. There is exactly one (canonical) instance of {@code
+ * CiRegisterValue} for each ({@link CiRegister}, {@link CiKind}) pair. Use {@link CiRegister#asValue(CiKind)} to
+ * retrieve the canonical {@link CiRegisterValue} instance for a given (register,kind) pair.
+ */
+public final class CiRegisterValue extends CiValue {
+    private static final long serialVersionUID = 7999341472196897163L;
+
+    /**
+     * The register.
+     */
+    public final CiRegister reg;
+
+    /**
+     * Should only be called from {@link CiRegister#CiRegister} to ensure canonicalization.
+     */
+    protected CiRegisterValue(CiKind kind, CiRegister register) {
+        super(kind);
+        this.reg = register;
+    }
+
+    @Override
+    public int hashCode() {
+        return (reg.number << 4) ^ kind.ordinal();
+    }
+
+    @Override
+    public String toString() {
+        return reg.name + kindSuffix();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiRuntimeCall.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ci;
+
+import static com.oracle.max.cri.ci.CiKind.*;
+
+/**
+ * Enumerates the calls that must be provided by the runtime system. The compiler
+ * may generate code that calls the runtime services for unresolved and slow cases of some
+ * bytecodes.
+ */
+public enum CiRuntimeCall {
+    UnwindException(Void, Object),
+    Deoptimize(Void),
+    RegisterFinalizer(Void, Object),
+    SetDeoptInfo(Void, Object),
+    CreateNullPointerException(Object),
+    CreateOutOfBoundsException(Object, Int),
+    JavaTimeMillis(Long),
+    JavaTimeNanos(Long),
+    Debug(Void),
+    ArithmeticFrem(Float, Float, Float),
+    ArithmeticDrem(Double, Double, Double),
+    ArithmeticCos(Double, Double),
+    ArithmeticTan(Double, Double),
+    ArithmeticSin(Double, Double),
+    GenericCallback(Object, Object, Object);
+
+    public final CiKind resultKind;
+    public final CiKind[] arguments;
+
+    private CiRuntimeCall(CiKind resultKind, CiKind... args) {
+        this.resultKind = resultKind;
+        this.arguments = args;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiStackSlot.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2010, 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.max.cri.ci;
+
+import static com.oracle.max.cri.ci.CiKind.*;
+
+/**
+ * Represents a compiler spill slot or an outgoing stack-based argument in a method's frame
+ * or an incoming stack-based argument in a method's {@linkplain #inCallerFrame() caller's frame}.
+ */
+public final class CiStackSlot extends CiValue {
+    private static final long serialVersionUID = -7725071921307318433L;
+
+    private final int offset;
+    private final boolean addFrameSize;
+
+    /**
+     * Gets a {@link CiStackSlot} instance representing a stack slot at a given index
+     * holding a value of a given kind.
+     *
+     * @param kind The kind of the value stored in the stack slot.
+     * @param offset The offset of the stack slot (in bytes)
+     * @param inCallerFrame Specifies if the offset is relative to the stack pointer,
+     *        or the beginning of the frame (stack pointer + total frame size).
+     */
+    public static CiStackSlot get(CiKind kind, int offset, boolean addFrameSize) {
+        assert kind.stackKind() == kind;
+        assert addFrameSize || offset >= 0;
+
+        if (offset % CACHE_GRANULARITY == 0) {
+            CiStackSlot[][] cache;
+            int index = offset / CACHE_GRANULARITY;
+            if (!addFrameSize) {
+                cache = OUT_CACHE;
+            } else if (offset >= 0) {
+                cache = IN_CACHE;
+            } else {
+                cache = SPILL_CACHE;
+                index = -index;
+            }
+            CiStackSlot[] slots = cache[kind.ordinal()];
+            if (index < slots.length) {
+                CiStackSlot slot = slots[index];
+                assert slot.kind == kind && slot.offset == offset && slot.addFrameSize == addFrameSize;
+                return slot;
+            }
+        }
+        return new CiStackSlot(kind, offset, addFrameSize);
+    }
+
+    /**
+     * Private constructor to enforce use of {@link #get()} so that a cache can be used.
+     */
+    private CiStackSlot(CiKind kind, int offset, boolean addFrameSize) {
+        super(kind);
+        this.offset = offset;
+        this.addFrameSize = addFrameSize;
+    }
+
+    /**
+     * Gets the offset of this stack slot, relative to the stack pointer.
+     * @return The offset of this slot (in bytes).
+     */
+    public int offset(int totalFrameSize) {
+        assert totalFrameSize > 0 || !addFrameSize;
+        int result = offset + (addFrameSize ? totalFrameSize : 0);
+        assert result >= 0;
+        return result;
+    }
+
+    public boolean inCallerFrame() {
+        return addFrameSize && offset >= 0;
+    }
+
+    public int rawOffset() {
+        return offset;
+    }
+
+    public boolean rawAddFrameSize() {
+        return addFrameSize;
+    }
+
+    @Override
+    public int hashCode() {
+        return kind.ordinal() ^ (offset << 4) ^ (addFrameSize ? 15 : 0);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (o instanceof CiStackSlot) {
+            CiStackSlot l = (CiStackSlot) o;
+            return l.kind == kind && l.offset == offset && l.addFrameSize == addFrameSize;
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        if (!addFrameSize) {
+            return "out:" + offset + kindSuffix();
+        } else if (offset >= 0) {
+            return "in:" + offset + kindSuffix();
+        } else {
+            return "stack:" + (-offset) + kindSuffix();
+        }
+    }
+
+    /**
+     * Gets this stack slot used to pass an argument from the perspective of a caller.
+     */
+    public CiStackSlot asOutArg() {
+        assert offset >= 0;
+        if (addFrameSize) {
+            return get(kind, offset, false);
+        }
+        return this;
+    }
+
+    /**
+     * Gets this stack slot used to pass an argument from the perspective of a callee.
+     */
+    public CiStackSlot asInArg() {
+        assert offset >= 0;
+        if (!addFrameSize) {
+            return get(kind, offset, true);
+        }
+        return this;
+    }
+
+
+    private static final int CACHE_GRANULARITY = 8;
+    private static final int SPILL_CACHE_PER_KIND_SIZE = 100;
+    private static final int PARAM_CACHE_PER_KIND_SIZE = 10;
+
+    private static final CiStackSlot[][] SPILL_CACHE = makeCache(SPILL_CACHE_PER_KIND_SIZE, -1, true);
+    private static final CiStackSlot[][] IN_CACHE = makeCache(PARAM_CACHE_PER_KIND_SIZE, 1, true);
+    private static final CiStackSlot[][] OUT_CACHE = makeCache(PARAM_CACHE_PER_KIND_SIZE, 1, false);
+
+    private static CiStackSlot[][] makeCache(int cachePerKindSize, int sign, boolean addFrameSize) {
+        CiStackSlot[][] cache = new CiStackSlot[CiKind.VALUES.length][];
+        for (CiKind kind : new CiKind[] {Illegal, Int, Long, Float, Double, Object, Jsr}) {
+            CiStackSlot[] slots = new CiStackSlot[cachePerKindSize];
+            for (int i = 0; i < cachePerKindSize; i++) {
+                slots[i] = new CiStackSlot(kind, sign * i * CACHE_GRANULARITY, addFrameSize);
+            }
+            cache[kind.ordinal()] = slots;
+        }
+        return cache;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiTarget.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.cri.ci;
+
+
+/**
+ * Represents the target machine for a compiler, including the CPU architecture, the size of pointers and references,
+ * alignment of stacks, caches, etc.
+ */
+public class CiTarget {
+    public final CiArchitecture arch;
+
+    /**
+     * The OS page size.
+     */
+    public final int pageSize;
+
+    /**
+     * Specifies if this is a multi-processor system.
+     */
+    public final boolean isMP;
+
+    /**
+     * Specifies if this target supports encoding objects inline in the machine code.
+     */
+    public final boolean inlineObjects;
+
+    /**
+     * The machine word size on this target.
+     */
+    public final int wordSize;
+
+    /**
+     * The CiKind to be used for representing raw pointers and CPU registers.
+     */
+    public final CiKind wordKind;
+
+    /**
+     * The stack alignment requirement of the platform. For example,
+     * from Appendix D of <a href="http://www.intel.com/Assets/PDF/manual/248966.pdf">Intel 64 and IA-32 Architectures Optimization Reference Manual</a>:
+     * <pre>
+     *     "It is important to ensure that the stack frame is aligned to a
+     *      16-byte boundary upon function entry to keep local __m128 data,
+     *      parameters, and XMM register spill locations aligned throughout
+     *      a function invocation."
+     * </pre>
+     */
+    public final int stackAlignment;
+
+    /**
+     * @see http://docs.sun.com/app/docs/doc/806-0477/6j9r2e2b9?a=view
+     */
+    public final int stackBias;
+
+    /**
+     * The cache alignment.
+     */
+    public final int cacheAlignment;
+
+    /**
+     * Specifies how {@code long} and {@code double} constants are to be stored
+     * in {@linkplain CiFrame frames}. This is useful for VMs such as HotSpot
+     * where convention the interpreter uses is that the second local
+     * holds the first raw word of the native long or double representation.
+     * This is actually reasonable, since locals and stack arrays
+     * grow downwards in all implementations.
+     * If, on some machine, the interpreter's Java locals or stack
+     * were to grow upwards, the embedded doubles would be word-swapped.)
+     */
+    public final boolean debugInfoDoubleWordsInSecondSlot;
+
+    /**
+     * Temporary flag to distinguish between the semantics necessary for HotSpot and Maxine.
+     */
+    // TODO This should go away when XIR goes away, and the logic be part of the VM-specific lowering.
+    public final boolean invokeSnippetAfterArguments;
+
+    public CiTarget(CiArchitecture arch,
+             boolean isMP,
+             int stackAlignment,
+             int pageSize,
+             int cacheAlignment,
+             boolean inlineObjects,
+             boolean debugInfoDoubleWordsInSecondSlot,
+             boolean invokeSnippetAfterArguments) {
+        this.arch = arch;
+        this.pageSize = pageSize;
+        this.isMP = isMP;
+        this.wordSize = arch.wordSize;
+        if (wordSize == 8) {
+            this.wordKind = CiKind.Long;
+        } else {
+            this.wordKind = CiKind.Int;
+        }
+        this.stackAlignment = stackAlignment;
+        this.stackBias = 0; // TODO: configure with param once SPARC port exists
+        this.cacheAlignment = cacheAlignment;
+        this.inlineObjects = inlineObjects;
+        this.debugInfoDoubleWordsInSecondSlot = debugInfoDoubleWordsInSecondSlot;
+        this.invokeSnippetAfterArguments = invokeSnippetAfterArguments;
+    }
+
+    /**
+     * Gets the size in bytes of the specified kind for this target.
+     *
+     * @param kind the kind for which to get the size
+     * @return the size in bytes of {@code kind}
+     */
+    public int sizeInBytes(CiKind kind) {
+        // Checkstyle: stop
+        switch (kind) {
+            case Boolean: return 1;
+            case Byte: return 1;
+            case Char: return 2;
+            case Short: return 2;
+            case Int: return 4;
+            case Long: return 8;
+            case Float: return 4;
+            case Double: return 8;
+            case Object: return wordSize;
+            case Jsr: return 4;
+            default: return 0;
+        }
+        // Checkstyle: resume
+    }
+
+    /**
+     * Aligns the given frame size (without return instruction pointer) to the stack
+     * alignment size and return the aligned size (without return instruction pointer).
+     * @param frameSize the initial frame size to be aligned
+     * @return the aligned frame size
+     */
+    public int alignFrameSize(int frameSize) {
+        int x = frameSize + arch.returnAddressSize + (stackAlignment - 1);
+        return (x / stackAlignment) * stackAlignment - arch.returnAddressSize;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiTargetMethod.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,588 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ci;
+
+import java.io.*;
+import java.util.*;
+
+import com.oracle.max.cri.ri.*;
+
+/**
+ * Represents the output from compiling a method, including the compiled machine code, associated data and references,
+ * relocation information, deoptimization information, etc. It is the essential component of a {@link CiResult}, which also includes
+ * {@linkplain CiStatistics compilation statistics} and {@linkplain CiBailout failure information}.
+ */
+public class CiTargetMethod implements Serializable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -1319947729753702434L;
+
+    /**
+     * Represents a code position with associated additional information.
+     */
+    public abstract static class Site implements Serializable {
+        /**
+         *
+         */
+        private static final long serialVersionUID = -8214214947651979102L;
+        /**
+         * The position (or offset) of this site with respect to the start of the target method.
+         */
+        public final int pcOffset;
+
+        public Site(int pos) {
+            this.pcOffset = pos;
+        }
+    }
+
+    /**
+     * Represents a safepoint with associated debug info.
+     */
+    public static class Safepoint extends Site implements Comparable<Safepoint> {
+        /**
+         *
+         */
+        private static final long serialVersionUID = 2479806696381720162L;
+        public final CiDebugInfo debugInfo;
+
+        Safepoint(int pcOffset, CiDebugInfo debugInfo) {
+            super(pcOffset);
+            this.debugInfo = debugInfo;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(pcOffset);
+            sb.append("[<safepoint>]");
+            appendDebugInfo(sb, debugInfo);
+            return sb.toString();
+        }
+
+        @Override
+        public int compareTo(Safepoint o) {
+            if (pcOffset < o.pcOffset) {
+                return -1;
+            } else if (pcOffset > o.pcOffset) {
+                return 1;
+            }
+            return 0;
+        }
+    }
+
+    /**
+     * Represents a call in the code.
+     */
+    public static final class Call extends Safepoint {
+        /**
+         *
+         */
+        private static final long serialVersionUID = 1440741241631046954L;
+
+        /**
+         * The target of the call.
+         */
+        public final Object target;
+
+        /**
+         * The size of the call instruction.
+         */
+        public final int size;
+
+        /**
+         * Specifies if this call is direct or indirect. A direct call has an immediate operand encoding
+         * the absolute or relative (to the call itself) address of the target. An indirect call has a
+         * register or memory operand specifying the target address of the call.
+         */
+        public final boolean direct;
+
+        Call(Object target, int pcOffset, int size, boolean direct, CiDebugInfo debugInfo) {
+            super(pcOffset, debugInfo);
+            this.size = size;
+            this.target = target;
+            this.direct = direct;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(pcOffset);
+            sb.append('[');
+            sb.append(target);
+            sb.append(']');
+
+            if (debugInfo != null) {
+                appendDebugInfo(sb, debugInfo);
+            }
+
+            return sb.toString();
+        }
+    }
+
+    /**
+     * Represents a reference to data from the code. The associated data can be any constant.
+     */
+    public static final class DataPatch extends Site {
+        /**
+         *
+         */
+        private static final long serialVersionUID = 5771730331604867476L;
+        public final CiConstant constant;
+        public final int alignment;
+
+        DataPatch(int pcOffset, CiConstant data, int alignment) {
+            super(pcOffset);
+            this.constant = data;
+            this.alignment = alignment;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%d[<data patch referring to data %s>]", pcOffset, constant);
+        }
+    }
+
+    /**
+     * Provides extra information about instructions or data at specific positions in {@link CiTargetMethod#targetCode()}.
+     * This is optional information that can be used to enhance a disassembly of the code.
+     */
+    public abstract static class CodeAnnotation implements Serializable {
+        /**
+         *
+         */
+        private static final long serialVersionUID = -7903959680749520748L;
+        public final int position;
+
+        public CodeAnnotation(int position) {
+            this.position = position;
+        }
+    }
+
+    /**
+     * A string comment about one or more instructions at a specific position in the code.
+     */
+    public static final class CodeComment extends CodeAnnotation {
+        /**
+         *
+         */
+        private static final long serialVersionUID = 6802287188701961401L;
+        public final String value;
+        public CodeComment(int position, String comment) {
+            super(position);
+            this.value = comment;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getSimpleName() + "@" + position + ": " + value;
+        }
+    }
+
+    /**
+     * Labels some inline data in the code.
+     */
+    public static final class InlineData extends CodeAnnotation {
+        /**
+         *
+         */
+        private static final long serialVersionUID = 305997507263827108L;
+        public final int size;
+        public InlineData(int position, int size) {
+            super(position);
+            this.size = size;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getSimpleName() + "@" + position + ": size=" + size;
+        }
+    }
+
+    /**
+     * Describes a table of signed offsets embedded in the code. The offsets are relative to the starting
+     * address of the table. This type of table maybe generated when translating a multi-way branch
+     * based on a key value from a dense value set (e.g. the {@code tableswitch} JVM instruction).
+     *
+     * The table is indexed by the contiguous range of integers from {@link #low} to {@link #high} inclusive.
+     */
+    public static final class JumpTable extends CodeAnnotation {
+        /**
+         *
+         */
+        private static final long serialVersionUID = 2222194398353801831L;
+
+        /**
+         * The low value in the key range (inclusive).
+         */
+        public final int low;
+
+        /**
+         * The high value in the key range (inclusive).
+         */
+        public final int high;
+
+        /**
+         * The size (in bytes) of each table entry.
+         */
+        public final int entrySize;
+
+        public JumpTable(int position, int low, int high, int entrySize) {
+            super(position);
+            this.low = low;
+            this.high = high;
+            this.entrySize = entrySize;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getSimpleName() + "@" + position + ": [" + low + " .. " + high + "]";
+        }
+    }
+
+    /**
+     * Describes a table of key and offset pairs. The offset in each table entry is relative to the address of
+     * the table. This type of table maybe generated when translating a multi-way branch
+     * based on a key value from a sparse value set (e.g. the {@code lookupswitch} JVM instruction).
+     */
+    public static final class LookupTable extends CodeAnnotation {
+        /**
+         *
+         */
+        private static final long serialVersionUID = 8367952567559116160L;
+
+        /**
+         * The number of entries in the table.
+         */
+        public final int npairs;
+
+        /**
+         * The size (in bytes) of entry's key.
+         */
+        public final int keySize;
+
+        /**
+         * The size (in bytes) of entry's offset value.
+         */
+        public final int offsetSize;
+
+        public LookupTable(int position, int npairs, int keySize, int offsetSize) {
+            super(position);
+            this.npairs = npairs;
+            this.keySize = keySize;
+            this.offsetSize = offsetSize;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getSimpleName() + "@" + position + ": [npairs=" + npairs + ", keySize=" + keySize + ", offsetSize=" + offsetSize + "]";
+        }
+    }
+
+    /**
+     * Represents exception handler information for a specific code position. It includes the catch code position as
+     * well as the caught exception type.
+     */
+    public static final class ExceptionHandler extends Site {
+        /**
+         *
+         */
+        private static final long serialVersionUID = 4897339464722665281L;
+        public final int handlerPos;
+
+        ExceptionHandler(int pcOffset, int handlerPos) {
+            super(pcOffset);
+            this.handlerPos = handlerPos;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%d[<exception edge to %d>]", pcOffset, handlerPos);
+        }
+    }
+
+    public static final class Mark extends Site {
+        /**
+         *
+         */
+        private static final long serialVersionUID = 3612943150662354844L;
+        public final Object id;
+        public final Mark[] references;
+
+        Mark(int pcOffset, Object id, Mark[] references) {
+            super(pcOffset);
+            this.id = id;
+            this.references = references;
+        }
+
+        @Override
+        public String toString() {
+            if (id == null) {
+                return String.format("%d[<mark with %d references>]", pcOffset, references.length);
+            } else if (id instanceof Integer) {
+                return String.format("%d[<mark with %d references and id %s>]", pcOffset, references.length, Integer.toHexString((Integer) id));
+            } else {
+                return String.format("%d[<mark with %d references and id %s>]", pcOffset, references.length, id.toString());
+            }
+        }
+    }
+
+    /**
+     * List of safepoints, sorted by {@link Site#pcOffset}.
+     */
+    public final List<Safepoint> safepoints = new ArrayList<>();
+
+    /**
+     * List of data references.
+     */
+    public final List<DataPatch> dataReferences = new ArrayList<>();
+
+    /**
+     * List of exception handlers.
+     */
+    public final List<ExceptionHandler> exceptionHandlers = new ArrayList<>();
+
+    /**
+     * List of marks.
+     */
+    public final List<Mark> marks = new ArrayList<>();
+
+    private int frameSize = -1;
+    private int customStackAreaOffset = -1;
+    private int registerRestoreEpilogueOffset = -1;
+    /**
+     * The buffer containing the emitted machine code.
+     */
+    private byte[] targetCode;
+
+    /**
+     * The leading number of bytes in {@link #targetCode} containing the emitted machine code.
+     */
+    private int targetCodeSize;
+
+    private ArrayList<CodeAnnotation> annotations;
+
+    private CiAssumptions assumptions;
+
+    /**
+     * Constructs a new target method.
+     */
+    public CiTargetMethod() {
+    }
+
+    public void setAssumptions(CiAssumptions assumptions) {
+        this.assumptions = assumptions;
+    }
+
+    public CiAssumptions assumptions() {
+        return assumptions;
+    }
+
+    /**
+     * Sets the frame size in bytes. Does not include the return address pushed onto the
+     * stack, if any.
+     *
+     * @param size the size of the frame in bytes
+     */
+    public void setFrameSize(int size) {
+        frameSize = size;
+    }
+
+    /**
+     * Sets the machine that has been generated by the compiler.
+     *
+     * @param code the machine code generated
+     * @param size the size of the machine code
+     */
+    public void setTargetCode(byte[] code, int size) {
+        targetCode = code;
+        targetCodeSize = size;
+    }
+
+    /**
+     * Records a reference to the data section in the code section (e.g. to load an integer or floating point constant).
+     *
+     * @param codePos the position in the code where the data reference occurs
+     * @param data the data that is referenced
+     * @param alignment the alignment requirement of the data or 0 if there is no alignment requirement
+     */
+    public void recordDataReference(int codePos, CiConstant data, int alignment) {
+        assert codePos >= 0 && data != null;
+        dataReferences.add(new DataPatch(codePos, data, alignment));
+    }
+
+    /**
+     * Records a call in the code array.
+     *
+     * @param codePos the position of the call in the code array
+     * @param size the size of the call instruction
+     * @param target the {@link RiRuntime#asCallTarget(Object) target} being called
+     * @param debugInfo the debug info for the call
+     * @param direct specifies if this is a {@linkplain Call#direct direct} call
+     */
+    public void recordCall(int codePos, int size, Object target, CiDebugInfo debugInfo, boolean direct) {
+        final Call call = new Call(target, codePos, size, direct, debugInfo);
+        addSafepoint(call);
+    }
+
+    /**
+     * Records an exception handler for this method.
+     *
+     * @param codePos  the position in the code that is covered by the handler
+     * @param handlerPos    the position of the handler
+     * @param throwableType the type of exceptions handled by the handler
+     */
+    public void recordExceptionHandler(int codePos, int handlerPos) {
+        exceptionHandlers.add(new ExceptionHandler(codePos, handlerPos));
+    }
+
+    /**
+     * Records a safepoint in the code array.
+     *
+     * @param codePos the position of the safepoint in the code array
+     * @param debugInfo the debug info for the safepoint
+     */
+    public void recordSafepoint(int codePos, CiDebugInfo debugInfo) {
+        addSafepoint(new Safepoint(codePos, debugInfo));
+    }
+
+    private void addSafepoint(Safepoint safepoint) {
+        // The safepoints list must always be sorted
+        if (!safepoints.isEmpty() && safepoints.get(safepoints.size() - 1).pcOffset >= safepoint.pcOffset) {
+            // This re-sorting should be very rare
+            Collections.sort(safepoints);
+        }
+        safepoints.add(safepoint);
+    }
+
+    /**
+     * Records an instruction mark within this method.
+     *
+     * @param codePos the position in the code that is covered by the handler
+     * @param id the identifier for this mark
+     * @param references an array of other marks that this mark references
+     */
+    public Mark recordMark(int codePos, Object id, Mark[] references) {
+        Mark mark = new Mark(codePos, id, references);
+        marks.add(mark);
+        return mark;
+    }
+
+    /**
+     * Allows a method to specify the offset of the epilogue that restores the callee saved registers. Must be called
+     * iff the method is a callee saved method and stores callee registers on the stack.
+     *
+     * @param registerRestoreEpilogueOffset the offset in the machine code where the epilogue begins
+     */
+    public void setRegisterRestoreEpilogueOffset(int registerRestoreEpilogueOffset) {
+        assert this.registerRestoreEpilogueOffset == -1;
+        this.registerRestoreEpilogueOffset = registerRestoreEpilogueOffset;
+    }
+
+    /**
+     * The frame size of the method in bytes.
+     *
+     * @return the frame size
+     */
+    public int frameSize() {
+        assert frameSize != -1 : "frame size not yet initialized!";
+        return frameSize;
+    }
+
+    /**
+     * @return the code offset of the start of the epilogue that restores all callee saved registers, or -1 if this is
+     *         not a callee saved method
+     */
+    public int registerRestoreEpilogueOffset() {
+        return registerRestoreEpilogueOffset;
+    }
+
+    /**
+     * Offset in bytes for the custom stack area (relative to sp).
+     * @return the offset in bytes
+     */
+    public int customStackAreaOffset() {
+        return customStackAreaOffset;
+    }
+
+    /**
+     * @see #customStackAreaOffset()
+     * @param offset
+     */
+    public void setCustomStackAreaOffset(int offset) {
+        customStackAreaOffset = offset;
+    }
+
+    /**
+     * @return the machine code generated for this method
+     */
+    public byte[] targetCode() {
+        return targetCode;
+    }
+
+    /**
+     * @return the size of the machine code generated for this method
+     */
+    public int targetCodeSize() {
+        return targetCodeSize;
+    }
+
+    /**
+     * @return the code annotations or {@code null} if there are none
+     */
+    public List<CodeAnnotation> annotations() {
+        return annotations;
+    }
+
+    public void addAnnotation(CodeAnnotation annotation) {
+        assert annotation != null;
+        if (annotations == null) {
+            annotations = new ArrayList<>();
+        }
+        annotations.add(annotation);
+    }
+
+    private static void appendDebugInfo(StringBuilder sb, CiDebugInfo info) {
+        if (info != null) {
+            appendRefMap(sb, "stackMap", info.frameRefMap);
+            appendRefMap(sb, "registerMap", info.registerRefMap);
+            CiCodePos codePos = info.codePos;
+            if (codePos != null) {
+                CiUtil.appendLocation(sb.append(" "), codePos.method, codePos.bci);
+                if (info.hasFrame()) {
+                    sb.append(" #locals=").append(info.frame().numLocals).append(" #expr=").append(info.frame().numStack);
+                    if (info.frame().numLocks > 0) {
+                        sb.append(" #locks=").append(info.frame().numLocks);
+                    }
+                }
+            }
+        }
+    }
+
+    private static void appendRefMap(StringBuilder sb, String name, CiBitMap map) {
+        if (map != null) {
+            sb.append(' ').append(name).append('[').append(map.toBinaryString()).append(']');
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiUtil.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,747 @@
+/*
+ * Copyright (c) 2010, 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.max.cri.ci;
+
+import static java.lang.reflect.Modifier.*;
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import com.oracle.max.cri.ri.*;
+
+/**
+ * Miscellaneous collection of utility methods used in the {@code CRI} project.
+ */
+public class CiUtil {
+
+    public static final String NEW_LINE = String.format("%n");
+
+    /**
+     * Gets the annotation of a particular type for a formal parameter of a given method.
+     *
+     * @param annotationClass the Class object corresponding to the annotation type
+     * @param parameterIndex the index of a formal parameter of {@code method}
+     * @param method the method for which a parameter annotation is being requested
+     * @return the annotation of type {@code annotationClass} for the formal parameter present, else null
+     * @throws IndexOutOfBoundsException if {@code parameterIndex} does not denote a formal parameter
+     */
+    public static <T extends Annotation> T getParameterAnnotation(Class<T> annotationClass, int parameterIndex, RiResolvedMethod method) {
+        if (parameterIndex >= 0) {
+            Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+            for (Annotation a : parameterAnnotations[parameterIndex]) {
+                if (a.annotationType() == annotationClass) {
+                    return annotationClass.cast(a);
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Extends the functionality of {@link Class#getSimpleName()} to include a non-empty string for anonymous and local
+     * classes.
+     *
+     * @param clazz the class for which the simple name is being requested
+     * @param withEnclosingClass specifies if the returned name should be qualified with the name(s) of the enclosing
+     *            class/classes of {@code clazz} (if any). This option is ignored if {@code clazz} denotes an anonymous
+     *            or local class.
+     * @return the simple name
+     */
+    public static String getSimpleName(Class< ? > clazz, boolean withEnclosingClass) {
+        final String simpleName = clazz.getSimpleName();
+        if (simpleName.length() != 0) {
+            if (withEnclosingClass) {
+                String prefix = "";
+                Class< ? > enclosingClass = clazz;
+                while ((enclosingClass = enclosingClass.getEnclosingClass()) != null) {
+                    prefix = prefix + enclosingClass.getSimpleName() + ".";
+                }
+                return prefix + simpleName;
+            }
+            return simpleName;
+        }
+        // Must be an anonymous or local class
+        final String name = clazz.getName();
+        int index = name.indexOf('$');
+        if (index == -1) {
+            return name;
+        }
+        index = name.lastIndexOf('.', index);
+        if (index == -1) {
+            return name;
+        }
+        return name.substring(index + 1);
+    }
+
+    public static final int K = 1024;
+    public static final int M = 1024 * 1024;
+
+    public static boolean isOdd(int n) {
+        return (n & 1) == 1;
+    }
+
+    public static boolean isEven(int n) {
+        return (n & 1) == 0;
+    }
+
+    /**
+     * Checks whether the specified integer is a power of two.
+     *
+     * @param val the value to check
+     * @return {@code true} if the value is a power of two; {@code false} otherwise
+     */
+    public static boolean isPowerOf2(int val) {
+        return val != 0 && (val & val - 1) == 0;
+    }
+
+    /**
+     * Checks whether the specified long is a power of two.
+     *
+     * @param val the value to check
+     * @return {@code true} if the value is a power of two; {@code false} otherwise
+     */
+    public static boolean isPowerOf2(long val) {
+        return val != 0 && (val & val - 1) == 0;
+    }
+
+    /**
+     * Computes the log (base 2) of the specified integer, rounding down. (E.g {@code log2(8) = 3}, {@code log2(21) = 4}
+     * )
+     *
+     * @param val the value
+     * @return the log base 2 of the value
+     */
+    public static int log2(int val) {
+        assert val > 0 && isPowerOf2(val);
+        return 31 - Integer.numberOfLeadingZeros(val);
+    }
+
+    /**
+     * Computes the log (base 2) of the specified long, rounding down. (E.g {@code log2(8) = 3}, {@code log2(21) = 4})
+     *
+     * @param val the value
+     * @return the log base 2 of the value
+     */
+    public static int log2(long val) {
+        assert val > 0 && isPowerOf2(val);
+        return 63 - Long.numberOfLeadingZeros(val);
+    }
+
+    public static int align(int size, int align) {
+        assert isPowerOf2(align);
+        return (size + align - 1) & ~(align - 1);
+    }
+
+    /**
+     * Gets a word with the nth bit set.
+     *
+     * @param n the nth bit to set
+     * @return an integer value with the nth bit set
+     */
+    public static int nthBit(int n) {
+        return n >= Integer.SIZE ? 0 : 1 << n;
+    }
+
+    /**
+     * Gets a word with the right-most n bits set.
+     *
+     * @param n the number of right most bits to set
+     * @return an integer value with the right-most n bits set
+     */
+    public static int rightNBits(int n) {
+        return nthBit(n) - 1;
+    }
+
+    /**
+     * Converts a given type to its Java programming language name. The following are examples of strings returned by
+     * this method:
+     *
+     * <pre>
+     *     qualified == true:
+     *         java.lang.Object
+     *         int
+     *         boolean[][]
+     *     qualified == false:
+     *         Object
+     *         int
+     *         boolean[][]
+     * </pre>
+     *
+     * @param riType the type to be converted to a Java name
+     * @param qualified specifies if the package prefix of the type should be included in the returned name
+     * @return the Java name corresponding to {@code riType}
+     */
+    public static String toJavaName(RiType riType, boolean qualified) {
+        CiKind kind = riType.kind(false);
+        if (kind.isPrimitive() || kind == CiKind.Void) {
+            return kind.javaName;
+        }
+        return internalNameToJava(riType.name(), qualified);
+    }
+
+    /**
+     * Converts a given type to its Java programming language name. The following are examples of strings returned by
+     * this method:
+     *
+     * <pre>
+     *      java.lang.Object
+     *      int
+     *      boolean[][]
+     * </pre>
+     *
+     * @param riType the type to be converted to a Java name
+     * @return the Java name corresponding to {@code riType}
+     */
+    public static String toJavaName(RiType riType) {
+        return (riType == null) ? null : internalNameToJava(riType.name(), true);
+    }
+
+    public static String internalNameToJava(String name, boolean qualified) {
+        switch (name.charAt(0)) {
+            case 'L': {
+                String result = name.substring(1, name.length() - 1).replace('/', '.');
+                if (!qualified) {
+                    final int lastDot = result.lastIndexOf('.');
+                    if (lastDot != -1) {
+                        result = result.substring(lastDot + 1);
+                    }
+                }
+                return result;
+
+            }
+            case '[':
+                return internalNameToJava(name.substring(1), qualified) + "[]";
+            default:
+                if (name.length() != 1) {
+                    throw new IllegalArgumentException("Illegal internal name: " + name);
+                }
+                return CiKind.fromPrimitiveOrVoidTypeChar(name.charAt(0)).javaName;
+        }
+    }
+
+    /**
+     * Gets a string for a given method formatted according to a given format specification. A format specification is
+     * composed of characters that are to be copied verbatim to the result and specifiers that denote an attribute of
+     * the method that is to be copied to the result. A specifier is a single character preceded by a '%' character. The
+     * accepted specifiers and the method attributes they denote are described below:
+     *
+     * <pre>
+     *     Specifier | Description                                          | Example(s)
+     *     ----------+------------------------------------------------------------------------------------------
+     *     'R'       | Qualified return type                                | "int" "java.lang.String"
+     *     'r'       | Unqualified return type                              | "int" "String"
+     *     'H'       | Qualified holder                                     | "java.util.Map.Entry"
+     *     'h'       | Unqualified holder                                   | "Entry"
+     *     'n'       | Method name                                          | "add"
+     *     'P'       | Qualified parameter types, separated by ', '         | "int, java.lang.String"
+     *     'p'       | Unqualified parameter types, separated by ', '       | "int, String"
+     *     'f'       | Indicator if method is unresolved, static or virtual | "unresolved" "static" "virtual"
+     *     '%'       | A '%' character                                      | "%"
+     * </pre>
+     *
+     * @param format a format specification
+     * @param method the method to be formatted
+     * @param kinds if {@code true} then the types in {@code method}'s signature are printed in the
+     *            {@linkplain CiKind#jniName JNI} form of their {@linkplain CiKind kind}
+     * @return the result of formatting this method according to {@code format}
+     * @throws IllegalFormatException if an illegal specifier is encountered in {@code format}
+     */
+    public static String format(String format, RiMethod method) throws IllegalFormatException {
+        final StringBuilder sb = new StringBuilder();
+        int index = 0;
+        RiSignature sig = null;
+        while (index < format.length()) {
+            final char ch = format.charAt(index++);
+            if (ch == '%') {
+                if (index >= format.length()) {
+                    throw new UnknownFormatConversionException("An unquoted '%' character cannot terminate a method format specification");
+                }
+                final char specifier = format.charAt(index++);
+                boolean qualified = false;
+                switch (specifier) {
+                    case 'R':
+                        qualified = true;
+                        // fall through
+                    case 'r': {
+                        if (sig == null) {
+                            sig = method.signature();
+                        }
+                        sb.append(toJavaName(sig.returnType(null), qualified));
+                        break;
+                    }
+                    case 'H':
+                        qualified = true;
+                        // fall through
+                    case 'h': {
+                        sb.append(toJavaName(method.holder(), qualified));
+                        break;
+                    }
+                    case 'n': {
+                        sb.append(method.name());
+                        break;
+                    }
+                    case 'P':
+                        qualified = true;
+                        // fall through
+                    case 'p': {
+                        if (sig == null) {
+                            sig = method.signature();
+                        }
+                        for (int i = 0; i < sig.argumentCount(false); i++) {
+                            if (i != 0) {
+                                sb.append(", ");
+                            }
+                            sb.append(toJavaName(sig.argumentTypeAt(i, null), qualified));
+                        }
+                        break;
+                    }
+                    case 'f': {
+                        sb.append(!(method instanceof RiResolvedMethod) ? "unresolved" : isStatic(((RiResolvedMethod) method).accessFlags()) ? "static" : "virtual");
+                        break;
+                    }
+                    case '%': {
+                        sb.append('%');
+                        break;
+                    }
+                    default: {
+                        throw new UnknownFormatConversionException(String.valueOf(specifier));
+                    }
+                }
+            } else {
+                sb.append(ch);
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Gets a string for a given field formatted according to a given format specification. A format specification is
+     * composed of characters that are to be copied verbatim to the result and specifiers that denote an attribute of
+     * the field that is to be copied to the result. A specifier is a single character preceded by a '%' character. The
+     * accepted specifiers and the field attributes they denote are described below:
+     *
+     * <pre>
+     *     Specifier | Description                                          | Example(s)
+     *     ----------+------------------------------------------------------------------------------------------
+     *     'T'       | Qualified type                                       | "int" "java.lang.String"
+     *     't'       | Unqualified type                                     | "int" "String"
+     *     'H'       | Qualified holder                                     | "java.util.Map.Entry"
+     *     'h'       | Unqualified holder                                   | "Entry"
+     *     'n'       | Field name                                           | "age"
+     *     'f'       | Indicator if field is unresolved, static or instance | "unresolved" "static" "instance"
+     *     '%'       | A '%' character                                      | "%"
+     * </pre>
+     *
+     * @param format a format specification
+     * @param field the field to be formatted
+     * @param kinds if {@code true} then {@code field}'s type is printed in the {@linkplain CiKind#jniName JNI} form of
+     *            its {@linkplain CiKind kind}
+     * @return the result of formatting this field according to {@code format}
+     * @throws IllegalFormatException if an illegal specifier is encountered in {@code format}
+     */
+    public static String format(String format, RiField field) throws IllegalFormatException {
+        final StringBuilder sb = new StringBuilder();
+        int index = 0;
+        RiType type = field.type();
+        while (index < format.length()) {
+            final char ch = format.charAt(index++);
+            if (ch == '%') {
+                if (index >= format.length()) {
+                    throw new UnknownFormatConversionException("An unquoted '%' character cannot terminate a field format specification");
+                }
+                final char specifier = format.charAt(index++);
+                boolean qualified = false;
+                switch (specifier) {
+                    case 'T':
+                        qualified = true;
+                        // fall through
+                    case 't': {
+                        sb.append(toJavaName(type, qualified));
+                        break;
+                    }
+                    case 'H':
+                        qualified = true;
+                        // fall through
+                    case 'h': {
+                        sb.append(toJavaName(field.holder(), qualified));
+                        break;
+                    }
+                    case 'n': {
+                        sb.append(field.name());
+                        break;
+                    }
+                    case 'f': {
+                        sb.append(!(field instanceof RiResolvedField) ? "unresolved" : isStatic(((RiResolvedField) field).accessFlags()) ? "static" : "instance");
+                        break;
+                    }
+                    case '%': {
+                        sb.append('%');
+                        break;
+                    }
+                    default: {
+                        throw new UnknownFormatConversionException(String.valueOf(specifier));
+                    }
+                }
+            } else {
+                sb.append(ch);
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Gets a stack trace element for a given method and bytecode index.
+     */
+    public static StackTraceElement toStackTraceElement(RiMethod method, @SuppressWarnings("unused") int bci) {
+        // TODO(tw): Look if we can use bci to get the line number.
+        return new StackTraceElement(CiUtil.toJavaName(method.holder()), method.name(), null, -1);
+    }
+
+    /**
+     * Converts a Java source-language class name into the internal form.
+     *
+     * @param className the class name
+     * @return the internal name form of the class name
+     */
+    public static String toInternalName(String className) {
+        return "L" + className.replace('.', '/') + ";";
+    }
+
+    /**
+     * Creates a set that uses reference-equality instead of {@link Object#equals(Object)} when comparing values.
+     *
+     * @param <T> the type of elements in the set
+     * @return a set based on reference-equality
+     */
+    public static <T> Set<T> newIdentityHashSet() {
+        return Collections.newSetFromMap(new IdentityHashMap<T, Boolean>());
+    }
+
+    /**
+     * Prepends the String {@code indentation} to every line in String {@code lines}, including a possibly non-empty
+     * line following the final newline.
+     */
+    public static String indent(String lines, String indentation) {
+        if (lines.length() == 0) {
+            return lines;
+        }
+        final String newLine = "\n";
+        if (lines.endsWith(newLine)) {
+            return indentation + (lines.substring(0, lines.length() - 1)).replace(newLine, newLine + indentation) + newLine;
+        }
+        return indentation + lines.replace(newLine, newLine + indentation);
+    }
+
+    /**
+     * Formats the values in a frame as a tabulated string.
+     *
+     * @param frame
+     * @return the values in {@code frame} as a tabulated string
+     */
+    public static String tabulateValues(CiFrame frame) {
+        int cols = Math.max(frame.numLocals, Math.max(frame.numStack, frame.numLocks));
+        assert cols > 0;
+        ArrayList<Object> cells = new ArrayList<>();
+        cells.add("");
+        for (int i = 0; i < cols; i++) {
+            cells.add(i);
+        }
+        cols++;
+        if (frame.numLocals != 0) {
+            cells.add("locals:");
+            cells.addAll(Arrays.asList(frame.values).subList(0, frame.numLocals));
+            cells.addAll(Collections.nCopies(cols - frame.numLocals - 1, ""));
+        }
+        if (frame.numStack != 0) {
+            cells.add("stack:");
+            cells.addAll(Arrays.asList(frame.values).subList(frame.numLocals, frame.numLocals + frame.numStack));
+            cells.addAll(Collections.nCopies(cols - frame.numStack - 1, ""));
+        }
+        if (frame.numLocks != 0) {
+            cells.add("locks:");
+            cells.addAll(Arrays.asList(frame.values).subList(frame.numLocals + frame.numStack, frame.values.length));
+            cells.addAll(Collections.nCopies(cols - frame.numLocks - 1, ""));
+        }
+        Object[] cellArray = cells.toArray();
+        for (int i = 0; i < cellArray.length; i++) {
+            if ((i % cols) != 0) {
+                cellArray[i] = "|" + cellArray[i];
+            }
+        }
+        return CiUtil.tabulate(cellArray, cols, 1, 1);
+    }
+
+    /**
+     * Formats a given table as a string. The value of each cell is produced by {@link String#valueOf(Object)}.
+     *
+     * @param cells the cells of the table in row-major order
+     * @param cols the number of columns per row
+     * @param lpad the number of space padding inserted before each formatted cell value
+     * @param rpad the number of space padding inserted after each formatted cell value
+     * @return a string with one line per row and each column left-aligned
+     */
+    public static String tabulate(Object[] cells, int cols, int lpad, int rpad) {
+        int rows = (cells.length + (cols - 1)) / cols;
+        int[] colWidths = new int[cols];
+        for (int col = 0; col < cols; col++) {
+            for (int row = 0; row < rows; row++) {
+                int index = col + (row * cols);
+                if (index < cells.length) {
+                    Object cell = cells[index];
+                    colWidths[col] = Math.max(colWidths[col], String.valueOf(cell).length());
+                }
+            }
+        }
+        StringBuilder sb = new StringBuilder();
+        String nl = NEW_LINE;
+        for (int row = 0; row < rows; row++) {
+            for (int col = 0; col < cols; col++) {
+                int index = col + (row * cols);
+                if (index < cells.length) {
+                    for (int i = 0; i < lpad; i++) {
+                        sb.append(' ');
+                    }
+                    Object cell = cells[index];
+                    String s = String.valueOf(cell);
+                    int w = s.length();
+                    sb.append(s);
+                    while (w < colWidths[col]) {
+                        sb.append(' ');
+                        w++;
+                    }
+                    for (int i = 0; i < rpad; i++) {
+                        sb.append(' ');
+                    }
+                }
+            }
+            sb.append(nl);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Convenient shortcut for calling {@link #appendLocation(StringBuilder, RiMethod, int)} without having to supply a
+     * a {@link StringBuilder} instance and convert the result to a string.
+     */
+    public static String toLocation(RiResolvedMethod method, int bci) {
+        return appendLocation(new StringBuilder(), method, bci).toString();
+    }
+
+    /**
+     * Appends a string representation of a location specified by a given method and bci to a given
+     * {@link StringBuilder}. If a stack trace element with a non-null file name and non-negative line number is
+     * {@linkplain RiMethod#toStackTraceElement(int) available} for the given method, then the string returned is the
+     * {@link StackTraceElement#toString()} value of the stack trace element, suffixed by the bci location. For example:
+     *
+     * <pre>
+     *     java.lang.String.valueOf(String.java:2930) [bci: 12]
+     * </pre>
+     *
+     * Otherwise, the string returned is the value of {@code CiUtil.format("%H.%n(%p)"}, suffixed by the bci location.
+     * For example:
+     *
+     * <pre>
+     *     java.lang.String.valueOf(int) [bci: 12]
+     * </pre>
+     *
+     * @param sb
+     * @param method
+     * @param bci
+     * @return
+     */
+    public static StringBuilder appendLocation(StringBuilder sb, RiResolvedMethod method, int bci) {
+        if (method != null) {
+            StackTraceElement ste = method.toStackTraceElement(bci);
+            if (ste.getFileName() != null && ste.getLineNumber() > 0) {
+                sb.append(ste);
+            } else {
+                sb.append(CiUtil.format("%H.%n(%p)", method));
+            }
+        } else {
+            sb.append("Null method");
+        }
+        return sb.append(" [bci: ").append(bci).append(']');
+    }
+
+    /**
+     * Appends a formatted code position to a {@link StringBuilder}.
+     *
+     * @param sb the {@link StringBuilder} to append to
+     * @param pos the code position to format and append to {@code sb}
+     * @return the value of {@code sb}
+     */
+    public static StringBuilder append(StringBuilder sb, CiCodePos pos) {
+        appendLocation(sb.append("at "), pos.method, pos.bci);
+        if (pos.caller != null) {
+            sb.append(NEW_LINE);
+            append(sb, pos.caller);
+        }
+        return sb;
+    }
+
+    /**
+     * Appends a formatted frame to a {@link StringBuilder}.
+     *
+     * @param sb the {@link StringBuilder} to append to
+     * @param frame the frame to format and append to {@code sb}
+     * @return the value of {@code sb}
+     */
+    public static StringBuilder append(StringBuilder sb, CiFrame frame) {
+        appendLocation(sb.append("at "), frame.method, frame.bci);
+        if (frame.values != null && frame.values.length > 0) {
+            sb.append(NEW_LINE);
+            String table = tabulateValues(frame);
+            String[] rows = table.split(NEW_LINE);
+            for (int i = 0; i < rows.length; i++) {
+                String row = rows[i];
+                if (!row.trim().isEmpty()) {
+                    sb.append("  ").append(row);
+                    if (i != rows.length - 1) {
+                        sb.append(NEW_LINE);
+                    }
+                }
+            }
+        }
+        if (frame.caller() != null) {
+            sb.append(NEW_LINE);
+            append(sb, frame.caller());
+        } else if (frame.caller != null) {
+            sb.append(NEW_LINE);
+            append(sb, frame.caller);
+        }
+        return sb;
+    }
+
+    /**
+     * Formats a location present in a register or frame reference map.
+     */
+    public static class RefMapFormatter {
+
+        /**
+         * The size of a stack slot.
+         */
+        public final int slotSize;
+
+        /**
+         * The register used as the frame pointer.
+         */
+        public final CiRegister fp;
+
+        public final CiArchitecture arch;
+
+        /**
+         * The offset (in bytes) from the slot pointed to by {@link #fp} to the slot corresponding to bit 0 in the frame
+         * reference map.
+         */
+        public final int refMapToFPOffset;
+
+        public RefMapFormatter(CiArchitecture arch, int slotSize, CiRegister fp, int refMapToFPOffset) {
+            this.arch = arch;
+            this.slotSize = slotSize;
+            this.fp = fp;
+            this.refMapToFPOffset = refMapToFPOffset;
+        }
+
+        public String formatStackSlot(int frameRefMapIndex) {
+            int refMapOffset = frameRefMapIndex * slotSize;
+            int fpOffset = refMapOffset + refMapToFPOffset;
+            if (fpOffset >= 0) {
+                return fp + "+" + fpOffset;
+            }
+            return fp.name + fpOffset;
+        }
+
+        public String formatRegister(int regRefMapIndex) {
+            return arch.registers[regRefMapIndex].toString();
+        }
+    }
+
+    /**
+     * Appends a formatted debug info to a {@link StringBuilder}.
+     *
+     * @param sb the {@link StringBuilder} to append to
+     * @param info the debug info to format and append to {@code sb}
+     * @return the value of {@code sb}
+     */
+    public static StringBuilder append(StringBuilder sb, CiDebugInfo info, RefMapFormatter formatter) {
+        String nl = NEW_LINE;
+        if (info.hasRegisterRefMap()) {
+            sb.append("  reg-ref-map:");
+            CiBitMap bm = info.registerRefMap;
+            if (formatter != null) {
+                for (int reg = bm.nextSetBit(0); reg >= 0; reg = bm.nextSetBit(reg + 1)) {
+                    sb.append(" " + formatter.formatRegister(reg));
+                }
+            }
+            sb.append(' ').append(bm).append(nl);
+        }
+        if (info.hasStackRefMap()) {
+            sb.append("frame-ref-map:");
+            CiBitMap bm = info.frameRefMap;
+            if (formatter != null) {
+                for (int i = bm.nextSetBit(0); i >= 0; i = bm.nextSetBit(i + 1)) {
+                    sb.append(" " + formatter.formatStackSlot(i));
+                }
+            }
+            sb.append(' ').append(bm).append(nl);
+        }
+        CiFrame frame = info.frame();
+        if (frame != null) {
+            append(sb, frame);
+        } else if (info.codePos != null) {
+            append(sb, info.codePos);
+        }
+        return sb;
+    }
+
+    public static CiKind[] signatureToKinds(RiResolvedMethod method) {
+        CiKind receiver = isStatic(method.accessFlags()) ? null : method.holder().kind(true);
+        return signatureToKinds(method.signature(), receiver);
+    }
+
+    public static CiKind[] signatureToKinds(RiSignature signature, CiKind receiverKind) {
+        int args = signature.argumentCount(false);
+        CiKind[] result;
+        int i = 0;
+        if (receiverKind != null) {
+            result = new CiKind[args + 1];
+            result[0] = receiverKind;
+            i = 1;
+        } else {
+            result = new CiKind[args];
+        }
+        for (int j = 0; j < args; j++) {
+            result[i + j] = signature.argumentKindAt(j, true);
+        }
+        return result;
+    }
+
+    public static Class< ? >[] signatureToTypes(RiSignature signature, RiResolvedType accessingClass) {
+        int count = signature.argumentCount(false);
+        Class< ? >[] result = new Class< ? >[count];
+        for (int i = 0; i < result.length; ++i) {
+            result[i] = signature.argumentTypeAt(i, accessingClass).resolve(accessingClass).toJava();
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiValue.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.cri.ci;
+
+import java.io.*;
+
+/**
+ * Abstract base class for values manipulated by the compiler. All values have a {@linkplain CiKind kind} and are immutable.
+ */
+public abstract class CiValue implements Serializable {
+    private static final long serialVersionUID = -6909397188697766469L;
+
+    @SuppressWarnings("serial")
+    public static CiValue IllegalValue = new CiValue(CiKind.Illegal) {
+        @Override
+        public String toString() {
+            return "-";
+        }
+    };
+
+    /**
+     * The kind of this value.
+     */
+    public final CiKind kind;
+
+    /**
+     * Initializes a new value of the specified kind.
+     * @param kind the kind
+     */
+    protected CiValue(CiKind kind) {
+        this.kind = kind;
+    }
+
+    /**
+     * String representation of the kind, which should be the end of all {@link #toString()} implementation of subclasses.
+     */
+    protected final String kindSuffix() {
+        return "|" + kind.typeChar;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiValueUtil.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2012, 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.max.cri.ci;
+
+public class CiValueUtil {
+    public static boolean isIllegal(CiValue value) {
+        assert value != null;
+        return value == CiValue.IllegalValue;
+    }
+
+    public static boolean isLegal(CiValue value) {
+        return !isIllegal(value);
+    }
+
+    public static boolean isVirtualObject(CiValue value) {
+        assert value != null;
+        return value instanceof CiVirtualObject;
+    }
+
+    public static CiVirtualObject asVirtualObject(CiValue value) {
+        assert value != null;
+        return (CiVirtualObject) value;
+    }
+
+    public static boolean isConstant(CiValue value) {
+        assert value != null;
+        return value instanceof CiConstant;
+    }
+
+    public static CiConstant asConstant(CiValue value) {
+        assert value != null;
+        return (CiConstant) value;
+    }
+
+
+    public static boolean isStackSlot(CiValue value) {
+        assert value != null;
+        return value instanceof CiStackSlot;
+    }
+
+    public static CiStackSlot asStackSlot(CiValue value) {
+        assert value != null;
+        return (CiStackSlot) value;
+    }
+
+    public static boolean isAddress(CiValue value) {
+        assert value != null;
+        return value instanceof CiAddress;
+    }
+
+    public static CiAddress asAddress(CiValue value) {
+        assert value != null;
+        return (CiAddress) value;
+    }
+
+
+    public static boolean isRegister(CiValue value) {
+        assert value != null;
+        return value instanceof CiRegisterValue;
+    }
+
+    public static CiRegister asRegister(CiValue value) {
+        assert value != null;
+        return ((CiRegisterValue) value).reg;
+    }
+
+    public static CiRegister asIntReg(CiValue value) {
+        assert value.kind == CiKind.Int || value.kind == CiKind.Jsr;
+        return asRegister(value);
+    }
+
+    public static CiRegister asLongReg(CiValue value) {
+        assert value.kind == CiKind.Long : value.kind;
+        return asRegister(value);
+    }
+
+    public static CiRegister asObjectReg(CiValue value) {
+        assert value.kind == CiKind.Object;
+        return asRegister(value);
+    }
+
+    public static CiRegister asFloatReg(CiValue value) {
+        assert value.kind == CiKind.Float;
+        return asRegister(value);
+    }
+
+    public static CiRegister asDoubleReg(CiValue value) {
+        assert value.kind == CiKind.Double;
+        return asRegister(value);
+    }
+
+
+    public static boolean sameRegister(CiValue v1, CiValue v2) {
+        return isRegister(v1) && isRegister(v2) && asRegister(v1) == asRegister(v2);
+    }
+
+    public static boolean sameRegister(CiValue v1, CiValue v2, CiValue v3) {
+        return sameRegister(v1, v2) && sameRegister(v1, v3);
+    }
+
+    public static boolean differentRegisters(CiValue v1, CiValue v2) {
+        return !isRegister(v1) || !isRegister(v2) || asRegister(v1) != asRegister(v2);
+    }
+
+    public static boolean differentRegisters(CiValue v1, CiValue v2, CiValue v3) {
+        return differentRegisters(v1, v2) && differentRegisters(v1, v3) && differentRegisters(v2, v3);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiVirtualObject.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2010, 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.max.cri.ci;
+
+import com.oracle.max.cri.ri.*;
+
+/**
+ * An instance of this class represents an object whose allocation was removed by escape analysis. The information stored in the {@link CiVirtualObject} is used during
+ * deoptimization to recreate the object.
+ */
+public final class CiVirtualObject extends CiValue {
+    private static final long serialVersionUID = -2907197776426346021L;
+
+    private final RiType type;
+    private CiValue[] values;
+    private final int id;
+
+    /**
+     * Creates a new CiVirtualObject for the given type, with the given fields. If the type is an instance class then the values array needs to have one entry for each field, ordered in
+     * like the fields returned by {@link RiResolvedType#declaredFields()}. If the type is an array then the length of the values array determines the reallocated array length.
+     * @param type the type of the object whose allocation was removed during compilation. This can be either an instance of an array type.
+     * @param values an array containing all the values to be stored into the object when it is recreated.
+     * @param id a unique id that identifies the object within the debug information for one position in the compiled code.
+     * @return a new CiVirtualObject instance.
+     */
+    public static CiVirtualObject get(RiType type, CiValue[] values, int id) {
+        return new CiVirtualObject(type, values, id);
+    }
+
+    private CiVirtualObject(RiType type, CiValue[] values, int id) {
+        super(CiKind.Object);
+        this.type = type;
+        this.values = values;
+        this.id = id;
+    }
+
+    @Override
+    public String toString() {
+        return "vobject:" + id;
+    }
+
+    /**
+     * @return the type of the object whose allocation was removed during compilation. This can be either an instance of an array type.
+     */
+    public RiType type() {
+        return type;
+    }
+
+    /**
+     * @return an array containing all the values to be stored into the object when it is recreated.
+     */
+    public CiValue[] values() {
+        return values;
+    }
+
+    /**
+     * @return the unique id that identifies the object within the debug information for one position in the compiled code.
+     */
+    public int id() {
+        return id;
+    }
+
+    /**
+     * Overwrites the current set of values with a new one.
+     * @param values an array containing all the values to be stored into the object when it is recreated.
+     */
+    public void setValues(CiValue[] values) {
+        this.values = values;
+    }
+
+    @Override
+    public int hashCode() {
+        return kind.ordinal() + type.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (o instanceof CiVirtualObject) {
+            CiVirtualObject l = (CiVirtualObject) o;
+            if (l.type != type || l.values.length != values.length) {
+                return false;
+            }
+            for (int i = 0; i < values.length; i++) {
+                if (values[i] != l.values[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * This is a helper class used to create virtual objects for a number of different JDK classes.
+     */
+    public static class CiVirtualObjectFactory {
+        private int nextId = 0;
+        private final RiRuntime runtime;
+
+        public CiVirtualObjectFactory(RiRuntime runtime) {
+            this.runtime = runtime;
+        }
+
+        public CiVirtualObject constantProxy(CiKind kind, CiValue objectValue, CiValue primitiveValue) {
+            CiConstant cKind = CiConstant.forObject(kind);
+            // TODO: here the ordering is hard coded... we should query RiType.fields() and act accordingly
+            return new CiVirtualObject(runtime.getType(CiConstant.class), new CiValue[] {cKind, primitiveValue, CiValue.IllegalValue, objectValue}, nextId++);
+        }
+
+        public CiValue proxy(CiValue ciValue) {
+            switch (ciValue.kind) {
+                case Boolean:
+                    return new CiVirtualObject(runtime.getType(Boolean.class), new CiValue[] {ciValue}, nextId++);
+                case Byte:
+                    return new CiVirtualObject(runtime.getType(Byte.class), new CiValue[] {ciValue}, nextId++);
+                case Char:
+                    return new CiVirtualObject(runtime.getType(Character.class), new CiValue[] {ciValue}, nextId++);
+                case Double:
+                    return new CiVirtualObject(runtime.getType(Double.class), new CiValue[] {ciValue, CiValue.IllegalValue}, nextId++);
+                case Float:
+                    return new CiVirtualObject(runtime.getType(Float.class), new CiValue[] {ciValue}, nextId++);
+                case Int:
+                    return new CiVirtualObject(runtime.getType(Integer.class), new CiValue[] {ciValue}, nextId++);
+                case Long:
+                    return new CiVirtualObject(runtime.getType(Long.class), new CiValue[] {ciValue, CiValue.IllegalValue}, nextId++);
+                case Object:
+                    return ciValue;
+                case Short:
+                    return new CiVirtualObject(runtime.getType(Short.class), new CiValue[] {ciValue}, nextId++);
+                default:
+                    assert false : ciValue.kind;
+                    return null;
+            }
+        }
+
+        public CiVirtualObject arrayProxy(RiType arrayType, CiValue[] values) {
+            return new CiVirtualObject(arrayType, values, nextId++);
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/package-info.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+/**
+ * The compiler-provided part of the bi-directional interface between the compiler and the runtime system of a virtual machine for the instruction set defined in
+ * {@link com.oracle.max.graal.compiler.graphbuilder.Bytecodes}.
+ *
+ * The target hardware architecture is represented by {@link com.oracle.max.cri.ci.CiArchitecture} and the specific target machine
+ * environment for a compiler instance is represented by {@link com.oracle.max.cri.ci.CiTarget}.
+ * <p>
+ * A {@code CiResult} encapsulates
+ * {@linkplain com.oracle.max.cri.ci.CiStatistics compilation statistics}, possible {@linkplain com.oracle.max.cri.ci.CiBailout error state}
+ * and the {@linkplain com.oracle.max.cri.ci.CiTargetMethod compiled code and metadata}.
+ * {@link com.oracle.max.cri.ci.CiCodePos} and {@link com.oracle.max.cri.ci.CiDebugInfo} provide detailed information to the
+ * runtime to support debugging and deoptimization of the compiled code.
+ * <p>
+ * The compiler manipulates {@link com.oracle.max.cri.ci.CiValue} instances that have a {@link com.oracle.max.cri.ci.CiKind}, and are
+ * immutable. A concrete {@link com.oracle.max.cri.ci.CiValue value} is one of the following subclasses:
+ * <ul>
+ * <li>{@link com.oracle.max.cri.ci.CiConstant}: a constant value.
+ * <li>{@link com.oracle.max.cri.ci.CiRegisterValue}: a value stored in a {@linkplain com.oracle.max.cri.ci.CiRegister target machine register}.
+ * <li>{@link com.oracle.max.cri.ci.CiStackSlot}: a spill slot or an outgoing stack-based argument in a method's frame.
+ * <li>{@link com.oracle.max.cri.ci.CiAddress}: an address in target machine memory.
+ * <li>{@link com.oracle.max.graal.compiler.lir.CiVariable}: a value (cf. virtual register) that is yet to be bound to a target machine location (physical register or memory address).
+ *</ul>
+ */
+package com.oracle.max.cri.ci;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/package-info.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+/**
+ * A virtual machine compiler-runtime interface (CRI).
+ * <p>
+ * Specifically, this package defines an interface between the compiler and the runtime system of a virtual machine for
+ * the instruction set defined in {@link com.oracle.max.graal.compiler.graphbuilder.Bytecodes}. The interface has three components:
+ * <ol>
+ * <li>the {@link com.oracle.max.cri.ci compiler-provided interface} that must be used by the runtime.
+ * <li>the {@link com.oracle.max.cri.ri runtime-provided interface} that must be used by the compiler.
+ * <li>the {@link com.oracle.max.cri.xir XIR interface} for translating object operations.
+ * </ol>
+ *
+ * The interface is independent of any particular compiler or runtime implementation.
+ * <p>
+ * For more details see <a href="http://wikis.sun.com/download/attachments/173802383/vee2010.pdf">Improving Compiler-Runtime Separation with XIR</a>.
+ */
+package com.oracle.max.cri;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiCompiledMethod.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ * 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.max.cri.ri;
+
+/**
+ * Represents a compiled instance of a method. It may have been invalidated or removed in the meantime.
+ */
+public interface RiCompiledMethod {
+
+    /**
+     * Returns the method to which the compiled code belongs.
+     * @return the method to which the compiled code belongs.
+     */
+    RiResolvedMethod method();
+
+    /**
+     * @return true if the code represented by this object is still valid, false otherwise (may happen due to deopt, etc.)
+     */
+    boolean isValid();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiConstantPool.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ri;
+
+/**
+ * Represents the runtime representation of the constant pool that is
+ * used by the compiler when parsing bytecode. The {@code lookupXXX} methods look up a constant
+ * pool entry without performing resolution, and are used during compilation.
+ */
+public interface RiConstantPool {
+
+    /**
+     * Makes sure that the type referenced by the specified constant pool entry is loaded and
+     * initialized. This can be used to compile time resolve a type. It works for field, method,
+     * or type constant pool entries.
+     * @param cpi the index of the constant pool entry that references the type
+     * @param opcode the opcode of the instruction that references the type
+     */
+    void loadReferencedType(int cpi, int opcode);
+
+    /**
+     * Looks up a reference to a field. If {@code opcode} is non-negative, then resolution checks
+     * specific to the JVM instruction it denotes are performed if the field is already resolved.
+     * Should any of these checks fail, an {@linkplain RiField#isResolved() unresolved}
+     * field reference is returned.
+     *
+     * @param cpi the constant pool index
+     * @param opcode the opcode of the instruction for which the lookup is being performed or {@code -1}
+     * @return a reference to the field at {@code cpi} in this pool
+     * @throws ClassFormatError if the entry at {@code cpi} is not a field
+     */
+    RiField lookupField(int cpi, int opcode);
+
+    /**
+     * Looks up a reference to a method. If {@code opcode} is non-negative, then resolution checks
+     * specific to the JVM instruction it denotes are performed if the method is already resolved.
+     * Should any of these checks fail, an {@linkplain RiMethod#isResolved() unresolved}
+     * method reference is returned.
+     *
+     * @param cpi the constant pool index
+     * @param opcode the opcode of the instruction for which the lookup is being performed or {@code -1}
+     * @return a reference to the method at {@code cpi} in this pool
+     * @throws ClassFormatError if the entry at {@code cpi} is not a method
+     */
+    RiMethod lookupMethod(int cpi, int opcode);
+
+    /**
+     * Looks up a reference to a type. If {@code opcode} is non-negative, then resolution checks
+     * specific to the JVM instruction it denotes are performed if the type is already resolved.
+     * Should any of these checks fail, an {@linkplain RiType#isResolved() unresolved}
+     * type reference is returned.
+     *
+     * @param cpi the constant pool index
+     * @param opcode the opcode of the instruction for which the lookup is being performed or {@code -1}
+     * @return a reference to the compiler interface type
+     */
+    RiType lookupType(int cpi, int opcode);
+
+    /**
+     * Looks up a method signature.
+     *
+     * @param cpi the constant pool index
+     * @return the method signature at index {@code cpi} in this constant pool
+     */
+    RiSignature lookupSignature(int cpi);
+
+    /**
+     * Looks up a constant at the specified index.
+     * @param cpi the constant pool index
+     * @return the {@code CiConstant} instance representing the constant
+     */
+    Object lookupConstant(int cpi);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiExceptionHandler.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ri;
+
+/**
+ * Represents an exception handler within the bytecode.
+ */
+public interface RiExceptionHandler {
+
+    /**
+     * Gets the start bytecode index of the protected range of this handler.
+     * @return the start bytecode index
+     */
+    int startBCI();
+
+    /**
+     * Gets the end bytecode index of the protected range of this handler.
+     * @return the end bytecode index
+     */
+    int endBCI();
+
+    /**
+     * Gets the bytecode index of the handler block of this handler.
+     * @return the handler block bytecode index
+     */
+    int handlerBCI();
+
+    /**
+     * Gets the index into the constant pool representing the type of exception
+     * caught by this handler.
+     * @return the constant pool index of the catch type
+     */
+    int catchTypeCPI();
+
+    /**
+     * Checks whether this handler catches all exceptions.
+     * @return {@code true} if this handler catches all exceptions
+     */
+    boolean isCatchAll();
+
+    /**
+     * The type of exception caught by this exception handler.
+     *
+     * @return the exception type
+     */
+    RiType catchType();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiExceptionSeen.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,37 @@
+/*
+ * 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.max.cri.ri;
+
+
+/**
+ * Represents the three possibilities that an exception was seen at a specific BCI.
+ */
+public enum RiExceptionSeen {
+    TRUE,
+    FALSE,
+    NOT_SUPPORTED;
+
+    public static RiExceptionSeen get(boolean value) {
+        return value ? TRUE : FALSE;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiField.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ri;
+
+
+import com.oracle.max.cri.ci.*;
+
+/**
+ * Represents a reference to a field, including both resolved and unresolved fields. Fields, like methods and types, are
+ * resolved through {@link RiConstantPool constant pools}, and their actual implementation is provided by the
+ * {@link RiRuntime runtime} to the compiler.
+ */
+public interface RiField {
+    /**
+     * Gets the name of this field as a string.
+     * @return the name of this field
+     */
+    String name();
+
+    /**
+     * Gets the type of this field as a compiler-runtime interface type.
+     * @return the type of this field
+     */
+    RiType type();
+
+    /**
+     * Gets the kind of this field.
+     * @param architecture When true, the architecture-specific kind used for emitting machine code is returned.
+     *        When false, the kind according to the Java specification is returned.
+     * @return the kind
+     */
+    CiKind kind(boolean architecture);
+
+    /**
+     * Gets the holder of this field as a compiler-runtime interface type.
+     * @return the holder of this field
+     */
+    RiType holder();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiMethod.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ri;
+
+/**
+ * Represents resolved and unresolved methods. Methods, like fields and types, are resolved through
+ * {@link RiConstantPool constant pools}, and their actual implementation is provided by the {@link RiRuntime runtime}
+ * to the compiler.
+ */
+public interface RiMethod {
+
+    /**
+     * Gets the name of the method as a string.
+     * @return the name of the method
+     */
+    String name();
+
+    /**
+     * Gets the type in which this method is declared.
+     * @return the type in which this method is declared
+     */
+    RiType holder();
+
+    /**
+     * Gets the signature of the method.
+     * @return the signature of the method
+     */
+    RiSignature signature();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiProfilingInfo.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * 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.max.cri.ri;
+
+
+/**
+ * Provides access to the profiling information of one specific method.
+ * Every accessor method returns the information that is available at the time of invocation.
+ * If a method is invoked multiple times, it may return significantly different results for every invocation
+ * as the profiling information may be changed by other Java threads at any time.
+ */
+public interface RiProfilingInfo {
+    /**
+     * Returns an estimate of how often the branch at the given byte code was taken.
+     * @return The estimated probability, with 0.0 meaning never and 1.0 meaning always, or -1 if this information is not available.
+     */
+    double getBranchTakenProbability(int bci);
+
+    /**
+     * Returns an estimate of how often the switch cases are taken at the given BCI.
+     * The default case is stored as the last entry.
+     * @return A double value that contains the estimated probabilities, with 0.0 meaning never and 1.0 meaning always,
+     * or -1 if this information is not available.
+     */
+    double[] getSwitchProbabilities(int bci);
+
+    /**
+     * Returns the TypeProfile for the given BCI.
+     * @return Returns an RiTypeProfile object, or null if not available.
+     */
+    RiTypeProfile getTypeProfile(int bci);
+
+    /**
+     * Returns information if the given BCI did ever throw an exception.
+     * @return @link{RiExceptionSeen.TRUE} if the instruction has thrown an exception at least once,
+     * @link{RiExceptionSeen.FALSE} if it never threw an exception, and @link{RiExceptionSeen.UNKNOWN}
+     * if this information was not recorded.
+     */
+    RiExceptionSeen getExceptionSeen(int bci);
+
+    /**
+     * Returns an estimate how often the current BCI was executed. Avoid comparing execution counts to each other,
+     * as the returned value highly depends on the time of invocation.
+     * @return the estimated execution count or -1 if not available.
+     */
+    int getExecutionCount(int bci);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRegisterAttributes.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2010, 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.max.cri.ri;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+
+/**
+ * A collection of register attributes. The specific attribute values for a register may be
+ * local to a compilation context. For example, a {@link RiRegisterConfig} in use during
+ * a compilation will determine which registers are callee saved.
+ */
+public class RiRegisterAttributes {
+
+    /**
+     * Denotes a register whose value preservation (if required) across a call is the responsibility of the caller.
+     */
+    public final boolean isCallerSave;
+
+    /**
+     * Denotes a register whose value preservation (if required) across a call is the responsibility of the callee.
+     */
+    public final boolean isCalleeSave;
+
+    /**
+     * Denotes a register that is available for use by a register allocator.
+     */
+    public final boolean isAllocatable;
+
+    /**
+     * Denotes a register guaranteed to be non-zero if read in compiled Java code.
+     * For example, a register dedicated to holding the current thread.
+     */
+    public boolean isNonZero;
+
+    public RiRegisterAttributes(boolean isCallerSave, boolean isCalleeSave, boolean isAllocatable) {
+        this.isCallerSave = isCallerSave;
+        this.isCalleeSave = isCalleeSave;
+        this.isAllocatable = isAllocatable;
+    }
+
+    public static final RiRegisterAttributes NONE = new RiRegisterAttributes(false, false, false);
+
+    /**
+     * Creates a map from register {@linkplain CiRegister#number numbers} to register
+     * {@linkplain RiRegisterAttributes attributes} for a given register configuration and set of
+     * registers.
+     *
+     * @param registerConfig a register configuration
+     * @param registers a set of registers
+     * @return an array whose length is the max register number in {@code registers} plus 1. An element at index i holds
+     *         the attributes of the register whose number is i.
+     */
+    public static RiRegisterAttributes[] createMap(RiRegisterConfig registerConfig, CiRegister[] registers) {
+        RiRegisterAttributes[] map = new RiRegisterAttributes[registers.length];
+        for (CiRegister reg : registers) {
+            if (reg != null) {
+                CiCalleeSaveLayout csl = registerConfig.getCalleeSaveLayout();
+                RiRegisterAttributes attr = new RiRegisterAttributes(
+                                Arrays.asList(registerConfig.getCallerSaveRegisters()).contains(reg),
+                                csl == null ? false : Arrays.asList(csl.registers).contains(reg),
+                                Arrays.asList(registerConfig.getAllocatableRegisters()).contains(reg));
+                if (map.length <= reg.number) {
+                    map = Arrays.copyOf(map, reg.number + 1);
+                }
+                map[reg.number] = attr;
+            }
+        }
+        for (int i = 0; i < map.length; i++) {
+            if (map[i] == null) {
+                map[i] = NONE;
+            }
+        }
+        return map;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRegisterConfig.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ri;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiCallingConvention.*;
+import com.oracle.max.cri.ci.CiRegister.*;
+
+/**
+ * A register configuration binds roles and {@linkplain RiRegisterAttributes attributes}
+ * to physical registers.
+ */
+public interface RiRegisterConfig {
+
+    /**
+     * Gets the register to be used for returning a value of a given kind.
+     */
+    CiRegister getReturnRegister(CiKind kind);
+
+    /**
+     * Gets the register to which {@link CiRegister#Frame} and {@link CiRegister#CallerFrame} are bound.
+     */
+    CiRegister getFrameRegister();
+
+    CiRegister getScratchRegister();
+
+    /**
+     * Gets the calling convention describing how arguments are passed.
+     *
+     * @param type the type of calling convention being requested
+     * @param parameters the types of the arguments of the call
+     * @param target the target platform
+     * @param stackOnly ignore registers
+     */
+    CiCallingConvention getCallingConvention(Type type, CiKind[] parameters, CiTarget target, boolean stackOnly);
+
+    /**
+     * Gets the ordered set of registers that are can be used to pass parameters
+     * according to a given calling convention.
+     *
+     * @param type the type of calling convention
+     * @param flag specifies whether registers for {@linkplain RegisterFlag#CPU integral} or
+     *             {@linkplain} RegisterFlag#FPU floating point} parameters are being requested
+     * @return the ordered set of registers that may be used to pass parameters in a call conforming to {@code type}
+     */
+    CiRegister[] getCallingConventionRegisters(Type type, RegisterFlag flag);
+
+    /**
+     * Gets the set of registers that can be used by the register allocator.
+     */
+    CiRegister[] getAllocatableRegisters();
+
+    /**
+     * Gets the set of registers that can be used by the register allocator,
+     * {@linkplain CiRegister#categorize(CiRegister[]) categorized} by register {@linkplain RegisterFlag flags}.
+     *
+     * @return a map from each {@link RegisterFlag} constant to the list of {@linkplain #getAllocatableRegisters()
+     *         allocatable} registers for which the flag is {@linkplain #isSet(RegisterFlag) set}
+     *
+     */
+    EnumMap<RegisterFlag, CiRegister[]> getCategorizedAllocatableRegisters();
+
+    /**
+     * Gets the registers whose values must be preserved by a method across any call it makes.
+     */
+    CiRegister[] getCallerSaveRegisters();
+
+    /**
+     * Gets the layout of the callee save area of this register configuration.
+     *
+     * @return {@code null} if there is no callee save area
+     */
+    CiCalleeSaveLayout getCalleeSaveLayout();
+
+    /**
+     * Gets a map from register {@linkplain CiRegister#number numbers} to register
+     * {@linkplain RiRegisterAttributes attributes} for this register configuration.
+     *
+     * @return an array where an element at index i holds the attributes of the register whose number is i
+     * @see CiRegister#categorize(CiRegister[])
+     */
+    RiRegisterAttributes[] getAttributesMap();
+
+    /**
+     * Gets the register corresponding to a runtime-defined role.
+     *
+     * @param id the identifier of a runtime-defined register role
+     * @return the register playing the role specified by {@code id}
+     */
+    CiRegister getRegisterForRole(int id);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedField.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ri;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+
+import com.oracle.max.cri.ci.*;
+
+/**
+ * Represents a reference to a resolved field. Fields, like methods and types, are
+ * resolved through {@link RiConstantPool constant pools}, and their actual implementation is provided by the
+ * {@link RiRuntime runtime} to the compiler.
+ */
+public interface RiResolvedField extends RiField {
+
+    /**
+     * Gets the access flags for this field. Only the flags specified in the JVM specification
+     * will be included in the returned mask. The utility methods in the {@link Modifier} class
+     * should be used to query the returned mask for the presence/absence of individual flags.
+     * @return the mask of JVM defined field access flags defined for this field
+     */
+    int accessFlags();
+
+    /**
+     * Gets the constant value of this field if available.
+     * @param receiver object from which this field's value is to be read. This value is ignored if this field is static.
+     * @return the constant value of this field or {@code null} if the constant value is not available
+     */
+    CiConstant constantValue(CiConstant receiver);
+
+    /**
+     * Gets the holder of this field as a compiler-runtime interface type.
+     * @return the holder of this field
+     */
+    RiResolvedType holder();
+
+    /**
+     * Returns this field's annotation of a specified type.
+     *
+     * @param annotationClass the Class object corresponding to the annotation type
+     * @return the annotation of type {@code annotationClass} for this field if present, else null
+     */
+    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedMethod.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ri;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+
+
+/**
+ * Represents resolved methods. Methods, like fields and types, are resolved through
+ * {@link RiConstantPool constant pools}, and their actual implementation is provided by the {@link RiRuntime runtime}
+ * to the compiler.
+ */
+public interface RiResolvedMethod extends RiMethod {
+
+    /**
+     * Gets the bytecode of the method, if the method {@linkplain #isResolved()} and has code.
+     * @return the bytecode of the method or {@code null} if none is available
+     */
+    byte[] code();
+
+    /**
+     * Gets the size of the bytecode of the method, if the method {@linkplain #isResolved()} and has code.
+     * @return the size of the bytecode in bytes, or 0 if no bytecode is available
+     */
+    int codeSize();
+
+    /**
+     * Gets the size of the compiled machine code.
+     * @return the size of the compiled machine code in bytes, or 0 if no compiled code exists.
+     */
+    int compiledCodeSize();
+
+    /**
+     * Gets an estimate how complex it is to compile this method.
+     * @return A value >= 0, where higher means more complex.
+     */
+    int compilationComplexity();
+
+    /**
+     * Gets the symbol used to link this method if it is native, otherwise {@code null}.
+     */
+    String jniSymbol();
+
+    /**
+     * Gets the type in which this method is declared.
+     * @return the type in which this method is declared
+     */
+    RiResolvedType holder();
+
+    /**
+     * Gets the maximum number of locals used in this method's bytecode.
+     * @return the maximum number of locals
+     */
+    int maxLocals();
+
+    /**
+     * Gets the maximum number of stack slots used in this method's bytecode.
+     * @return the maximum number of stack slots
+     */
+    int maxStackSize();
+
+    /**
+     * Checks whether this method has balanced monitor operations.
+     * @return {@code true} if the method has balanced monitor operations
+     */
+    boolean hasBalancedMonitors();
+
+    /**
+     * Gets the access flags for this method. Only the flags specified in the JVM specification
+     * will be included in the returned mask. The utility methods in the {@link Modifier} class
+     * should be used to query the returned mask for the presence/absence of individual flags.
+     * @return the mask of JVM defined method access flags defined for this method
+     */
+    int accessFlags();
+
+    /**
+     * Checks whether this method is a leaf method.
+     * @return {@code true} if the method is a leaf method (that is, is final or private)
+     */
+    boolean isLeafMethod();
+
+    /**
+     * Checks whether this method is a class initializer.
+     * @return {@code true} if the method is a class initializer
+     */
+    boolean isClassInitializer();
+
+    /**
+     * Checks whether this method is a constructor.
+     * @return {@code true} if the method is a constructor
+     */
+    boolean isConstructor();
+
+    /**
+     * Checks whether this method has been overridden. Decisions made based
+     * on a method being overridden must be registered as dependencies.
+     * @return {@code true} if the method has been overridden
+     */
+    boolean isOverridden();
+
+    /**
+     * Checks whether the compiler can insert safepoint polls in this method.
+     * @return {@code true} if the method cannot have safepoint polls inserted
+     */
+    boolean noSafepointPolls();
+
+    /**
+     * Gets a map from bytecode indexes to bit maps denoting the live locals at that position.
+     * If a non-null array is return, its length is guaranteed to be equal to {@code code().length}.
+     *
+     * @return the liveness map if it is available; {@code null} otherwise
+     */
+    CiBitMap[] livenessMap();
+
+    /**
+     * Checks whether this method can be statically bound (that is, it is final or private or static).
+     * @return {@code true} if this method can be statically bound
+     */
+    boolean canBeStaticallyBound();
+
+    /**
+     * Gets the list of exception handlers for this method.
+     * @return the list of exception handlers
+     */
+    RiExceptionHandler[] exceptionHandlers();
+
+    /**
+     * Gets a stack trace element for this method and a given bytecode index.
+     */
+    StackTraceElement toStackTraceElement(int bci);
+
+    /**
+     * Temporary work-around to support the @ACCESSOR Maxine annotation.
+     * Non-Maxine VMs should just return {@code null}.
+     */
+    RiResolvedType accessor();
+
+    /**
+     * Gets the intrinsic id of this method.
+     */
+    String intrinsic();
+
+    /**
+     * Provides an estimate of how often this method has been executed.
+     * @return The number of invocations, or -1 if this information isn't available.
+     */
+    int invocationCount();
+
+    /**
+     * Returns an object that provides access to the method's profiling information.
+     * @return The profiling information recorded for this method.
+     */
+    RiProfilingInfo profilingInfo();
+
+    /**
+     * Returns a map that the compiler can use to store objects that should survive the current compilation.
+     */
+    Map<Object, Object> compilerStorage();
+
+    /**
+     * Returns a pointer to the method's constant pool.
+     * @return the constant pool
+     */
+    RiConstantPool getConstantPool();
+
+    /**
+     * Returns this method's annotation of a specified type.
+     *
+     * @param annotationClass the Class object corresponding to the annotation type
+     * @return the annotation of type {@code annotationClass} for this method if present, else null
+     */
+    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
+
+    /**
+     * Returns an array of arrays that represent the annotations on the formal
+     * parameters, in declaration order, of this method.
+     *
+     * @see Method#getParameterAnnotations()
+     * @see CiUtil#getParameterAnnotation(int, RiResolvedMethod)
+     */
+    Annotation[][] getParameterAnnotations();
+
+    /**
+     * Returns an array of {@link Type} objects that represent the formal
+     * parameter types, in declaration order, of this method.
+     *
+     * @see Method#getGenericParameterTypes()
+     */
+    Type[] getGenericParameterTypes();
+
+    /**
+     * Returns a {@link Type} object that represents the formal return type of this method.
+     *
+     * @see Method#getGenericReturnType()
+     */
+    Type getGenericReturnType();
+
+    /**
+     * @return {@code true} if this method can be inlined
+     */
+    boolean canBeInlined();
+
+    /**
+     * Dumps the recorded profiling information to TTY.
+     */
+    void dumpProfile();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedType.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ri;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+
+import com.oracle.max.cri.ci.*;
+
+/**
+ * Represents a resolved in the compiler-runtime interface. Types include primitives, objects, {@code void},
+ * and arrays thereof. Types, like fields and methods, are resolved through {@link RiConstantPool constant pools}, and
+ * their actual implementation is provided by the {@link RiRuntime runtime} to the compiler.
+ */
+public interface RiResolvedType extends RiType {
+
+    /**
+     * Gets the encoding of (that is, a constant representing the value of) the specified part of this type.
+     * @param r the part of the this type
+     * @return a constant representing a reference to the specified part of this type
+     */
+    CiConstant getEncoding(Representation r);
+
+    /**
+     * Checks whether this type has any subclasses so far. Any decisions
+     * based on this information require the registration of a dependency, since
+     * this information may change.
+     * @return {@code true} if this class has subclasses
+     */
+    boolean hasSubclass();
+
+    /**
+     * Checks whether this type has a finalizer method.
+     * @return {@code true} if this class has a finalizer
+     */
+    boolean hasFinalizer();
+
+    /**
+     * Checks whether this type has any finalizable subclasses so far. Any decisions
+     * based on this information require the registration of a dependency, since
+     * this information may change.
+     * @return {@code true} if this class has any subclasses with finalizers
+     */
+    boolean hasFinalizableSubclass();
+
+    /**
+     * Checks whether this type is an interface.
+     * @return {@code true} if this type is an interface
+     */
+    boolean isInterface();
+
+    /**
+     * Checks whether this type is an instance class.
+     * @return {@code true} if this type is an instance class
+     */
+    boolean isInstanceClass();
+
+    /**
+     * Checks whether this type is an array class.
+     * @return {@code true} if this type is an array class
+     */
+    boolean isArrayClass();
+
+    /**
+     * Gets the access flags for this type. Only the flags specified in the JVM specification
+     * will be included in the returned mask. The utility methods in the {@link Modifier} class
+     * should be used to query the returned mask for the presence/absence of individual flags.
+     * @return the mask of JVM defined class access flags defined for this type
+     */
+    int accessFlags();
+
+    /**
+     * Checks whether this type is initialized.
+     * @return {@code true} if this type is initialized
+     */
+    boolean isInitialized();
+
+    /**
+     * Checks whether this type is a subtype of another type.
+     * @param other the type to test
+     * @return {@code true} if this type a subtype of the specified type
+     */
+    boolean isSubtypeOf(RiResolvedType other);
+
+    /**
+     * Checks whether the specified object is an instance of this type.
+     * @param obj the object to test
+     * @return {@code true} if the object is an instance of this type
+     */
+    boolean isInstance(CiConstant obj);
+
+    /**
+     * Attempts to get an exact type for this type. Final classes,
+     * arrays of final classes, and primitive types all have exact types.
+     * @return the exact type of this type, if it exists; {@code null} otherwise
+     */
+    RiResolvedType exactType();
+
+    /**
+     * Gets the super type of this type or {@code null} if no such type exists.
+     */
+    RiResolvedType superType();
+
+    /**
+     * Walks the class hierarchy upwards and returns the least common type that is a super type of both
+     * the current and the given type.
+     * @return the least common type that is a super type of both the current and the given type, or null if primitive types are involved.
+     */
+    RiResolvedType leastCommonAncestor(RiResolvedType otherType);
+
+    /**
+     * Attempts to get the unique concrete subtype of this type.
+     * @return the exact type of this type, if it exists; {@code null} otherwise
+     */
+    RiResolvedType uniqueConcreteSubtype();
+
+    /**
+     * For array types, gets the type of the components.
+     * @return the component type of this array type
+     */
+    RiResolvedType componentType();
+
+    /**
+     * Gets the type representing an array with elements of this type.
+     * @return a new compiler interface type representing an array of this type
+     */
+    RiResolvedType arrayOf();
+
+    /**
+     * Resolves the method implementation for virtual dispatches on objects
+     * of this dynamic type.
+     * @param method the method to select the implementation of
+     * @return the method implementation that would be selected at runtime
+     */
+    RiResolvedMethod resolveMethodImpl(RiResolvedMethod method);
+
+    /**
+     * Given an RiMethod a, returns a concrete RiMethod b that is the only possible
+     * unique target for a virtual call on a(). Returns {@code null} if either no
+     * such concrete method or more than one such method exists. Returns the method a
+     * if a is a concrete method that is not overridden. If the compiler uses the
+     * result of this method for its compilation, it must register an assumption
+     * (see {@link CiAssumptions}), because dynamic class loading can invalidate
+     * the result of this method.
+     * @param method the method a for which a unique concrete target is searched
+     * @return the unique concrete target or {@code null} if no such target exists
+     *         or assumptions are not supported by this runtime
+     */
+    RiResolvedMethod uniqueConcreteMethod(RiResolvedMethod method);
+
+    /**
+     * Returns the instance fields declared in this class sorted by field offset.
+     * @return an array of instance fields
+     */
+    RiResolvedField[] declaredFields();
+
+    /**
+     * Returns this type's annotation of a specified type.
+     *
+     * @param annotationClass the Class object corresponding to the annotation type
+     * @return the annotation of type {@code annotationClass} for this type if present, else null
+     */
+    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
+
+    /**
+     * Returns the java.lang.Class object representing this RiType instance or {@code null} if none exists.
+     * @return the java.lang.Class object
+     */
+    Class<?> toJava();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRuntime.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.cri.ri;
+
+import java.lang.reflect.*;
+
+import com.oracle.max.cri.ci.*;
+
+/**
+ * Encapsulates the main functionality of the runtime for the compiler, including access
+ * to constant pools, OSR frames, inlining requirements, and runtime calls such as checkcast.
+s */
+public interface RiRuntime {
+
+    /**
+     * Offset of the lock within the lock object on the stack.
+
+     * Note: superseded by sizeOfLockData() in Graal.
+     *
+     * @return the offset in bytes
+     */
+    int basicObjectLockOffsetInBytes();
+
+    /**
+     * Get the size in bytes of a lock object on the stack.
+     *
+     * Note: superseded by sizeOfLockData() in Graal.
+     */
+    int sizeOfBasicObjectLock();
+
+    /**
+     * Get the size in bytes for locking information on the stack.
+     */
+    int sizeOfLockData();
+
+    /**
+     * The offset of the normal entry to the code. The compiler inserts NOP instructions to satisfy this constraint.
+     *
+     * @return the code offset in bytes
+     */
+    int codeOffset();
+
+    /**
+     * Returns the disassembly of the given code bytes. Used for debugging purposes only.
+     *
+     * @param code the code bytes that should be disassembled
+     * @param address an address at which the bytes are located. This can be used for an address prefix per line of disassembly.
+     * @return the disassembly. This will be of length 0 if the runtime does not support disassembling.
+     */
+    String disassemble(byte[] code, long address);
+
+    /**
+     * Returns the disassembly of the given code bytes. Used for debugging purposes only.
+     *
+     * @param targetMethod the {@link CiTargetMethod} containing the code bytes that should be disassembled
+     * @return the disassembly. This will be of length 0 if the runtime does not support disassembling.
+     */
+    String disassemble(CiTargetMethod targetMethod);
+
+    /**
+     * Returns the disassembly of the given method in a {@code javap}-like format.
+     * Used for debugging purposes only.
+     *
+     * @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(RiResolvedMethod method);
+
+    /**
+     * Registers the given compiler stub and returns an object that can be used to identify it in the relocation
+     * information.
+     *
+     * @param targetMethod the target method representing the code of the compiler stub
+     * @param name the name of the stub, used for debugging purposes only
+     * @return the identification object
+     */
+    Object registerCompilerStub(CiTargetMethod targetMethod, String name);
+
+    /**
+     * Returns the RiType object representing the base type for the given kind.
+     */
+    RiResolvedType asRiType(CiKind kind);
+
+    /**
+     * Returns the type of the given constant object.
+     *
+     * @return {@code null} if {@code constant.isNull() || !constant.kind.isObject()}
+     */
+    RiResolvedType getTypeOf(CiConstant constant);
+
+
+    RiResolvedType getType(Class<?> clazz);
+
+    /**
+     * Returns true if the given type is a subtype of java/lang/Throwable.
+     */
+    boolean isExceptionType(RiResolvedType type);
+
+    /**
+     * Used by the canonicalizer to compare objects, since a given runtime might not want to expose the real objects to the compiler.
+     *
+     * @return true if the two parameters represent the same runtime object, false otherwise
+     */
+    boolean areConstantObjectsEqual(CiConstant x, CiConstant y);
+
+    /**
+     * Gets the register configuration to use when compiling a given method.
+     *
+     * @param method the top level method of a compilation
+     */
+    RiRegisterConfig getRegisterConfig(RiMethod method);
+
+    RiRegisterConfig getGlobalStubRegisterConfig();
+
+    /**
+     * Custom area on the stack of each compiled method that the VM can use for its own purposes.
+     * @return the size of the custom area in bytes
+     */
+    int getCustomStackAreaSize();
+
+    /**
+     * Minimum size of the stack area reserved for outgoing parameters. This area is reserved in all cases, even when
+     * the compiled method has no regular call instructions.
+     * @return the minimum size of the outgoing parameter area in bytes
+     */
+    int getMinimumOutgoingSize();
+
+    /**
+     * Gets the length of the array that is wrapped in a CiConstant object.
+     */
+    int getArrayLength(CiConstant array);
+
+    /**
+     * Converts the given CiConstant object to a object.
+     *
+     * @return {@code null} if the conversion is not possible <b>OR</b> {@code c.isNull() == true}
+     */
+    Object asJavaObject(CiConstant c);
+
+    /**
+     * Converts the given CiConstant object to a {@link Class} object.
+     *
+     * @return {@code null} if the conversion is not possible.
+     */
+    Class<?> asJavaClass(CiConstant c);
+
+    /**
+     * Performs any runtime-specific conversion on the object used to describe the target of a call.
+     */
+    Object asCallTarget(Object target);
+
+    /**
+     * Returns the maximum absolute offset of a runtime call target from any position in the code cache or -1
+     * when not known or not applicable. Intended for determining the required size of address/offset fields.
+     */
+    long getMaxCallTargetOffset(CiRuntimeCall rtcall);
+
+    /**
+     * Provides the {@link RiMethod} for a {@link Method} obtained via reflection.
+     */
+    RiResolvedMethod getRiMethod(Method reflectionMethod);
+
+    /**
+     * Installs some given machine code as the implementation of a given method.
+     *
+     * @param method a method whose executable code is being modified
+     * @param code the code to be executed when {@code method} is called
+     */
+    void installMethod(RiResolvedMethod method, CiTargetMethod code);
+
+    /**
+     * Adds the given machine code as an implementation of the given method without making it the default implementation.
+     * @param method a method to which the executable code is begin added
+     * @param code the code to be added
+     * @return a reference to the compiled and ready-to-run code
+     */
+    RiCompiledMethod addMethod(RiResolvedMethod method, CiTargetMethod code);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiSignature.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ri;
+
+import com.oracle.max.cri.ci.*;
+
+/**
+ * Represents a method signature provided by the runtime.
+ *
+ * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#7035">Method Descriptors</a>
+ */
+public interface RiSignature {
+    /**
+     * Gets the number of arguments in this signature, adding 1 for a receiver if requested.
+     *
+     * @param receiver true if 1 is to be added to the result for a receiver
+     * @return the number of arguments + 1 iff {@code receiver == true}
+     */
+    int argumentCount(boolean receiver);
+
+    /**
+     * Gets the argument type at the specified position. This method will return a
+     * {@linkplain RiType#isResolved() resolved} type if possible but without
+     * triggering any class loading or resolution.
+     *
+     * @param index the index into the parameters, with {@code 0} indicating the first parameter
+     * @param accessingClass the context of the type lookup. If accessing class is resolved, its class loader
+     *        is used to retrieve an existing resolved type. This value can be {@code null} if the caller does
+     *        not care for a resolved type.
+     * @return the {@code index}'th argument type
+     */
+    RiType argumentTypeAt(int index, RiResolvedType accessingClass);
+
+    /**
+     * Gets the argument kind at the specified position.
+     * @param index the index into the parameters, with {@code 0} indicating the first parameter
+     * @param architecture When true, the architecture-specific kind used for emitting machine code is returned.
+     *        When false, the kind according to the Java specification is returned.
+     * @return the kind of the argument at the specified position
+     */
+    CiKind argumentKindAt(int index, boolean architecture);
+
+    /**
+     * Gets the return type of this signature. This method will return a
+     * {@linkplain RiResolvedType resolved} type if possible but without
+     * triggering any class loading or resolution.
+     *
+     * @param accessingClass the context of the type lookup. If accessing class is resolved, its class loader
+     *        is used to retrieve an existing resolved type. This value can be {@code null} if the caller does
+     *        not care for a resolved type.
+     * @return the compiler interface type representing the return type
+     */
+    RiType returnType(RiType accessingClass);
+
+    /**
+     * Gets the return kind of this signature.
+     * @param architectureSpecific When true, the architecture-specific kind used for emitting machine code is returned.
+     *        When false, the kind according to the Java specification is returned.
+     * @return the return kind
+     */
+    CiKind returnKind(boolean architectureSpecific);
+
+    /**
+     * Converts this signature to a string.
+     * @return the signature as a string
+     */
+    String asString();
+
+    /**
+     * Gets the size, in Java slots, of the arguments to this signature.
+     * @param withReceiver {@code true} if to add a slot for a receiver object; {@code false} not to include the receiver
+     * @return the size of the arguments in slots
+     */
+    int argumentSlots(boolean withReceiver);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiType.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.ri;
+
+import com.oracle.max.cri.ci.*;
+
+/**
+ * Represents a resolved or unresolved type in the compiler-runtime interface. Types include primitives, objects, {@code void},
+ * and arrays thereof.
+ */
+public interface RiType {
+
+    /**
+     * Represents each of the several different parts of the runtime representation of
+     * a type which compiled code may need to reference individually. These may or may not be
+     * different objects or data structures, depending on the runtime system.
+     */
+    public enum Representation {
+        /**
+         * The runtime representation of the data structure containing the static fields of this type.
+         */
+        StaticFields,
+
+        /**
+         * The runtime representation of the Java class object of this type.
+         */
+        JavaClass,
+
+        /**
+         * The runtime representation of the "hub" of this type--that is, the closest part of the type
+         * representation which is typically stored in the object header.
+         */
+        ObjectHub,
+
+        /**
+         * The runtime representation of the type information for an object, which is typically used
+         * for subtype tests.
+         */
+        TypeInfo
+    }
+
+    /**
+     * Gets the name of this type in internal form. The following are examples of strings returned by this method:
+     * <pre>
+     *     "Ljava/lang/Object;"
+     *     "I"
+     *     "[[B"
+     * </pre>
+     *
+     * @return the name of this type in internal form
+     */
+    String name();
+
+    /**
+     * For array types, gets the type of the components.
+     * @return the component type of this array type
+     */
+    RiType componentType();
+
+    /**
+     * Gets the type representing an array with elements of this type.
+     * @return a new compiler interface type representing an array of this type
+     */
+    RiType arrayOf();
+
+    /**
+     * Gets the kind of this compiler interface type.
+     * @param architecture When true, the architecture-specific kind used for emitting machine code is returned.
+     *        When false, the kind according to the Java specification is returned.
+     * @return the kind
+     */
+    CiKind kind(boolean architecture);
+
+    /**
+     * Gets the kind used to represent the specified part of this type.
+     * @param r the part of the this type
+     * @return the kind of constants for the specified part of the type
+     */
+    CiKind getRepresentationKind(Representation r);
+
+    RiResolvedType resolve(RiResolvedType accessingClass);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiTypeProfile.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,71 @@
+/*
+ * 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.max.cri.ri;
+
+import java.io.*;
+
+/**
+ * This profile object represents the type profile at a specific BCI. The precision of the supplied values may vary,
+ * but a runtime that provides this information should be aware that it will be used to guide performance-critical
+ * decisions like speculative inlining, etc.
+ */
+public final class RiTypeProfile implements Serializable {
+    /**
+     *
+     */
+    private static final long serialVersionUID = -6877016333706838441L;
+
+    private final RiResolvedType[] types;
+    private final double notRecordedProbability;
+    private final double[] probabilities;
+
+    public RiTypeProfile(RiResolvedType[] types, double notRecordedProbability, double[] probabilites) {
+        this.types = types;
+        this.notRecordedProbability = notRecordedProbability;
+        this.probabilities = probabilites;
+    }
+
+    /**
+     * The estimated probabilities of the different receivers. This array needs to have the same length as the array returned by
+     * {@link RiTypeProfile#types}.
+     */
+    public double[] getProbabilities() {
+        return probabilities;
+    }
+
+    /**
+     * Returns the estimated probability of all types that could not be recorded due to profiling limitations.
+     * @return double value >= 0.0 and <= 1.0
+     */
+    public double getNotRecordedProbability() {
+        return notRecordedProbability;
+    }
+
+    /**
+     * A list of receivers for which the runtime has recorded probability information. This array needs to have the same
+     * length as {@link RiTypeProfile#probabilities}.
+     */
+    public RiResolvedType[] getTypes() {
+        return types;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/package-info.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2009, 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.
+ */
+/**
+ * The runtime-provided part of the bi-directional interface between the compiler and the runtime system of a virtual machine for the
+ * instruction set defined in {@link com.oracle.max.graal.compiler.graphbuilder.Bytecodes}.
+ * <p>
+ * Unlike the {@link com.oracle.max.cri.ci compiler-provided interface}, the runtime-provided interface is specified largely
+ * using interfaces, that must be implemented by classes provided by a specific runtime implementation.
+ * <p>
+ * {@link com.oracle.max.cri.ri.RiRuntime} encapsulates the main functionality of the runtime for the compiler.
+ * <p>
+ * Types (i.e., primitives, classes and interfaces}, fields and methods are represented by {@link com.oracle.max.cri.ri.RiType},
+ * {@link com.oracle.max.cri.ri.RiField} and {@link com.oracle.max.cri.ri.RiMethod}, respectively, with additional support from
+ * {@link com.oracle.max.cri.ri.RiSignature} and {@link com.oracle.max.cri.ri.RiExceptionHandler}. Access to the runtime constant pool
+ * is through {@link com.oracle.max.cri.ri.RiConstantPool}.
+ */
+package com.oracle.max.cri.ri;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/util/JavacBug.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,38 @@
+/*
+ * 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.max.cri.util;
+
+/**
+ * Used to indicate that an otherwise strange looking code pattern is required to work around a bug in javac.
+ */
+public @interface JavacBug {
+    /**
+     * A description of the bug. Only really useful if there is no existing entry for the bug in the <a href="http://bugs.sun.com/bugdatabase/">Bug Database</a>.
+     */
+    String value() default "";
+
+    /**
+     * An identifier in the <a href="http://bugs.sun.com/bugdatabase/">Bug Database</a>.
+     */
+    int id() default 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/util/MemoryBarriers.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2011, 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.max.cri.util;
+
+/**
+ * Constants and intrinsic definition for memory barriers.
+ *
+ * The documentation for each constant is taken from Doug Lea's
+ * <a href="http://gee.cs.oswego.edu/dl/jmm/cookbook.html">The JSR-133 Cookbook for Compiler Writers</a>.
+ * <p>
+ * The {@code JMM_*} constants capture the memory barriers necessary to implement the Java Memory Model
+ * with respect to volatile field accesses. Their values are explained by this
+ * comment from templateTable_i486.cpp in the HotSpot source code:
+ * <pre>
+ * Volatile variables demand their effects be made known to all CPU's in
+ * order.  Store buffers on most chips allow reads & writes to reorder; the
+ * JMM's ReadAfterWrite.java test fails in -Xint mode without some kind of
+ * memory barrier (i.e., it's not sufficient that the interpreter does not
+ * reorder volatile references, the hardware also must not reorder them).
+ *
+ * According to the new Java Memory Model (JMM):
+ * (1) All volatiles are serialized wrt to each other.
+ * ALSO reads & writes act as acquire & release, so:
+ * (2) A read cannot let unrelated NON-volatile memory refs that happen after
+ * the read float up to before the read.  It's OK for non-volatile memory refs
+ * that happen before the volatile read to float down below it.
+ * (3) Similarly, a volatile write cannot let unrelated NON-volatile memory refs
+ * that happen BEFORE the write float down to after the write.  It's OK for
+ * non-volatile memory refs that happen after the volatile write to float up
+ * before it.
+ *
+ * We only put in barriers around volatile refs (they are expensive), not
+ * _between_ memory refs (which would require us to track the flavor of the
+ * previous memory refs).  Requirements (2) and (3) require some barriers
+ * before volatile stores and after volatile loads.  These nearly cover
+ * requirement (1) but miss the volatile-store-volatile-load case.  This final
+ * case is placed after volatile-stores although it could just as well go
+ * before volatile-loads.
+ * </pre>
+ */
+public class MemoryBarriers {
+
+    /**
+     * The sequence {@code Load1; LoadLoad; Load2} ensures that {@code Load1}'s data are loaded before data accessed
+     * by {@code Load2} and all subsequent load instructions are loaded. In general, explicit {@code LoadLoad}
+     * barriers are needed on processors that perform speculative loads and/or out-of-order processing in which
+     * waiting load instructions can bypass waiting stores. On processors that guarantee to always preserve load
+     * ordering, these barriers amount to no-ops.
+     */
+    public static final int LOAD_LOAD   = 0x0001;
+
+    /**
+     * The sequence {@code Load1; LoadStore; Store2} ensures that {@code Load1}'s data are loaded before all data
+     * associated with {@code Store2} and subsequent store instructions are flushed. {@code LoadStore} barriers are
+     * needed only on those out-of-order processors in which waiting store instructions can bypass loads.
+     */
+    public static final int LOAD_STORE  = 0x0002;
+
+    /**
+     * The sequence {@code Store1; StoreLoad; Load2} ensures that {@code Store1}'s data are made visible to other
+     * processors (i.e., flushed to main memory) before data accessed by {@code Load2} and all subsequent load
+     * instructions are loaded. {@code StoreLoad} barriers protect against a subsequent load incorrectly using
+     * {@code Store1}'s data value rather than that from a more recent store to the same location performed by a
+     * different processor. Because of this, on the processors discussed below, a {@code StoreLoad} is strictly
+     * necessary only for separating stores from subsequent loads of the same location(s) as were stored before the
+     * barrier. {@code StoreLoad} barriers are needed on nearly all recent multiprocessors, and are usually the most
+     * expensive kind. Part of the reason they are expensive is that they must disable mechanisms that ordinarily
+     * bypass cache to satisfy loads from write-buffers. This might be implemented by letting the buffer fully
+     * flush, among other possible stalls.
+     */
+    public static final int STORE_LOAD  = 0x0004;
+
+    /**
+     * The sequence {@code Store1; StoreStore; Store2} ensures that {@code Store1}'s data are visible to other
+     * processors (i.e., flushed to memory) before the data associated with {@code Store2} and all subsequent store
+     * instructions. In general, {@code StoreStore} barriers are needed on processors that do not otherwise
+     * guarantee strict ordering of flushes from write buffers and/or caches to other processors or main memory.
+     */
+    public static final int STORE_STORE = 0x0008;
+
+    public static final int JMM_PRE_VOLATILE_WRITE = LOAD_STORE | STORE_STORE;
+    public static final int JMM_POST_VOLATILE_WRITE = STORE_LOAD | STORE_STORE;
+    public static final int JMM_PRE_VOLATILE_READ = 0;
+    public static final int JMM_POST_VOLATILE_READ = LOAD_LOAD | LOAD_STORE;
+
+    public static String barriersString(int barriers) {
+        StringBuilder sb = new StringBuilder();
+        sb.append((barriers & LOAD_LOAD) != 0 ? "LOAD_LOAD " : "");
+        sb.append((barriers & LOAD_STORE) != 0 ? "LOAD_STORE " : "");
+        sb.append((barriers & STORE_LOAD) != 0 ? "STORE_LOAD " : "");
+        sb.append((barriers & STORE_STORE) != 0 ? "STORE_STORE " : "");
+        return sb.toString().trim();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/util/UnsignedMath.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2011, 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.max.cri.util;
+
+/**
+ * {@link INTRINSIC} method definitions for unsigned comparisons.
+ * All methods have correct, but slow, standard Java implementations so that
+ * they can be used with compilers not supporting the intrinsics.
+ */
+public class UnsignedMath {
+    private static final long MASK = 0xffffffffL;
+
+    /**
+     * Unsigned comparison aboveThan for two numbers.
+     */
+    public static boolean aboveThan(int a, int b) {
+        return (a & MASK) > (b & MASK);
+    }
+
+    /**
+     * Unsigned comparison aboveOrEqual for two numbers.
+     */
+    public static boolean aboveOrEqual(int a, int b) {
+        return (a & MASK) >= (b & MASK);
+    }
+
+    /**
+     * Unsigned comparison belowThan for two numbers.
+     */
+    public static boolean belowThan(int a, int b) {
+        return (a & MASK) < (b & MASK);
+    }
+
+    /**
+     * Unsigned comparison belowOrEqual for two numbers.
+     */
+    public static boolean belowOrEqual(int a, int b) {
+        return (a & MASK) <= (b & MASK);
+    }
+
+    /**
+     * Unsigned comparison aboveThan for two numbers.
+     */
+    public static boolean aboveThan(long a, long b) {
+        return (a > b) ^ ((a < 0) != (b < 0));
+    }
+
+    /**
+     * Unsigned comparison aboveOrEqual for two numbers.
+     */
+    public static boolean aboveOrEqual(long a, long b) {
+        return (a >= b) ^ ((a < 0) != (b < 0));
+    }
+
+    /**
+     * Unsigned comparison belowThan for two numbers.
+     */
+    public static boolean belowThan(long a, long b) {
+        return (a < b) ^ ((a < 0) != (b < 0));
+    }
+
+    /**
+     * Unsigned comparison belowOrEqual for two numbers.
+     */
+    public static boolean belowOrEqual(long a, long b) {
+        return (a <= b) ^ ((a < 0) != (b < 0));
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/CiXirAssembler.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,980 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.xir;
+
+import static com.oracle.max.cri.xir.CiXirAssembler.XirOp.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiAddress.*;
+import com.oracle.max.cri.ri.*;
+
+/**
+ * Represents an assembler that allows a client such as the runtime system to
+ * create {@link XirTemplate XIR templates}.
+ */
+public abstract class CiXirAssembler {
+
+    protected XirOperand resultOperand;
+    protected boolean allocateResultOperand;
+
+    protected final List<XirInstruction> instructions = new ArrayList<>();
+    protected final List<XirLabel> labels = new ArrayList<>(5);
+    protected final List<XirParameter> parameters = new ArrayList<>(5);
+    protected final List<XirTemp> temps = new ArrayList<>(5);
+    protected final List<XirConstant> constants = new ArrayList<>(5);
+    protected final List<XirMark> marks = new ArrayList<>(5);
+
+    protected int outgoingStackSize = 0;
+
+    /**
+     * Increases by one for every {@link XirOperand operand} created.
+     */
+    protected int variableCount;
+
+    /**
+     * Marks the assembly complete.
+     */
+    protected boolean finished = true;
+
+    protected final CiTarget target;
+
+    public CiXirAssembler(CiTarget target) {
+        this.target = target;
+    }
+
+    public static class RuntimeCallInformation {
+        public final Object target;
+        public final boolean useInfoAfter;
+
+        public RuntimeCallInformation(Object target, boolean useInfoAfter) {
+            this.target = target;
+            this.useInfoAfter = useInfoAfter;
+        }
+    }
+
+    /**
+     * Represents additional address calculation information.
+     */
+    public static final class AddressAccessInformation {
+
+        /**
+         * The scaling factor for the scaled-index part of an address computation.
+         */
+        public final Scale scale;
+
+        /**
+         * The constant byte-sized displacement part of an address computation.
+         */
+        public final int disp;
+
+        /**
+         * Determines if the memory access through the address can trap.
+         */
+        public final boolean canTrap;
+
+        private AddressAccessInformation(boolean canTrap) {
+            this.canTrap = canTrap;
+            this.scale = Scale.Times1;
+            this.disp = 0;
+        }
+
+        private AddressAccessInformation(boolean canTrap, int disp) {
+            this.canTrap = canTrap;
+            this.scale = Scale.Times1;
+            this.disp = disp;
+        }
+
+        private AddressAccessInformation(boolean canTrap, int disp, Scale scale) {
+            this.canTrap = canTrap;
+            this.scale = scale;
+            this.disp = disp;
+        }
+    }
+
+    /**
+     * A label that is the target of a control flow instruction.
+     */
+    public static final class XirLabel {
+        public static final String TrueSuccessor = "TrueSuccessor";
+        public static final String FalseSuccessor = "FalseSuccessor";
+        public final String name;
+        public final int index;
+        /**
+         * If {@code true} the label is to an instruction in the fast path sequence, otherwise to the slow path.
+         */
+        public final boolean inline;
+
+        private XirLabel(String name, int index, boolean inline) {
+            this.name = name;
+            this.index = index;
+            this.inline = inline;
+        }
+
+        @Override
+        public String toString() {
+            return name;
+        }
+    }
+
+    /**
+     * Tagging interface that indicates that an {@link XirOperand} is a constant.
+     */
+    public interface XirConstantOperand {
+        int getIndex();
+    }
+
+    public static final XirOperand VOID = null;
+
+    /**
+     * Operands for {@link XirInstruction instructions}.
+     * There are three basic variants, {@link XirConstant constant}, {@link XirParameter parameter} and {@link XirTemp}.
+     */
+    public abstract static class XirOperand {
+
+        public final CiKind kind;
+
+        /**
+         * Unique id in range {@code 0} to {@link #variableCount variableCount - 1}.
+         */
+        public final int index;
+
+        /**
+         * Value whose {@link #toString()} method provides a name for this operand.
+         */
+        public final Object name;
+
+        public XirOperand(CiXirAssembler asm, Object name, CiKind kind) {
+            this.kind = kind;
+            this.name = name;
+            this.index = asm.variableCount++;
+        }
+
+        @Override
+        public String toString() {
+            return String.valueOf(name);
+        }
+
+        public String detailedToString() {
+
+            StringBuffer sb = new StringBuffer();
+
+            sb.append(name);
+            sb.append('$');
+            sb.append(kind.typeChar);
+            return sb.toString();
+        }
+    }
+
+    /**
+     * Parameters to {@link XirTemplate templates}.
+     */
+    public static class XirParameter extends XirOperand {
+        /**
+         * Unique id in range {@code 0} to {@code parameters.Size()  - 1}.
+         */
+        public final int parameterIndex;
+
+        public final boolean canBeConstant;
+
+        XirParameter(CiXirAssembler asm, String name, CiKind kind, boolean canBeConstant) {
+            super(asm, name, kind);
+            this.parameterIndex = asm.parameters.size();
+            this.canBeConstant = canBeConstant;
+            asm.parameters.add(this);
+        }
+
+    }
+
+    public static class XirConstantParameter extends XirParameter implements XirConstantOperand {
+        XirConstantParameter(CiXirAssembler asm, String name, CiKind kind) {
+            super(asm, name, kind, true);
+        }
+
+        public int getIndex() {
+            return index;
+        }
+    }
+
+    public static class XirVariableParameter extends XirParameter {
+        XirVariableParameter(CiXirAssembler asm, String name, CiKind kind, boolean canBeConstant) {
+            super(asm, name, kind, canBeConstant);
+        }
+    }
+
+    public static class XirConstant extends XirOperand implements XirConstantOperand {
+        public final CiConstant value;
+
+        XirConstant(CiXirAssembler asm, CiConstant value) {
+            super(asm, value, value.kind);
+            this.value = value;
+        }
+
+        public int getIndex() {
+            return index;
+        }
+    }
+
+    public static class XirTemp extends XirOperand {
+        public final boolean reserve;
+
+        XirTemp(CiXirAssembler asm, String name, CiKind kind, boolean reserve) {
+            super(asm, name, kind);
+            this.reserve = reserve;
+        }
+    }
+
+    public static class XirRegister extends XirTemp {
+        public final CiValue register;
+
+        XirRegister(CiXirAssembler asm, String name, CiRegisterValue register, boolean reserve) {
+            super(asm, name, register.kind, reserve);
+            this.register = register;
+        }
+    }
+
+    /**
+     * Start a new assembly with no initial {@link #resultOperand result operand}.
+     */
+    public void restart() {
+        reset();
+        resultOperand = null;
+    }
+
+    /**
+     * Start a new assembly with a {@link #resultOperand result operand} of type {@code kind}.
+     * @param kind the result kind
+     * @return an {@code XirOperand} for the result operand
+     */
+    public XirOperand restart(CiKind kind) {
+        reset();
+        resultOperand = new XirTemp(this, "result", kind, true);
+        allocateResultOperand = true;
+        return resultOperand;
+    }
+
+    /**
+     * Reset the state of the class to the initial conditions to facilitate a new assembly.
+     */
+    private void reset() {
+        assert finished : "must be finished before!";
+        variableCount = 0;
+        allocateResultOperand = false;
+        finished = false;
+        instructions.clear();
+        labels.clear();
+        parameters.clear();
+        temps.clear();
+        constants.clear();
+        marks.clear();
+        outgoingStackSize = 0;
+    }
+
+    /**
+     * Represents an XIR instruction, characterized by an {@link XirOp operation}, a {@link CiKind kind}, an optional {@link XirOperand result}, a variable number of {@link XirOperand arguments},
+     * and some optional instruction-specific state. The {@link #x}, {@link #y} and {@link #z} methods are convenient ways to access the first, second and third
+     * arguments, respectively. Only the {@link XirOp#CallStub} and {@link XirOp#CallRuntime} instructions can have more than three arguments.
+     *
+     */
+    public static final class XirInstruction {
+        /**
+         * The {@link CiKind kind} of values the instruction operates on.
+         */
+        public final CiKind kind;
+        /**
+         * The {@link XirOp operation}.
+         */
+        public final XirOp op;
+        /**
+         * The result, if any.
+         */
+        public final XirOperand result;
+        /**
+         * The arguments.
+         */
+        public final XirOperand[] arguments;
+        /**
+         * Arbitrary additional data associated with the instruction.
+         */
+        public final Object extra;
+
+        public XirInstruction(CiKind kind, XirOp op, XirOperand result, XirOperand... arguments) {
+            this(kind, null, op, result, arguments);
+        }
+
+        public XirInstruction(CiKind kind, Object extra, XirOp op, XirOperand result, XirOperand... arguments) {
+            this.extra = extra;
+            this.kind = kind;
+            this.op = op;
+            this.result = result;
+            this.arguments = arguments;
+        }
+
+        public XirOperand x() {
+            assert arguments.length > 0 : "no x operand for this instruction";
+            return arguments[0];
+        }
+
+        public XirOperand y() {
+            assert arguments.length > 1 : "no y operand for this instruction";
+            return arguments[1];
+        }
+
+        public XirOperand z() {
+            assert arguments.length > 2 : "no z operand for this instruction";
+            return arguments[2];
+        }
+
+        @Override
+        public String toString() {
+            StringBuffer sb = new StringBuffer();
+
+            if (result != null) {
+                sb.append(result.toString());
+                sb.append(" = ");
+            }
+
+            sb.append(op.name());
+
+            if (kind != CiKind.Void) {
+                sb.append('$');
+                sb.append(kind.typeChar);
+            }
+
+            if (arguments != null && arguments.length > 0) {
+                sb.append("(");
+
+                for (int i = 0; i < arguments.length; i++) {
+                    if (i != 0) {
+                        sb.append(", ");
+                    }
+                    sb.append(arguments[i]);
+                }
+
+                sb.append(")");
+            }
+
+            if (extra != null) {
+                sb.append(" ");
+                sb.append(extra);
+            }
+
+            return sb.toString();
+        }
+    }
+
+    /**
+     * These marks let the RiXirGenerator mark positions in the generated native code and bring them in relationship with on another.
+     * This is necessary for code patching, etc.
+     */
+    public static class XirMark {
+        public final XirMark[] references;
+        public final Object id;
+
+        // special mark used to refer to the actual call site of an invoke
+        public static final XirMark CALLSITE = new XirMark(null);
+
+        public XirMark(Object id, XirMark... references) {
+            this.id = id;
+            this.references = references;
+        }
+    }
+
+    /**
+     * The set of opcodes for XIR instructions.
+     * {@link XirInstruction} defines {@code x}, {@code y} and {@code z} as the first, second and third arguments, respectively.
+     * We use these mnemonics, plus {@code args} for the complete set of arguments, {@code r} for the result, and {@code extra}
+     * for the instruction-specific extra data, in the opcode specifications. Note that the opcodes that operate on values do not directly
+     * specify the size (kind) of the data operated on;  this is is encoded in {@link XirInstruction#kind}.
+     * Note: If the instruction kind differs from the argument/result kinds, the behavior is undefined.
+     *
+     */
+    public enum XirOp {
+        /**
+         * Move {@code x} to {@code r}.
+         */
+        Mov,
+        /**
+         * Add {@code y} to {@code x} and put the result in {@code r}.
+         */
+        Add,
+        /**
+         * Subtract {@code y} from {@code x} and put the result in {@code r}.
+         */
+        Sub,
+        /**
+         * Divide {@code y} by {@code x} and put the result in {@code r}.
+         */
+        Div,
+        /**
+         * Multiply {@code y} by {@code x} and put the result in {@code r}.
+         */
+        Mul,
+        /**
+         * {@code y} modulus {@code x} and put the result in {@code r}.
+         */
+        Mod,
+        /**
+         * Shift  {@code y} left by {@code x} and put the result in {@code r}.
+         */
+        Shl,
+        /**
+         * Arithmetic shift  {@code y} right by {@code x} and put the result in {@code r}.
+         */
+        Sar,
+        /**
+         * Shift  {@code y} right by {@code x} and put the result in {@code r}.
+         */
+        Shr,
+        /**
+         * And {@code y} by {@code x} and put the result in {@code r}.
+         */
+        And,
+        /**
+         * Or {@code y} by {@code x} and put the result in {@code r}.
+         */
+        Or,
+        /**
+         * Exclusive Or {@code y} by {@code x} and put the result in {@code r}.
+         */
+        Xor,
+        /**
+         * Null check on {@code x}.
+         */
+        NullCheck,
+        /**
+         * Load value at address {@code x} and put the result in {@code r}.
+         */
+        PointerLoad,
+        /**
+         * Store {@code y} at address {@code x}.
+         */
+        PointerStore,
+        /**
+         * Load value at an effective address defined by base {@code x} and either a scaled index {@code y} plus displacement
+         * or an offset {@code y} and put the result in {@code r}.
+         */
+        PointerLoadDisp,
+        /**
+         * Load an effective address defined by base {@code x} and either a scaled index {@code y} plus displacement
+         * or an offset {@code y} and put the result in {@code r}.
+         */
+        LoadEffectiveAddress,
+        /**
+         * Store {@code z} at address defined by base {@code x} and index {@code y}.
+         */
+        PointerStoreDisp,
+        /**
+         * Repeat move from {@code x} to {@code y} using {@code z} words.
+         */
+        RepeatMoveWords,
+        /**
+         * Repeat move from {@code x} to {@code y} using {@code z} words.
+         */
+        RepeatMoveBytes,
+        /**
+         * Compare value at at address {@code x} with value in {@code y} and store value {@code z} at address {@code x}
+         * if it was equal to {@code y}.
+         */
+        PointerCAS,
+        /**
+         * Call the {@link RiMethod} defined by {@code extra}  with {@code args} and put the result in {@code r}.
+         */
+        CallRuntime,
+        /**
+         * Transfer control to the instruction at the {@link XirLabel label} identified by {@code extra}.
+         */
+        Jmp,
+       /**
+         * If {@code x == y}, transfer control to the instruction at the {@link XirLabel label} identified by {@code extra}.
+         */
+        Jeq,
+        /**
+         * If {@code x != y}, transfer control to the instruction at the {@link XirLabel label} identified by {@code extra}.
+         */
+        Jneq,
+        /**
+         * If {@code x > y}, transfer control to the instruction at the {@link XirLabel label} identified by {@code extra}.
+         */
+        Jgt,
+        /**
+         * If {@code x >= y}, transfer control to the instruction at the {@link XirLabel label} identified by {@code extra}.
+         */
+        Jgteq,
+        /**
+         * If {@code x unsigned >= y}, transfer control to the instruction at the {@link XirLabel label} identified by {@code extra}.
+         */
+        Jugteq,
+        /**
+         * If {@code x < y}, transfer control to the instruction at the {@link XirLabel label} identified by {@code extra}.
+         */
+        Jlt,
+        /**
+         * If {@code x <= y}, transfer control to the instruction at the {@link XirLabel label} identified by {@code extra}.
+         */
+        Jlteq,
+        /**
+         * Decreases the input by one and jumps to the target if the input is not 0.
+         */
+        DecAndJumpNotZero,
+        /**
+         * If bit designated by {@code z} at effective address defined by base {@code x} and offset {@code y}
+         * is set transfer control to the instruction at the {@link XirLabel label} identified by {@code extra}.
+         */
+        Jbset,
+        /**
+         * Bind the {@link XirLabel label} identified by {@code extra} to the current instruction and update any references to it.
+         * A label may be bound more than once to the same location.
+         */
+        Bind,
+        /**
+         * Record a safepoint.
+         */
+        Safepoint,
+        /**
+         * Align the code following this instruction to a multiple of (int)extra.
+         */
+        Align,
+        /**
+         * Creates the stack banging overflow check.
+         */
+        StackOverflowCheck,
+        /**
+         * Creates the stack frame for the method and spills callee-save registers (if any) to the {@linkplain CiRegisterSaveArea register save area}.
+         */
+        PushFrame,
+        /**
+         * Restores all callee-save registers (if any) and removes the stack frame of the method.
+         */
+        PopFrame,
+        /**
+         * Inserts an array of bytes directly into the code output.
+         */
+        RawBytes,
+        /**
+         * Pushes a value onto the stack.
+         */
+        Push,
+        /**
+         * Pops a value from the stack.
+         */
+        Pop,
+        /**
+         * Marks a position in the generated native code.
+         */
+        Mark,
+        /**
+         * Load instruction pointer of the next instruction in a destination register.
+         */
+        Here,
+        /**
+         * Inserts nop instructions, with the given size in bytes.
+         */
+        Nop,
+        /**
+         * This instruction should never be reached, this is useful for debugging purposes.
+         */
+         ShouldNotReachHere
+    }
+
+    public/*private*/ void append(XirInstruction xirInstruction) {
+        assert !finished : "no instructions can be added to finished template";
+        instructions.add(xirInstruction);
+    }
+
+    public XirLabel createInlineLabel(String name) {
+        final XirLabel result = new XirLabel(name, this.labels.size(), true);
+        labels.add(result);
+        return result;
+    }
+
+    public XirLabel createOutOfLineLabel(String name) {
+        final XirLabel result = new XirLabel(name, this.labels.size(), false);
+        labels.add(result);
+        return result;
+    }
+
+    public void mov(XirOperand result, XirOperand a) {
+        append(new XirInstruction(result.kind, Mov, result, a));
+    }
+
+    public void add(XirOperand result, XirOperand a, XirOperand b) {
+        append(new XirInstruction(result.kind, Add, result, a, b));
+    }
+
+    public void sub(XirOperand result, XirOperand a, XirOperand b) {
+        append(new XirInstruction(result.kind, Sub, result, a, b));
+    }
+
+    public void div(XirOperand result, XirOperand a, XirOperand b) {
+        append(new XirInstruction(result.kind, Div, result, a, b));
+    }
+
+    public void mul(XirOperand result, XirOperand a, XirOperand b) {
+        append(new XirInstruction(result.kind, Mul, result, a, b));
+    }
+
+    public void mod(XirOperand result, XirOperand a, XirOperand b) {
+        append(new XirInstruction(result.kind, Mod, result, a, b));
+    }
+
+    public void shl(XirOperand result, XirOperand a, XirOperand b) {
+        append(new XirInstruction(result.kind, Shl, result, a, b));
+    }
+
+    public void shr(XirOperand result, XirOperand a, XirOperand b) {
+        append(new XirInstruction(result.kind, Shr, result, a, b));
+    }
+
+    public void and(XirOperand result, XirOperand a, XirOperand b) {
+        append(new XirInstruction(result.kind, And, result, a, b));
+    }
+
+    public void or(XirOperand result, XirOperand a, XirOperand b) {
+        append(new XirInstruction(result.kind, Or, result, a, b));
+    }
+
+    public void xor(XirOperand result, XirOperand a, XirOperand b) {
+        append(new XirInstruction(result.kind, Xor, result, a, b));
+    }
+
+    public void nullCheck(XirOperand pointer) {
+        append(new XirInstruction(CiKind.Object, NullCheck, VOID, pointer));
+    }
+
+    public void pload(CiKind kind, XirOperand result, XirOperand pointer, boolean canTrap) {
+        append(new XirInstruction(kind, canTrap, PointerLoad, result, pointer));
+    }
+
+    public void pstore(CiKind kind, XirOperand pointer, XirOperand value, boolean canTrap) {
+        append(new XirInstruction(kind, canTrap, PointerStore, null, pointer, value));
+    }
+
+    public void pload(CiKind kind, XirOperand result, XirOperand pointer, XirOperand offset, boolean canTrap) {
+        append(new XirInstruction(kind, new AddressAccessInformation(canTrap), PointerLoadDisp, result, pointer, offset));
+    }
+
+    public void pstore(CiKind kind, XirOperand pointer, XirOperand offset, XirOperand value, boolean canTrap) {
+        append(new XirInstruction(kind, new AddressAccessInformation(canTrap), PointerStoreDisp, VOID, pointer, offset, value));
+    }
+
+    public void pload(CiKind kind, XirOperand result, XirOperand pointer, XirOperand index, int disp, Scale scale,  boolean canTrap) {
+        append(new XirInstruction(kind, new AddressAccessInformation(canTrap, disp, scale), PointerLoadDisp, result, pointer, index));
+    }
+
+    public void lea(XirOperand result, XirOperand pointer, XirOperand index, int disp, Scale scale) {
+        append(new XirInstruction(target.wordKind, new AddressAccessInformation(false, disp, scale), LoadEffectiveAddress, result, pointer, index));
+    }
+
+    public void repmov(XirOperand src, XirOperand dest, XirOperand length) {
+        append(new XirInstruction(target.wordKind, null, RepeatMoveWords, null, src, dest, length));
+    }
+
+    public void here(XirOperand dst) {
+        append(new XirInstruction(target.wordKind, null, Here, dst));
+    }
+
+    public void repmovb(XirOperand src, XirOperand dest, XirOperand length) {
+        append(new XirInstruction(target.wordKind, null, RepeatMoveBytes, null, src, dest, length));
+    }
+
+    public void pstore(CiKind kind, XirOperand pointer, XirOperand index, XirOperand value, int disp, Scale scale, boolean canTrap) {
+        append(new XirInstruction(kind, new AddressAccessInformation(canTrap, disp, scale), PointerStoreDisp, VOID, pointer, index, value));
+    }
+
+    public void pcas(CiKind kind, XirOperand result, XirOperand pointer, XirOperand newValue, XirOperand oldValue) {
+        append(new XirInstruction(kind, null, PointerCAS, result, pointer, newValue, oldValue));
+    }
+
+    public void jmp(XirLabel l) {
+        append(new XirInstruction(CiKind.Void, l, Jmp, null));
+    }
+
+    public void decAndJumpNotZero(XirLabel l, XirOperand val) {
+        append(new XirInstruction(CiKind.Void, l, DecAndJumpNotZero, null, val));
+    }
+
+    public void jmpRuntime(Object rt) {
+        append(new XirInstruction(CiKind.Void, rt, Jmp, null));
+    }
+
+    public void jeq(XirLabel l, XirOperand a, XirOperand b) {
+        jcc(Jeq, l, a, b);
+    }
+
+    private void jcc(XirOp op, XirLabel l, XirOperand a, XirOperand b) {
+        append(new XirInstruction(CiKind.Void, l, op, null, a, b));
+    }
+
+    public void jneq(XirLabel l, XirOperand a, XirOperand b) {
+        jcc(Jneq, l, a, b);
+    }
+
+    public void jgt(XirLabel l, XirOperand a, XirOperand b) {
+        jcc(Jgt, l, a, b);
+    }
+
+    public void jgteq(XirLabel l, XirOperand a, XirOperand b) {
+        jcc(Jgteq, l, a, b);
+    }
+
+    public void jugteq(XirLabel l, XirOperand a, XirOperand b) {
+        jcc(Jugteq, l, a, b);
+    }
+
+    public void jlt(XirLabel l, XirOperand a, XirOperand b) {
+        jcc(Jlt, l, a, b);
+    }
+
+    public void jlteq(XirLabel l, XirOperand a, XirOperand b) {
+        jcc(Jlteq, l, a, b);
+    }
+
+    public void jbset(XirLabel l, XirOperand a, XirOperand b, XirOperand c) {
+        append(new XirInstruction(CiKind.Void, l, Jbset, null, a, b, c));
+    }
+
+    public void bindInline(XirLabel l) {
+        assert l.inline;
+        append(new XirInstruction(CiKind.Void, l, Bind, null));
+    }
+
+    public void bindOutOfLine(XirLabel l) {
+        assert !l.inline;
+        append(new XirInstruction(CiKind.Void, l, Bind, null));
+    }
+
+    public void safepoint() {
+        append(new XirInstruction(CiKind.Void, null, Safepoint, null));
+    }
+
+    public void align(int multiple) {
+        assert multiple > 0;
+        append(new XirInstruction(CiKind.Void, multiple, Align, null));
+    }
+
+    public void stackOverflowCheck() {
+        append(new XirInstruction(CiKind.Void, null, StackOverflowCheck, null));
+    }
+
+    public void pushFrame() {
+        append(new XirInstruction(CiKind.Void, null, PushFrame, null));
+    }
+
+    public void popFrame() {
+        append(new XirInstruction(CiKind.Void, null, PopFrame, null));
+    }
+
+    public void rawBytes(byte[] bytes) {
+        append(new XirInstruction(CiKind.Void, bytes, RawBytes, null));
+    }
+
+    public void push(XirOperand value) {
+        append(new XirInstruction(CiKind.Void, Push, VOID, value));
+    }
+
+    public void pop(XirOperand result) {
+        append(new XirInstruction(result.kind, Pop, result));
+    }
+
+    public XirMark mark(Object id, XirMark... references) {
+        XirMark mark = new XirMark(id, references);
+        marks.add(mark);
+        append(new XirInstruction(CiKind.Void, mark, Mark, null));
+        return mark;
+    }
+
+    public void nop(int size) {
+        append(new XirInstruction(CiKind.Void, size, Nop, null));
+    }
+
+    public void shouldNotReachHere() {
+        append(new XirInstruction(CiKind.Void, null, ShouldNotReachHere, null));
+    }
+
+    public void shouldNotReachHere(String message) {
+        append(new XirInstruction(CiKind.Void, message, ShouldNotReachHere, null));
+    }
+
+    public void callRuntime(Object rt, XirOperand result, XirOperand... args) {
+        callRuntime(rt, result, false, args);
+    }
+
+    public void callRuntime(Object rt, XirOperand result, boolean useInfoAfter, XirOperand... args) {
+        CiKind resultKind = result == null ? CiKind.Void : result.kind;
+        append(new XirInstruction(resultKind, new RuntimeCallInformation(rt, useInfoAfter), CallRuntime, result, args));
+    }
+
+    /**
+     * Terminates the assembly, checking invariants, in particular that {@link resultOperand} is set, and setting {@link #finished} to {@code true}.
+     */
+    private void end() {
+        assert !finished : "template may only be finished once!";
+        assert resultOperand != null : "result operand should be set";
+        finished = true;
+    }
+
+    /**
+     * Creates an {@link XirVariableParameter variable input parameter}  of given name and {@link CiKind kind}.
+     * @param name a name for the parameter
+     * @param kind the parameter kind
+     * @return the  {@link XirVariableParameter}
+     */
+    public XirVariableParameter createInputParameter(String name, CiKind kind, boolean canBeConstant) {
+        assert !finished;
+        return new XirVariableParameter(this, name, kind, canBeConstant);
+    }
+
+    public XirVariableParameter createInputParameter(String name, CiKind kind) {
+        return createInputParameter(name, kind, false);
+    }
+
+    /**
+     * Creates an {@link XirConstantParameter constant input parameter}  of given name and {@link CiKind kind}.
+     * @param name a name for the parameter
+     * @param kind the parameter kind
+     * @return the  {@link XirConstantParameter}
+     */
+    public XirConstantParameter createConstantInputParameter(String name, CiKind kind) {
+        assert !finished;
+        return new XirConstantParameter(this, name, kind);
+    }
+
+    public XirConstant createConstant(CiConstant constant) {
+        assert !finished;
+        XirConstant temp = new XirConstant(this, constant);
+        constants.add(temp);
+        return temp;
+    }
+
+    public XirOperand createTemp(String name, CiKind kind) {
+        assert !finished;
+        XirTemp temp = new XirTemp(this, name, kind, true);
+        temps.add(temp);
+        return temp;
+    }
+
+    public XirOperand createRegister(String name, CiKind kind, CiRegister register) {
+        return createRegister(name, kind, register, false);
+    }
+
+    public XirOperand createRegisterTemp(String name, CiKind kind, CiRegister register) {
+        return createRegister(name, kind, register, true);
+    }
+
+    private XirOperand createRegister(String name, CiKind kind, CiRegister register, boolean reserve) {
+        assert !finished;
+        XirRegister fixed = new XirRegister(this, name, register.asValue(kind), reserve);
+        temps.add(fixed);
+        return fixed;
+    }
+
+    public XirParameter getParameter(String name) {
+        for (XirParameter param : parameters) {
+            if (param.name.toString().equals(name)) {
+                return param;
+            }
+        }
+        throw new IllegalArgumentException("no parameter: " + name);
+    }
+
+    public XirTemp getTemp(String name) {
+        for (XirTemp temp : temps) {
+            if (temp.name.toString().equals(name)) {
+                return temp;
+            }
+        }
+        throw new IllegalArgumentException("no temp: " + name);
+    }
+
+    public XirConstant i(int v) {
+        return createConstant(CiConstant.forInt(v));
+    }
+
+    public XirConstant l(int v) {
+        return createConstant(CiConstant.forLong(v));
+    }
+
+    public XirConstant b(boolean v) {
+        return createConstant(CiConstant.forBoolean(v));
+    }
+
+    public XirConstant o(Object obj) {
+        return createConstant(CiConstant.forObject(obj));
+    }
+
+    public void reserveOutgoingStack(int size) {
+        outgoingStackSize = Math.max(outgoingStackSize, size);
+    }
+
+    /**
+     * Finishes the assembly of a non-stub template, providing the {@link #resultOperand} and constructs the {@link XirTemplate}.
+     * @param result the {@link XirOperand} to be set as the {@link #resultOperand}
+     * @param name the name of the template
+     * @return the generated template
+     */
+    public XirTemplate finishTemplate(XirOperand result, String name) {
+        assert this.resultOperand == null;
+        assert result != null;
+        this.resultOperand = result;
+        final XirTemplate template = buildTemplate(name, false);
+        end();
+        return template;
+    }
+
+    /**
+     * Finishes the assembly of a non-stub template and constructs the {@link XirTemplate}.
+     * @param name the name of the template
+     * @return the generated template
+     */
+    public XirTemplate finishTemplate(String name) {
+        final XirTemplate template = buildTemplate(name, false);
+        end();
+        return template;
+    }
+
+    /**
+     * Finishes the assembly of a {@link XirTemplate.GlobalFlags#GLOBAL_STUB stub} and constructs the {@link XirTemplate}.
+     * @param name the name of the template
+     * @return the generated template
+     */
+    public XirTemplate finishStub(String name) {
+        final XirTemplate template = buildTemplate(name, true);
+        end();
+        return template;
+    }
+
+    /**
+     * Builds the {@link XirTemplate} from the assembly state in this object.
+     * The actual assembly is dependent on the target architecture and implemented
+     * in a concrete subclass.
+     * @param name the name of the template
+     * @param isStub {@code true} if the template represents a {@link XirTemplate.GlobalFlags#GLOBAL_STUB stub}
+     * @return the generated template
+     */
+    protected abstract XirTemplate buildTemplate(String name, boolean isStub);
+
+    public abstract CiXirAssembler copy();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/RiXirGenerator.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.xir;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.cri.ri.RiType.Representation;
+
+/**
+ * Represents the interface through which the compiler requests the XIR for a given bytecode from the runtime system.
+ */
+public interface RiXirGenerator {
+
+    /**
+     * Note: may return {@code null}.
+     */
+    XirSnippet genPrologue(XirSite site, RiResolvedMethod method);
+
+    /**
+     * Note: may return {@code null} in which case the compiler will not emit a return instruction.
+     */
+    XirSnippet genEpilogue(XirSite site, RiResolvedMethod method);
+
+    XirSnippet genSafepointPoll(XirSite site);
+
+    XirSnippet genExceptionObject(XirSite site);
+
+    XirSnippet genResolveClass(XirSite site, RiType type, Representation representation);
+
+    XirSnippet genIntrinsic(XirSite site, XirArgument[] arguments, RiMethod method);
+
+    XirSnippet genInvokeInterface(XirSite site, XirArgument receiver, RiMethod method);
+
+    XirSnippet genInvokeVirtual(XirSite site, XirArgument receiver, RiMethod method);
+
+    XirSnippet genInvokeSpecial(XirSite site, XirArgument receiver, RiMethod method);
+
+    XirSnippet genInvokeStatic(XirSite site, RiMethod method);
+
+    XirSnippet genMonitorEnter(XirSite site, XirArgument receiver, XirArgument lockAddress);
+
+    XirSnippet genMonitorExit(XirSite site, XirArgument receiver, XirArgument lockAddress);
+
+    XirSnippet genGetField(XirSite site, XirArgument receiver, RiField field);
+
+    XirSnippet genPutField(XirSite site, XirArgument receiver, RiField field, XirArgument value);
+
+    XirSnippet genGetStatic(XirSite site, XirArgument staticTuple, RiField field);
+
+    XirSnippet genPutStatic(XirSite site, XirArgument staticTuple, RiField field, XirArgument value);
+
+    XirSnippet genNewInstance(XirSite site, RiType type);
+
+    XirSnippet genNewArray(XirSite site, XirArgument length, CiKind elementKind, RiType componentType, RiType arrayType);
+
+    XirSnippet genNewObjectArrayClone(XirSite site, XirArgument newLength, XirArgument referenceArray);
+
+    XirSnippet genNewMultiArray(XirSite site, XirArgument[] lengths, RiType type);
+
+    XirSnippet genCheckCast(XirSite site, XirArgument receiver, XirArgument hub, RiType type, RiResolvedType[] hints, boolean hintsExact);
+
+    XirSnippet genInstanceOf(XirSite site, XirArgument receiver, XirArgument hub, RiType type, RiResolvedType[] hints, boolean hintsExact);
+
+    XirSnippet genMaterializeInstanceOf(XirSite site, XirArgument receiver, XirArgument hub, XirArgument trueValue, XirArgument falseValue, RiType type, RiResolvedType[] hints, boolean hintsExact);
+
+    XirSnippet genArrayLoad(XirSite site, XirArgument array, XirArgument index, CiKind elementKind, RiType elementType);
+
+    XirSnippet genArrayStore(XirSite site, XirArgument array, XirArgument index, XirArgument value, CiKind elementKind, RiType elementType);
+
+    XirSnippet genArrayLength(XirSite site, XirArgument array);
+
+    XirSnippet genWriteBarrier(XirArgument object);
+
+    XirSnippet genArrayCopy(XirSite site, XirArgument src, XirArgument srcPos, XirArgument dest, XirArgument destPos, XirArgument length, RiType elementType, boolean inputsSame, boolean inputsDifferent);
+
+    XirSnippet genCurrentThread(XirSite site);
+
+    XirSnippet genGetClass(XirSite site, XirArgument xirArgument);
+
+    /**
+     * Generates code that checks that the {@linkplain Representation#ObjectHub hub} of
+     * an object is identical to a given hub constant. In pseudo code:
+     * <pre>
+     *     if (object.getHub() != hub) {
+     *       jump(falseSuccessor)
+     *     }
+     * </pre>
+     * This snippet should only be used when the object is guaranteed not to be null.
+     */
+    XirSnippet genTypeBranch(XirSite site, XirArgument thisHub, XirArgument otherHub, RiType type);
+
+    /**
+     * Initializes the XIR generator for the given XIR assembler.
+     *
+     * @param asm the XIR assembler
+     */
+    void initialize(CiXirAssembler asm);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/XirArgument.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.xir;
+
+import com.oracle.max.cri.ci.*;
+
+/**
+ * Represents an argument to an {@link XirSnippet}.
+ * Currently, this is a <i>union </i> type; it is either a {@link CiConstant} or an {@code Object}.
+ */
+public final class XirArgument {
+
+    public final CiConstant constant;
+    public final Object object;
+
+    private XirArgument(CiConstant value) {
+        this.constant = value;
+        this.object = null;
+    }
+
+    private XirArgument(Object o) {
+        this.constant = null;
+        this.object = o;
+    }
+
+    public static XirArgument forInternalObject(Object o) {
+        return new XirArgument(o);
+    }
+
+    public static XirArgument forInt(int x) {
+        return new XirArgument(CiConstant.forInt(x));
+    }
+
+    public static XirArgument forLong(long x) {
+        return new XirArgument(CiConstant.forLong(x));
+    }
+
+    public static XirArgument forObject(Object o) {
+        return new XirArgument(CiConstant.forObject(o));
+    }
+
+    @Override
+    public String toString() {
+        if (constant != null) {
+            return constant.toString();
+        } else {
+            return "" + object;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/XirSite.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.xir;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+
+/**
+ * Encapsulates the notion of a site where XIR can be supplied. It is supplied to the {@link RiXirGenerator} by the
+ * compiler for each place where XIR can be generated. This interface allows a number of queries, including the
+ * bytecode-level location and optimization hints computed by the compiler.
+ */
+public interface XirSite {
+
+    /**
+     * Gets the {@link CiCodePos code position} associated with this site. This is useful for inserting
+     * instrumentation at the XIR level.
+     * @return the code position if it is available; {@code null} otherwise
+     */
+    CiCodePos getCodePos();
+
+    /**
+     * Checks whether the specified argument is guaranteed to be non-null at this site.
+     * @param argument the argument
+     * @return {@code true} if the argument is non null at this site
+     */
+    boolean isNonNull(XirArgument argument);
+
+    /**
+     * Checks whether this site requires a null check.
+     * @return {@code true} if a null check is required
+     */
+    boolean requiresNullCheck();
+
+    /**
+     * Checks whether this site requires a range check.
+     * @return {@code true} if a range check is required
+     */
+    boolean requiresBoundsCheck();
+
+    /**
+     * Checks whether this site requires a read barrier.
+     * @return {@code true} if a read barrier is required
+     */
+    boolean requiresReadBarrier();
+
+    /**
+     * Checks whether this site requires a write barrier.
+     * @return {@code true} if a write barrier is required
+     */
+    boolean requiresWriteBarrier();
+
+    /**
+     * Checks whether this site requires an array store check.
+     * @return {@code true} if an array store check is required
+     */
+    boolean requiresArrayStoreCheck();
+
+    /**
+     * Checks whether an approximation of the type for the specified argument is available.
+     * @param argument the argument
+     * @return an {@link RiType} indicating the most specific type known for the argument, if any;
+     * {@code null} if no particular type is known
+     */
+    RiType getApproximateType(XirArgument argument);
+
+    /**
+     * Checks whether an exact type is known for the specified argument.
+     * @param argument the argument
+     * @return an {@link RiType} indicating the exact type known for the argument, if any;
+     * {@code null} if no particular type is known
+     */
+    RiType getExactType(XirArgument argument);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/XirSnippet.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.xir;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiTargetMethod.*;
+import com.oracle.max.cri.xir.CiXirAssembler.*;
+
+/**
+ * Represents a {@link XirTemplate template of XIR} along with the {@link XirArgument arguments} to be passed to the
+ * template. The runtime generates such snippets for each bytecode being compiled at the request of the compiler, and
+ * the compiler can generate machine code for the XIR snippet.
+ */
+public class XirSnippet {
+
+    public final XirArgument[] arguments;
+    public final XirTemplate template;
+    public final Map<XirMark, Mark> marks;
+
+    public XirSnippet(XirTemplate template, XirArgument... inputs) {
+        assert template != null;
+        this.template = template;
+        this.arguments = inputs;
+        this.marks = (template.marks != null && template.marks.length > 0) ? new HashMap<XirMark, Mark>() : null;
+        assert assertArgumentsCorrect();
+    }
+
+    private boolean assertArgumentsCorrect() {
+        int argLength = arguments == null ? 0 : arguments.length;
+        int paramLength = template.parameters == null ? 0 : template.parameters.length;
+        assert argLength == paramLength : "expected param count: " + paramLength + ", actual: " + argLength;
+        for (int i = 0; i < arguments.length; i++) {
+            assert assertArgumentCorrect(template.parameters[i], arguments[i]) : "mismatch in parameter " + i + ": " + arguments[i] + " instead of " + template.parameters[i];
+        }
+        return true;
+    }
+
+    private static boolean assertArgumentCorrect(XirParameter param, XirArgument arg) {
+        if (param.kind == CiKind.Illegal || param.kind == CiKind.Void) {
+            if (arg != null) {
+                return false;
+            }
+        } else {
+            if (arg == null) {
+                return false;
+            }
+            if (arg.constant != null) {
+                if (arg.constant.kind != param.kind) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(template.toString());
+        sb.append("(");
+        for (XirArgument a : arguments) {
+            sb.append(" ");
+            sb.append(a);
+        }
+
+        sb.append(" )");
+
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/XirTemplate.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2009, 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.max.cri.xir;
+
+import java.io.*;
+import java.util.*;
+
+import com.oracle.max.cri.xir.CiXirAssembler.*;
+
+/**
+ * Represents a completed template of XIR code that has been first assembled by
+ * the runtime, and then verified and preprocessed by the compiler. An {@code XirTemplate}
+ * instance is immutable.
+ */
+public class XirTemplate {
+
+    /**
+     * Flags that indicate key features of the template for quick checking.
+     */
+    public enum GlobalFlags {
+        /**
+         * Contains a call to a {@link GlobalFlags#GLOBAL_STUB} template.
+         */
+        HAS_STUB_CALL,
+
+        /**
+         * Contains a call to the runtime.
+         */
+        HAS_RUNTIME_CALL,
+
+        /**
+         * Not simply a linear sequence of instructions, contains control transfers.
+         */
+        HAS_CONTROL_FLOW,
+
+        /**
+         * Is a shared instruction sequence for use by other templates.
+         */
+        GLOBAL_STUB;
+
+        public final int mask = 1 << ordinal();
+    }
+
+    /**
+     * Name of the template.
+     */
+    public final String name;
+
+    public final XirOperand resultOperand;
+
+    /**
+     * The sequence of instructions for the fast (inline) path.
+     */
+    public final CiXirAssembler.XirInstruction[] fastPath;
+
+    /**
+     * The sequence of instructions for the slow (out of line) path.
+     */
+    public final CiXirAssembler.XirInstruction[] slowPath;
+
+    /**
+     * Labels used in control transfers.
+     */
+    public final XirLabel[] labels;
+
+    /**
+     * Parameters to the template.
+     */
+    public final XirParameter[] parameters;
+
+    /**
+     * An array of same length as {@link #parameters} where {@code parameterDestroyed[i]} is {@code true}
+     * iff {@code parameters[i]} is the {@link XirInstruction#result result} of any {@link XirInstruction} in either
+     * {@link #fastPath} or {@link #slowPath}.
+     */
+    public final boolean[] parameterDestroyed;
+
+    /**
+     * Temporary variables used by the template.
+     */
+    public final XirTemp[] temps;
+
+    /**
+     * Constants used in the template.
+     */
+    public final XirConstant[] constants;
+
+    /**
+     * The total number of variables. (relation to temps/parameters???)
+     */
+    public final int variableCount;
+
+    public final boolean allocateResultOperand;
+
+    public final XirMark[] marks;
+
+    public final int outgoingStackSize;
+
+    public final XirOperand[] inputOperands;
+    public final XirOperand[] inputTempOperands;
+    public final XirOperand[] tempOperands;
+
+
+    /**
+     * The {@link GlobalFlags} associated with the template.
+     */
+    public final int flags;
+
+    public XirTemplate(String name,
+                       int variableCount,
+                       boolean allocateResultOperand,
+                       XirOperand resultOperand,
+                       CiXirAssembler.XirInstruction[] fastPath,
+                       CiXirAssembler.XirInstruction[] slowPath,
+                       XirLabel[] labels,
+                       XirParameter[] parameters,
+                       XirTemp[] temps,
+                       XirConstant[] constantValues,
+                       int flags,
+                       XirMark[] marks,
+                       int outgoingStackSize) {
+        this.name = name;
+        this.variableCount = variableCount;
+        this.resultOperand = resultOperand;
+        this.fastPath = fastPath;
+        this.slowPath = slowPath;
+        this.labels = labels;
+        this.parameters = parameters;
+        this.flags = flags;
+        this.temps = temps;
+        this.allocateResultOperand = allocateResultOperand;
+        this.constants = constantValues;
+        this.marks = marks;
+        this.outgoingStackSize = outgoingStackSize;
+
+        assert fastPath != null;
+        assert labels != null;
+        assert parameters != null;
+
+        List<XirOperand> inputOperandList = new ArrayList<>(4);
+        List<XirOperand> inputTempOperandList = new ArrayList<>(4);
+        List<XirOperand> tempOperandList = new ArrayList<>(4);
+
+        parameterDestroyed = new boolean[parameters.length];
+        for (int i = 0; i < parameters.length; i++) {
+            for (XirInstruction ins : fastPath) {
+                if (ins.result == parameters[i]) {
+                    parameterDestroyed[i] = true;
+                    break;
+                }
+            }
+
+            if (slowPath != null && !parameterDestroyed[i]) {
+                for (XirInstruction ins : slowPath) {
+                    if (ins.result == parameters[i]) {
+                        parameterDestroyed[i] = true;
+                    }
+                }
+            }
+
+            if (parameterDestroyed[i]) {
+                inputTempOperandList.add(parameters[i]);
+            } else {
+                inputOperandList.add(parameters[i]);
+            }
+        }
+
+        for (XirTemp temp : temps) {
+            if (temp.reserve) {
+                tempOperandList.add(temp);
+            }
+        }
+
+        this.inputOperands = inputOperandList.toArray(new XirOperand[inputOperandList.size()]);
+        this.inputTempOperands = inputTempOperandList.toArray(new XirOperand[inputTempOperandList.size()]);
+        this.tempOperands = tempOperandList.toArray(new XirOperand[tempOperandList.size()]);
+    }
+
+    /**
+     * Convenience getter that returns the value at a given index in the {@link #parameterDestroyed} array.
+     * @param index
+     * @return the value at {@code parameterDestroyed[index]}
+     */
+    public boolean isParameterDestroyed(int index) {
+        return parameterDestroyed[index];
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    public void print(PrintStream p) {
+        final String indent = "   ";
+
+        p.println();
+        p.println("Template " + name);
+
+        p.print("Param:");
+        for (XirParameter param : parameters) {
+            p.print(" " + param.detailedToString());
+        }
+        p.println();
+
+        if (temps.length > 0) {
+            p.print("Temps:");
+            for (XirTemp temp : temps) {
+                p.print(" " + temp.detailedToString());
+            }
+            p.println();
+        }
+
+        if (constants.length > 0) {
+            p.print("Constants:");
+            for (XirConstant c : constants) {
+                p.print(" " + c.detailedToString());
+            }
+            p.println();
+        }
+
+        if (flags != 0) {
+            p.print("Flags:");
+            for (XirTemplate.GlobalFlags flag : XirTemplate.GlobalFlags.values()) {
+                if ((this.flags & flag.mask) != 0) {
+                    p.print(" " + flag.name());
+                }
+            }
+            p.println();
+        }
+
+        p.println("Fast path:");
+        for (XirInstruction i : fastPath) {
+            p.println(indent + i.toString());
+        }
+
+        if (slowPath != null) {
+            p.println("Slow path:");
+            for (XirInstruction i : slowPath) {
+                p.println(indent + i.toString());
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/package-info.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+/**
+ * XIR defines a domain specific instruction set for expressing the lowering of bytecode operations. The details of the
+ * lowering operations are entirely encapsulated in the runtime and are provided to the compiler on request using
+ * {@link com.oracle.max.cri.xir.XirSnippet XIR snippets}. A snippet is a combination of a {@link com.oracle.max.cri.xir.XirTemplate
+ * template}, which is a sequence of {@link com.oracle.max.cri.xir.CiXirAssembler.XirInstruction XIR instructions} that has
+ * unbound {@link com.oracle.max.cri.xir.CiXirAssembler.XirParameter parameters}, and site-specific
+ * {@link com.oracle.max.cri.xir.XirArgument arguments} that are bound to the parameters.
+ * <p>
+ * The runtime is responsible for creating the {@link com.oracle.max.cri.xir.XirTemplate templates} and provides these to the
+ * compiler as part of the initialization process.
+ * <p>
+ * The XIR instruction set has no textual representation, and therefore no parser. An assembly is represented by an
+ * instance of {@link com.oracle.max.cri.xir.CiXirAssembler}, which provides methods to create instructions and operands.
+ */
+package com.oracle.max.cri.xir;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/BaseUnresolvedField.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, 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.max.criutils;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+
+/**
+ * A implementation of {@link RiField} for an unresolved field.
+ */
+public class BaseUnresolvedField implements RiField {
+
+    public final String name;
+    public final RiType holder;
+    public final RiType type;
+
+    public BaseUnresolvedField(RiType holder, String name, RiType type) {
+        this.name = name;
+        this.type = type;
+        this.holder = holder;
+    }
+
+    public String name() {
+        return name;
+    }
+
+    public RiType type() {
+        return type;
+    }
+
+    public CiKind kind(boolean architecture) {
+        return type.kind(architecture);
+    }
+
+    public RiType holder() {
+        return holder;
+    }
+
+    @Override
+    public int hashCode() {
+        return System.identityHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return o == this;
+    }
+
+    /**
+     * Converts this compiler interface field to a string.
+     */
+    @Override
+    public String toString() {
+        return CiUtil.format("%H.%n [unresolved]", this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/BaseUnresolvedMethod.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009, 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.max.criutils;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+
+/**
+ * A implementation of {@link RiMethod} for an unresolved method.
+ */
+public class BaseUnresolvedMethod implements RiMethod {
+
+    public final String name;
+    public final RiType holder;
+    public final RiSignature signature;
+
+    public BaseUnresolvedMethod(RiType holder, String name, RiSignature signature) {
+        this.name = name;
+        this.holder = holder;
+        this.signature = signature;
+    }
+
+    public String name() {
+        return name;
+    }
+
+    public RiType holder() {
+        return holder;
+    }
+
+    public RiSignature signature() {
+        return signature;
+    }
+
+    @Override
+    public int hashCode() {
+        return System.identityHashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return o == this;
+    }
+
+    @Override
+    public String toString() {
+        return CiUtil.format("%H.%n(%p) [unresolved]", this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/CompilationPrinter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2011, 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.max.criutils;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.io.*;
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+
+/**
+ * Utility for printing compilation related data structures at various compilation phases.
+ * The output format is such that it can then be fed to the
+ * <a href="https://c1visualizer.dev.java.net/">C1 Visualizer</a>.
+ */
+public class CompilationPrinter {
+    public static final String COLUMN_END = " <|@";
+    public static final String HOVER_START = "<@";
+    public static final String HOVER_SEP = "|@";
+    public static final String HOVER_END = ">@";
+
+    private static OutputStream globalOut;
+
+    /**
+     * Gets a global output stream on a file in the current working directory.
+     * This stream is first opened if necessary. The name of the file
+     * is {@code "compilations-" + System.currentTimeMillis() + ".cfg"}.
+     *
+     * @return the global output stream or {@code null} if there was an error opening the file for writing
+     */
+    public static synchronized OutputStream globalOut() {
+        if (globalOut == null) {
+            File file = new File("compilations-" + System.currentTimeMillis() + ".cfg");
+            try {
+                globalOut = new FileOutputStream(file);
+            } catch (FileNotFoundException e) {
+                TTY.println("WARNING: Could not open " + file.getAbsolutePath());
+            }
+        }
+        return globalOut;
+    }
+
+    protected final LogStream out;
+
+    /**
+     * Creates a control flow graph printer.
+     *
+     * @param os where the output generated via this printer will be sent
+     */
+    public CompilationPrinter(OutputStream os) {
+        out = new LogStream(os);
+    }
+
+    /**
+     * Flushes all buffered output to the underlying output stream.
+     */
+    public void flush() {
+        out.flush();
+    }
+
+    protected void begin(String string) {
+        out.println("begin_" + string);
+        out.adjustIndentation(2);
+    }
+
+    protected void end(String string) {
+        out.adjustIndentation(-2);
+        out.println("end_" + string);
+    }
+
+    /**
+     * Prints a compilation timestamp for a given method.
+     *
+     * @param method the method for which a timestamp will be printed
+     */
+    public void printCompilation(RiMethod method) {
+        begin("compilation");
+        out.print("name \" ").print(CiUtil.format("%H::%n", method)).println('"');
+        out.print("method \"").print(CiUtil.format("%f %r %H.%n(%p)", method)).println('"');
+        out.print("date ").println(System.currentTimeMillis());
+        end("compilation");
+    }
+
+    /**
+     * Formats a given {@linkplain FrameState JVM frame state} as a multi line string.
+     */
+    protected String debugInfoToString(CiCodePos codePos, CiBitMap registerRefMap, CiBitMap frameRefMap, CiArchitecture arch) {
+        StringBuilder sb = new StringBuilder();
+
+        if (registerRefMap != null) {
+            sb.append("reg-ref-map:");
+            for (int reg = registerRefMap.nextSetBit(0); reg >= 0; reg = registerRefMap.nextSetBit(reg + 1)) {
+                sb.append(' ').append(arch == null ? "r" + reg : arch.registers[reg]);
+            }
+            sb.append("\n");
+        }
+
+        if (frameRefMap != null) {
+            sb.append("frame-ref-map:");
+            for (int reg = frameRefMap.nextSetBit(0); reg >= 0; reg = frameRefMap.nextSetBit(reg + 1)) {
+                sb.append(' ').append("s").append(reg);
+            }
+            sb.append("\n");
+        }
+
+        if (codePos != null) {
+            CiCodePos curCodePos = codePos;
+            List<CiVirtualObject> virtualObjects = new ArrayList<>();
+            do {
+                sb.append(CiUtil.toLocation(curCodePos.method, curCodePos.bci));
+                sb.append('\n');
+                if (curCodePos instanceof CiFrame) {
+                    CiFrame frame = (CiFrame) curCodePos;
+                    if (frame.numStack > 0) {
+                        sb.append("stack: ");
+                        for (int i = 0; i < frame.numStack; i++) {
+                            sb.append(valueToString(frame.getStackValue(i), virtualObjects)).append(' ');
+                        }
+                        sb.append("\n");
+                    }
+                    sb.append("locals: ");
+                    for (int i = 0; i < frame.numLocals; i++) {
+                        sb.append(valueToString(frame.getLocalValue(i), virtualObjects)).append(' ');
+                    }
+                    sb.append("\n");
+                    if (frame.numLocks > 0) {
+                        sb.append("locks: ");
+                        for (int i = 0; i < frame.numLocks; ++i) {
+                            sb.append(valueToString(frame.getLockValue(i), virtualObjects)).append(' ');
+                        }
+                        sb.append("\n");
+                    }
+
+                }
+                curCodePos = curCodePos.caller;
+            } while (curCodePos != null);
+
+            for (int i = 0; i < virtualObjects.size(); i++) {
+                CiVirtualObject obj = virtualObjects.get(i);
+                sb.append(obj).append(" ").append(obj.type().name()).append(" ");
+                for (int j = 0; j < obj.values().length; j++) {
+                    sb.append(valueToString(obj.values()[j], virtualObjects)).append(' ');
+                }
+                sb.append("\n");
+
+            }
+        }
+        return sb.toString();
+    }
+
+    protected String valueToString(CiValue value, List<CiVirtualObject> virtualObjects) {
+        if (value == null) {
+            return "-";
+        }
+        if (isVirtualObject(value) && !virtualObjects.contains(asVirtualObject(value))) {
+            virtualObjects.add(asVirtualObject(value));
+        }
+        return value.toString();
+    }
+
+    public void printMachineCode(String code, String label) {
+        if (code.length() == 0) {
+            return;
+        }
+        if (label != null) {
+            begin("cfg");
+            out.print("name \"").print(label).println('"');
+            end("cfg");
+        }
+        begin("nmethod");
+        out.print(code);
+        out.println(" <|@");
+        end("nmethod");
+    }
+
+    public void printBytecodes(String code) {
+        if (code.length() == 0) {
+            return;
+        }
+        begin("bytecodes");
+        out.print(code);
+        out.println(" <|@");
+        end("bytecodes");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/HexCodeFile.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2009, 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.max.criutils;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.regex.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiTargetMethod.*;
+
+
+/**
+ * A HexCodeFile is a textual format for representing a chunk of machine code along
+ * with extra information that can be used to enhance a disassembly of the code.
+ *
+ * A pseudo grammar for a HexCodeFile is given below.
+ * <pre>
+ *     HexCodeFile ::= Platform Delim HexCode Delim (OptionalSection Delim)*
+ *
+ *     OptionalSection ::= Comment | OperandComment | JumpTable | LookupTable
+ *
+ *     Platform ::= "Platform" ISA WordWidth
+ *
+ *     HexCode ::= "HexCode" StartAddress HexDigits
+ *
+ *     Comment ::= "Comment" Position String
+ *
+ *     OperandComment ::= "OperandComment" Position String
+ *
+ *     JumpTable ::= "JumpTable" Position EntrySize Low High
+ *
+ *     LookupTable ::= "LookupTable" Position NPairs KeySize OffsetSize
+ *
+ *     Position, EntrySize, Low, High, NPairs KeySize OffsetSize ::= int
+ *
+ *     Delim := "<||@"
+ * </pre>
+ *
+ * There must be exactly one HexCode and Platform part in a HexCodeFile. The length of HexDigits must be even
+ * as each pair of digits represents a single byte.
+ * <p>
+ * Below is an example of a valid Code input:
+ * <pre>
+ *
+ *  Platform AMD64 64  <||@
+ *  HexCode 0 e8000000009090904883ec084889842410d0ffff48893c24e800000000488b3c24488bf0e8000000004883c408c3  <||@
+ *  Comment 24 frame-ref-map: +0 {0}
+ *  at java.lang.String.toLowerCase(String.java:2496) [bci: 1]
+ *              |0
+ *     locals:  |stack:0:a
+ *     stack:   |stack:0:a
+ *    <||@
+ *  OperandComment 24 {java.util.Locale.getDefault()}  <||@
+ *  Comment 36 frame-ref-map: +0 {0}
+ *  at java.lang.String.toLowerCase(String.java:2496) [bci: 4]
+ *              |0
+ *     locals:  |stack:0:a
+ *    <||@
+ *  OperandComment 36 {java.lang.String.toLowerCase(Locale)}  <||@
+ *
+ * </pre>
+ */
+public class HexCodeFile {
+
+    public static final String NEW_LINE = CiUtil.NEW_LINE;
+    public static final String SECTION_DELIM = " <||@";
+    public static final Pattern SECTION = Pattern.compile("(\\S+)\\s+(.*)", Pattern.DOTALL);
+    public static final Pattern COMMENT = Pattern.compile("(\\d+)\\s+(.*)", Pattern.DOTALL);
+    public static final Pattern OPERAND_COMMENT = COMMENT;
+    public static final Pattern JUMP_TABLE = Pattern.compile("(\\d+)\\s+(\\d+)\\s+(-{0,1}\\d+)\\s+(-{0,1}\\d+)\\s*");
+    public static final Pattern LOOKUP_TABLE = Pattern.compile("(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s*");
+    public static final Pattern HEX_CODE = Pattern.compile("(\\p{XDigit}+)(?:\\s+(\\p{XDigit}*))?");
+    public static final Pattern PLATFORM = Pattern.compile("(\\S+)\\s+(\\S+)", Pattern.DOTALL);
+
+    /**
+     * Delimiter placed before a HexCodeFile when embedded in a string/stream.
+     */
+    public static final String EMBEDDED_HCF_OPEN = "<<<HexCodeFile";
+
+    /**
+     * Delimiter placed after a HexCodeFile when embedded in a string/stream.
+     */
+    public static final String EMBEDDED_HCF_CLOSE = "HexCodeFile>>>";
+
+    /**
+     * Map from a machine code position to a list of comments for the position.
+     */
+    public final Map<Integer, List<String>> comments = new TreeMap<>();
+
+    /**
+     * Map from a machine code position to a comment for the operands of the instruction at the position.
+     */
+    public final Map<Integer, String> operandComments = new TreeMap<>();
+
+    public final byte[] code;
+
+    public final ArrayList<JumpTable> jumpTables = new ArrayList<>();
+
+    public final ArrayList<LookupTable> lookupTables = new ArrayList<>();
+
+    public final String isa;
+
+    public final int wordWidth;
+
+    public final long startAddress;
+
+    public HexCodeFile(byte[] code, long startAddress, String isa, int wordWidth) {
+        this.code = code;
+        this.startAddress = startAddress;
+        this.isa = isa;
+        this.wordWidth = wordWidth;
+    }
+
+    /**
+     * Parses a string in the format produced by {@link #toString()} to produce a {@link HexCodeFile} object.
+     */
+    public static HexCodeFile parse(String source, String sourceName) {
+        return new Parser(source, sourceName).hcf;
+    }
+
+    /**
+     * Formats this HexCodeFile as a string that can be parsed with {@link #parse(String, String)}.
+     */
+    @Override
+    public String toString() {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        writeTo(baos);
+        return baos.toString();
+    }
+
+    public String toEmbeddedString() {
+        return EMBEDDED_HCF_OPEN + NEW_LINE + toString() + EMBEDDED_HCF_CLOSE;
+    }
+
+    public void writeTo(OutputStream out) {
+        PrintStream ps = out instanceof PrintStream ? (PrintStream) out : new PrintStream(out);
+        ps.printf("Platform %s %d %s%n",  isa, wordWidth, SECTION_DELIM);
+        ps.printf("HexCode %x %s %s%n", startAddress, HexCodeFile.hexCodeString(code), SECTION_DELIM);
+
+        for (JumpTable table : jumpTables) {
+            ps.printf("JumpTable %d %d %d %d %s%n", table.position, table.entrySize, table.low, table.high, SECTION_DELIM);
+        }
+
+        for (LookupTable table : lookupTables) {
+            ps.printf("LookupTable %d %d %d %d %s%n", table.position, table.npairs, table.keySize, table.keySize, SECTION_DELIM);
+        }
+
+        for (Map.Entry<Integer, List<String>> e : comments.entrySet()) {
+            int pos = e.getKey();
+            for (String comment : e.getValue()) {
+                ps.printf("Comment %d %s %s%n", pos, comment, SECTION_DELIM);
+            }
+        }
+
+        for (Map.Entry<Integer, String> e : operandComments.entrySet()) {
+            ps.printf("OperandComment %d %s %s%n", e.getKey(), e.getValue(), SECTION_DELIM);
+        }
+        ps.flush();
+    }
+
+
+    /**
+     * Formats a byte array as a string of hex digits.
+     */
+    public static String hexCodeString(byte[] code) {
+        StringBuilder sb = new StringBuilder(code.length * 2);
+        for (int b : code) {
+            String hex = Integer.toHexString(b & 0xff);
+            if (hex.length() == 1) {
+                sb.append('0');
+            }
+            sb.append(hex);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Adds a comment to the list of comments for a given position.
+     */
+    public void addComment(int pos, String comment) {
+        List<String> list = comments.get(pos);
+        if (list == null) {
+            list = new ArrayList<>();
+            comments.put(pos, list);
+        }
+        list.add(encodeString(comment));
+    }
+
+    /**
+     * Sets an operand comment for a given position.
+     *
+     * @return the previous operand comment for {@code pos}
+     */
+    public String addOperandComment(int pos, String comment) {
+        return operandComments.put(pos, encodeString(comment));
+    }
+
+    /**
+     * Adds any jump tables, lookup tables or code comments from a list of code annotations.
+     */
+    public static void addAnnotations(HexCodeFile hcf, List<CodeAnnotation> annotations) {
+        if (annotations == null || annotations.isEmpty()) {
+            return;
+        }
+        for (CodeAnnotation a : annotations) {
+            if (a instanceof JumpTable) {
+                JumpTable table = (JumpTable) a;
+                hcf.jumpTables.add(table);
+            } else if (a instanceof LookupTable) {
+                LookupTable table = (LookupTable) a;
+                hcf.lookupTables.add(table);
+            } else if (a instanceof CodeComment) {
+                CodeComment comment = (CodeComment) a;
+                hcf.addComment(comment.position, comment.value);
+            }
+        }
+    }
+
+    /**
+     * Modifies a string to mangle any substrings matching {@link #SECTION_DELIM}.
+     */
+    public static String encodeString(String s) {
+        int index;
+        String result = s;
+        while ((index = result.indexOf(SECTION_DELIM)) != -1) {
+            result = result.substring(0, index) + " < |@" + result.substring(index + SECTION_DELIM.length());
+        }
+        return result;
+    }
+
+    /**
+     * Helper class to parse a string in the format produced by {@link HexCodeFile#toString()}
+     * and produce a {@link HexCodeFile} object.
+     */
+    static class Parser {
+        private static final Field offsetField = stringField("offset");
+        private static final Field valueField = stringField("value");
+
+        static Field stringField(String name) {
+            try {
+                Field field = String.class.getDeclaredField(name);
+                field.setAccessible(true);
+                return field;
+            } catch (Exception e) {
+                throw new Error("Could not get reflective access to field " + String.class.getName() + "." + name);
+            }
+        }
+
+        final String input;
+        final String inputSource;
+        String isa;
+        int wordWidth;
+        byte[] code;
+        long startAddress;
+        HexCodeFile hcf;
+
+        Parser(String source, String sourceName) {
+            this.input = storage(source);
+            this.inputSource = sourceName;
+            parseSections(source);
+        }
+
+        void makeHCF() {
+            if (hcf == null) {
+                if (isa != null && wordWidth != 0 && code != null) {
+                    hcf = new HexCodeFile(code, startAddress, isa, wordWidth);
+                }
+            }
+        }
+
+        void checkHCF(String section, String where) {
+            check(hcf != null, where, section + " section must be after Platform and HexCode section");
+        }
+
+        void check(boolean condition, String where, String message) {
+            if (!condition) {
+                error(where, message);
+            }
+        }
+
+        int offset(String s) {
+            try {
+                return offsetField.getInt(s);
+            } catch (Exception e) {
+                throw new Error("Could not read value of field " + offsetField, e);
+            }
+        }
+
+        /**
+         * Gets a string corresponding to the storage char array for a given string.
+         */
+        String storage(String s) {
+            try {
+                char[] value = (char[]) valueField.get(s);
+                if (offset(s) == 0 && value.length == s.length()) {
+                    return s;
+                }
+                return new String(value);
+            } catch (Exception e) {
+                throw new Error("Could not read value of field " + valueField, e);
+            }
+        }
+
+        Error error(String where, String message) {
+            return error(offset(where), message);
+        }
+
+        Error error(int offset, String message) {
+            throw new Error(errorMessage(offset, message));
+        }
+
+        void warning(String where, String message) {
+            System.err.println("Warning: " + errorMessage(offset(where), message));
+        }
+
+        String errorMessage(int offset, String message) {
+            assert offset < input.length();
+            InputPos inputPos = filePos(offset);
+            int lineEnd = input.indexOf(HexCodeFile.NEW_LINE, offset);
+            int lineStart = offset - inputPos.col;
+            String line = lineEnd == -1 ? input.substring(lineStart) : input.substring(lineStart, lineEnd);
+            return String.format("%s:%d: %s%n%s%n%" + (inputPos.col + 1) + "s", inputSource, inputPos.line, message, line, "^");
+        }
+
+        static class InputPos {
+            final int line;
+            final int col;
+            public InputPos(int line, int col) {
+                this.line = line;
+                this.col = col;
+            }
+        }
+
+        InputPos filePos(int index) {
+            assert input != null;
+            int line = 1;
+            int lineEnd = 0;
+            int lineStart = 0;
+            while ((lineEnd = input.indexOf(HexCodeFile.NEW_LINE, lineStart)) != -1) {
+                if (lineEnd < index) {
+                    line++;
+                    lineStart = lineEnd + HexCodeFile.NEW_LINE.length();
+                } else {
+                    break;
+                }
+            }
+            return new InputPos(line, index - lineStart);
+        }
+
+        void parseSections(String source) {
+            int index = 0;
+            int endIndex = source.indexOf(SECTION_DELIM);
+            while (endIndex != -1) {
+                String section = source.substring(index, endIndex).trim();
+                parseSection(section);
+                index = endIndex + SECTION_DELIM.length();
+                endIndex = source.indexOf(SECTION_DELIM, index);
+            }
+        }
+
+        int parseInt(String value) {
+            try {
+                return Integer.parseInt(value);
+            } catch (NumberFormatException e) {
+                throw error(value, "Not a valid integer: " + value);
+            }
+        }
+
+        void parseSection(String section) {
+            if (section.isEmpty()) {
+                return;
+            }
+            Matcher m = HexCodeFile.SECTION.matcher(section);
+            check(m.matches(), section, "Section does not match pattern " + HexCodeFile.SECTION);
+
+            String header = m.group(1);
+            String body = m.group(2);
+
+            if (header.equals("Platform")) {
+                check(isa == null, body, "Duplicate Platform section found");
+                m = HexCodeFile.PLATFORM.matcher(body);
+                check(m.matches(), body, "Platform does not match pattern " + HexCodeFile.PLATFORM);
+                isa = m.group(1);
+                wordWidth = parseInt(m.group(2));
+                makeHCF();
+            } else if (header.equals("HexCode")) {
+                check(code == null, body, "Duplicate Code section found");
+                m = HexCodeFile.HEX_CODE.matcher(body);
+                check(m.matches(), body, "Code does not match pattern " + HexCodeFile.HEX_CODE);
+                String hexAddress = m.group(1);
+                startAddress = Long.valueOf(hexAddress, 16);
+                String hexCode = m.group(2);
+                if (hexCode == null) {
+                    code = new byte[0];
+                } else {
+                    check((hexCode.length() % 2) == 0, body, "Hex code length must be even");
+                    code = new byte[hexCode.length() / 2];
+                    for (int i = 0; i < code.length; i++) {
+                        String hexByte = hexCode.substring(i * 2, (i + 1) * 2);
+                        code[i] = (byte) Integer.parseInt(hexByte, 16);
+                    }
+                }
+                makeHCF();
+            } else if (header.equals("Comment")) {
+                checkHCF("Comment", header);
+                m = HexCodeFile.COMMENT.matcher(body);
+                check(m.matches(), body, "Comment does not match pattern " + HexCodeFile.COMMENT);
+                int pos = parseInt(m.group(1));
+                String comment = m.group(2);
+                hcf.addComment(pos, comment);
+            } else if (header.equals("OperandComment")) {
+                checkHCF("OperandComment", header);
+                m = HexCodeFile.OPERAND_COMMENT.matcher(body);
+                check(m.matches(), body, "OperandComment does not match pattern " + HexCodeFile.OPERAND_COMMENT);
+                int pos = parseInt(m.group(1));
+                String comment = m.group(2);
+                hcf.addOperandComment(pos, comment);
+            } else if (header.equals("JumpTable")) {
+                checkHCF("JumpTable", header);
+                m = HexCodeFile.JUMP_TABLE.matcher(body);
+                check(m.matches(), body, "JumpTable does not match pattern " + HexCodeFile.JUMP_TABLE);
+                int pos = parseInt(m.group(1));
+                int entrySize = parseInt(m.group(2));
+                int low = parseInt(m.group(3));
+                int high = parseInt(m.group(4));
+                hcf.jumpTables.add(new JumpTable(pos, low, high, entrySize));
+            } else if (header.equals("LookupTable")) {
+                checkHCF("LookupTable", header);
+                m = HexCodeFile.LOOKUP_TABLE.matcher(body);
+                check(m.matches(), body, "LookupTable does not match pattern " + HexCodeFile.LOOKUP_TABLE);
+                int pos = parseInt(m.group(1));
+                int npairs = parseInt(m.group(2));
+                int keySize = parseInt(m.group(3));
+                int offsetSize = parseInt(m.group(4));
+                hcf.lookupTables.add(new LookupTable(pos, npairs, keySize, offsetSize));
+            } else {
+                error(section, "Unknown section header: " + header);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/LogStream.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,469 @@
+/*
+ * Copyright (c) 2009, 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.max.criutils;
+
+import java.io.*;
+
+/**
+ * A utility for printing compiler debug and informational output to an output stream.
+ *
+ * A {@link LogStream} instance maintains an internal buffer that is flushed to the underlying
+ * output stream every time one of the {@code println} methods is invoked, or a newline character
+ * ({@code '\n'}) is written.
+ *
+ * All of the {@code print} and {@code println} methods return the {code LogStream} instance
+ * on which they were invoked. This allows chaining of these calls to mitigate use of String
+ * concatenation by the caller.
+ *
+ * A {@code LogStream} maintains a current {@linkplain #indentationLevel() indentation} level.
+ * Each line of output written to this stream has {@code n} spaces prefixed to it where
+ * {@code n} is the value that would be returned by {@link #indentationLevel()} when the first
+ * character of a new line is written.
+ *
+ * A {@code LogStream} maintains a current {@linkplain #position() position} for the current
+ * line being written. This position can be advanced to a specified position by
+ * {@linkplain #fillTo(int, char) filling} this stream with a given character.
+ */
+public class LogStream {
+
+    /**
+     * Null output stream that simply swallows any output sent to it.
+     */
+    public static final LogStream SINK = new LogStream();
+
+    private static final PrintStream SINK_PS = new PrintStream(new OutputStream() {
+        @Override
+        public void write(int b) throws IOException { }
+    });
+
+    private LogStream() {
+        this.ps = null;
+        this.lineBuffer = null;
+    }
+
+    /**
+     * The output stream to which this log stream writes.
+     */
+    private final PrintStream ps;
+
+    private final StringBuilder lineBuffer;
+    private int indentationLevel;
+    private char indentation = ' ';
+    private boolean indentationDisabled;
+
+    public final PrintStream out() {
+        if (ps == null) {
+            return SINK_PS;
+        }
+        return ps;
+    }
+
+    /**
+     * The system dependent line separator.
+     */
+    public static final String LINE_SEPARATOR = System.getProperty("line.separator");
+
+    /**
+     * Creates a new log stream.
+     *
+     * @param os the underlying output stream to which prints are sent
+     */
+    public LogStream(OutputStream os) {
+        ps = os instanceof PrintStream ? (PrintStream) os : new PrintStream(os);
+        lineBuffer = new StringBuilder(100);
+    }
+
+    /**
+     * Creates a new log stream that shares the same {@linkplain #ps output stream} as a given {@link LogStream}.
+     *
+     * @param log a LogStream whose output stream is shared with this one
+     */
+    public LogStream(LogStream log) {
+        ps = log.ps;
+        lineBuffer = new StringBuilder(100);
+    }
+
+    /**
+     * Prepends {@link #indentation} to the current output line until its write position is equal to the
+     * current {@linkplain #indentationLevel()} level.
+     */
+    private void indent() {
+        if (ps != null) {
+            if (!indentationDisabled && indentationLevel != 0) {
+                while (lineBuffer.length() < indentationLevel) {
+                    lineBuffer.append(indentation);
+                }
+            }
+        }
+    }
+
+    private LogStream flushLine(boolean withNewline) {
+        if (ps != null) {
+            if (withNewline) {
+                lineBuffer.append(LINE_SEPARATOR);
+            }
+            ps.print(lineBuffer.toString());
+            ps.flush();
+            lineBuffer.setLength(0);
+        }
+        return this;
+    }
+
+    /**
+     * Flushes the stream. This is done by terminating the current line if it is not at position 0
+     * and then flushing the underlying output stream.
+     */
+    public void flush() {
+        if (ps != null) {
+            if (lineBuffer.length() != 0) {
+                flushLine(false);
+            }
+            ps.flush();
+        }
+    }
+
+    /**
+     * Gets the current column position of this log stream.
+     *
+     * @return the current column position of this log stream
+     */
+    public int position() {
+        return lineBuffer == null ? 0 : lineBuffer.length();
+
+    }
+
+    /**
+     * Gets the current indentation level for this log stream.
+     *
+     * @return the current indentation level for this log stream.
+     */
+    public int indentationLevel() {
+        return indentationLevel;
+    }
+
+    /**
+     * Adjusts the current indentation level of this log stream.
+     *
+     * @param delta
+     */
+    public void adjustIndentation(int delta) {
+        if (delta < 0) {
+            indentationLevel = Math.max(0, indentationLevel + delta);
+        } else {
+            indentationLevel += delta;
+        }
+    }
+
+    /**
+     * Gets the current indentation character of this log stream.
+     */
+    public char indentation() {
+        return indentation;
+    }
+
+    public void disableIndentation() {
+        indentationDisabled = true;
+    }
+
+    public void enableIndentation() {
+        indentationDisabled = false;
+    }
+
+    /**
+     * Sets the character used for indentation.
+     */
+    public void setIndentation(char c) {
+        indentation = c;
+    }
+
+    /**
+     * Advances this stream's {@linkplain #position() position} to a given position by
+     * repeatedly appending a given character as necessary.
+     *
+     * @param position the position to which this stream's position will be advanced
+     * @param filler the character used to pad the stream
+     */
+    public LogStream fillTo(int position, char filler) {
+        if (ps != null) {
+            indent();
+            while (lineBuffer.length() < position) {
+                lineBuffer.append(filler);
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Writes a boolean value to this stream as {@code "true"} or {@code "false"}.
+     *
+     * @param b the value to be printed
+     * @return this {@link LogStream} instance
+     */
+    public LogStream print(boolean b) {
+        if (ps != null) {
+            indent();
+            lineBuffer.append(b);
+        }
+        return this;
+    }
+
+    /**
+     * Writes a boolean value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}.
+     *
+     * @param b the value to be printed
+     * @return this {@link LogStream} instance
+     */
+    public LogStream println(boolean b) {
+        if (ps != null) {
+            indent();
+            lineBuffer.append(b);
+            return flushLine(true);
+        }
+        return this;
+    }
+
+    /**
+     * Writes a character value to this stream.
+     *
+     * @param c the value to be printed
+     * @return this {@link LogStream} instance
+     */
+    public LogStream print(char c) {
+        if (ps != null) {
+            indent();
+            lineBuffer.append(c);
+            if (c == '\n') {
+                if (lineBuffer.indexOf(LINE_SEPARATOR, lineBuffer.length() - LINE_SEPARATOR.length()) != -1) {
+                    flushLine(false);
+                }
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Writes a character value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}.
+     *
+     * @param c the value to be printed
+     * @return this {@link LogStream} instance
+     */
+    public LogStream println(char c) {
+        if (ps != null) {
+            indent();
+            lineBuffer.append(c);
+            flushLine(true);
+        }
+        return this;
+    }
+
+    /**
+     * Prints an int value.
+     *
+     * @param i the value to be printed
+     * @return this {@link LogStream} instance
+     */
+    public LogStream print(int i) {
+        if (ps != null) {
+            indent();
+            lineBuffer.append(i);
+        }
+        return this;
+    }
+
+    /**
+     * Writes an int value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}.
+     *
+     * @param i the value to be printed
+     * @return this {@link LogStream} instance
+     */
+    public LogStream println(int i) {
+        if (ps != null) {
+            indent();
+            lineBuffer.append(i);
+            return flushLine(true);
+        }
+        return this;
+    }
+
+    /**
+     * Writes a float value to this stream.
+     *
+     * @param f the value to be printed
+     * @return this {@link LogStream} instance
+     */
+    public LogStream print(float f) {
+        if (ps != null) {
+            indent();
+            lineBuffer.append(f);
+        }
+        return this;
+    }
+
+    /**
+     * Writes a float value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}.
+     *
+     * @param f the value to be printed
+     * @return this {@link LogStream} instance
+     */
+    public LogStream println(float f) {
+        if (ps != null) {
+            indent();
+            lineBuffer.append(f);
+            return flushLine(true);
+        }
+        return this;
+    }
+
+    /**
+     * Writes a long value to this stream.
+     *
+     * @param l the value to be printed
+     * @return this {@link LogStream} instance
+     */
+    public LogStream print(long l) {
+        if (ps != null) {
+            indent();
+            lineBuffer.append(l);
+        }
+        return this;
+    }
+
+    /**
+     * Writes a long value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}.
+     *
+     * @param l the value to be printed
+     * @return this {@link LogStream} instance
+     */
+    public LogStream println(long l) {
+        if (ps != null) {
+            indent();
+            lineBuffer.append(l);
+            return flushLine(true);
+        }
+        return this;
+    }
+
+    /**
+     * Writes a double value to this stream.
+     *
+     * @param d the value to be printed
+     * @return this {@link LogStream} instance
+     */
+    public LogStream print(double d) {
+        if (ps != null) {
+            indent();
+            lineBuffer.append(d);
+        }
+        return this;
+    }
+
+    /**
+     * Writes a double value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}.
+     *
+     * @param d the value to be printed
+     * @return this {@link LogStream} instance
+     */
+    public LogStream println(double d) {
+        if (ps != null) {
+            indent();
+            lineBuffer.append(d);
+            return flushLine(true);
+        }
+        return this;
+    }
+
+    /**
+     * Writes a {@code String} value to this stream. This method ensures that the {@linkplain #position() position}
+     * of this stream is updated correctly with respect to any {@linkplain #LINE_SEPARATOR line separators}
+     * present in {@code s}.
+     *
+     * @param s the value to be printed
+     * @return this {@link LogStream} instance
+     */
+    public LogStream print(String s) {
+        if (ps != null) {
+            if (s == null) {
+                indent();
+                lineBuffer.append(s);
+                return this;
+            }
+
+            int index = 0;
+            int next = s.indexOf(LINE_SEPARATOR, index);
+            while (index < s.length()) {
+                indent();
+                if (next > index) {
+                    lineBuffer.append(s.substring(index, next));
+                    flushLine(true);
+                    index = next + LINE_SEPARATOR.length();
+                    next = s.indexOf(LINE_SEPARATOR, index);
+                } else {
+                    lineBuffer.append(s.substring(index));
+                    break;
+                }
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Writes a {@code String} value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}.
+     *
+     * @param s the value to be printed
+     * @return this {@link LogStream} instance
+     */
+    public LogStream println(String s) {
+        if (ps != null) {
+            print(s);
+            flushLine(true);
+        }
+        return this;
+    }
+
+    /**
+     * Writes a formatted string to this stream.
+     *
+     * @param format a format string as described in {@link String#format(String, Object...)}
+     * @param args the arguments to be formatted
+     * @return this {@link LogStream} instance
+     */
+    public LogStream printf(String format, Object... args) {
+        if (ps != null) {
+            print(String.format(format, args));
+        }
+        return this;
+    }
+
+    /**
+     * Writes a {@linkplain #LINE_SEPARATOR line separator} to this stream.
+     *
+     * @return this {@code LogStream} instance
+     */
+    public LogStream println() {
+        if (ps != null) {
+            indent();
+            flushLine(true);
+        }
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/TTY.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2009, 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.max.criutils;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.regex.*;
+
+/**
+ * A collection of static methods for printing debug and informational output to a global {@link LogStream}.
+ * The output can be (temporarily) suppressed per thread through use of a {@linkplain Filter filter}.
+ */
+public class TTY {
+
+    /**
+     * Support for thread-local suppression of {@link TTY}.
+     */
+    public static class Filter {
+        private LogStream previous;
+        private final Thread thread = Thread.currentThread();
+
+        /**
+         * Creates an object that will suppress {@link TTY} for the current thread if the given filter does not
+         * {@linkplain #matches(String, Object) match} the given object. To revert the suppression state to how it was
+         * before this call, the {@link #remove()} method must be called on the suppression object.
+         *
+         * @param filter the pattern for matching. If {@code null}, then the match is successful. If it starts with "~",
+         *            then a regular expression {@linkplain Pattern#matches(String, CharSequence) match} is performed
+         *            where the regular expression is specified by {@code filter} without the "~" prefix. Otherwise, a
+         *            simple {@linkplain String#contains(CharSequence) substring} match is performed where {@code
+         *            filter} is the substring used.
+         * @param object an object whose {@linkplain Object#toString() string} value is matched against {@code filter}
+         */
+        public Filter(String filter, Object object) {
+            boolean suppressed = false;
+            if (filter != null) {
+                String input = object.toString();
+                if (filter.startsWith("~")) {
+                    suppressed = !Pattern.matches(filter.substring(1), input);
+                } else {
+                    suppressed = !input.contains(filter);
+                }
+                if (suppressed) {
+                    previous = out();
+                    out.set(LogStream.SINK);
+                }
+            }
+        }
+
+        /**
+         * Creates an object that will suppress {@link TTY} for the current thread.
+         * To revert the suppression state to how it was before this call, the
+         * {@link #remove()} method must be called on this filter object.
+         */
+        public Filter() {
+            previous = out();
+            out.set(LogStream.SINK);
+        }
+
+        /**
+         * Reverts the suppression state of {@link TTY} to how it was before this object was constructed.
+         */
+        public void remove() {
+            assert thread == Thread.currentThread();
+            if (previous != null) {
+                out.set(previous);
+            }
+        }
+    }
+
+    public static final String MAX_TTY_LOG_FILE_PROPERTY = "max.tty.file";
+
+    public static PrintStream cachedOut;
+
+    public static void initialize() {
+        cachedOut = System.out;
+    }
+
+    private static LogStream createLog() {
+        if (cachedOut == null) {
+            // In case initialize() was not called.
+            cachedOut = System.out;
+        }
+        PrintStream newOut = cachedOut;
+        String value = System.getProperty(MAX_TTY_LOG_FILE_PROPERTY);
+        if (value != null) {
+            try {
+                newOut = new PrintStream(new FileOutputStream(value));
+            } catch (FileNotFoundException e) {
+                System.err.println("Could not open log file " + value + ": " + e);
+            }
+        }
+        return new LogStream(newOut);
+    }
+
+    private static final ThreadLocal<LogStream> out = new ThreadLocal<LogStream>() {
+        @Override
+        protected LogStream initialValue() {
+            return createLog();
+        }
+    };
+
+    public static boolean isSuppressed() {
+        return out.get() == LogStream.SINK;
+    }
+
+    /**
+     * Gets the thread-local log stream to which the static methods of this class send their output.
+     * This will either be a global log stream or the global {@linkplain LogStream#SINK sink} depending
+     * on whether any suppression {@linkplain Filter filters} are in effect for the current thread.
+     */
+    public static LogStream out() {
+        return out.get();
+    }
+
+    /**
+     * @see LogStream#print(String)
+     */
+    public static void print(String s) {
+        out().print(s);
+    }
+
+    /**
+     * @see LogStream#print(int)
+     */
+    public static void print(int i) {
+        out().print(i);
+    }
+
+    /**
+     * @see LogStream#print(long)
+     */
+    public static void print(long i) {
+        out().print(i);
+    }
+
+    /**
+     * @see LogStream#print(char)
+     */
+    public static void print(char c) {
+        out().print(c);
+    }
+
+    /**
+     * @see LogStream#print(boolean)
+     */
+    public static void print(boolean b) {
+        out().print(b);
+    }
+
+    /**
+     * @see LogStream#print(double)
+     */
+    public static void print(double d) {
+        out().print(d);
+    }
+
+    /**
+     * @see LogStream#print(float)
+     */
+    public static void print(float f) {
+        out().print(f);
+    }
+
+    /**
+     * @see LogStream#println(String)
+     */
+    public static void println(String s) {
+        out().println(s);
+    }
+
+    /**
+     * @see LogStream#println()
+     */
+    public static void println() {
+        out().println();
+    }
+
+    /**
+     * @see LogStream#println(int)
+     */
+    public static void println(int i) {
+        out().println(i);
+    }
+
+    /**
+     * @see LogStream#println(long)
+     */
+    public static void println(long l) {
+        out().println(l);
+    }
+
+    /**
+     * @see LogStream#println(char)
+     */
+    public static void println(char c) {
+        out().println(c);
+    }
+
+    /**
+     * @see LogStream#println(boolean)
+     */
+    public static void println(boolean b) {
+        out().println(b);
+    }
+
+    /**
+     * @see LogStream#println(double)
+     */
+    public static void println(double d) {
+        out().println(d);
+    }
+
+    /**
+     * @see LogStream#println(float)
+     */
+    public static void println(float f) {
+        out().println(f);
+    }
+
+    public static void print(String format, Object... args) {
+        out().printf(format, args);
+    }
+
+    public static void println(String format, Object... args) {
+        out().printf(format + "%n", args);
+    }
+
+    public static void fillTo(int i) {
+        out().fillTo(i, ' ');
+    }
+
+    public static void printFields(Class<?> javaClass) {
+        final String className = javaClass.getSimpleName();
+        TTY.println(className + " {");
+        for (final Field field : javaClass.getFields()) {
+            printField(field, false);
+        }
+        TTY.println("}");
+    }
+
+    public static void printField(final Field field, boolean tabbed) {
+        final String fieldName = String.format("%35s", field.getName());
+        try {
+            String prefix = tabbed ? "" : "    " + fieldName + " = ";
+            String postfix = tabbed ? "\t" : "\n";
+            if (field.getType() == int.class) {
+                TTY.print(prefix + field.getInt(null) + postfix);
+            } else if (field.getType() == boolean.class) {
+                TTY.print(prefix + field.getBoolean(null) + postfix);
+            } else if (field.getType() == float.class) {
+                TTY.print(prefix + field.getFloat(null) + postfix);
+            } else if (field.getType() == String.class) {
+                TTY.print(prefix + field.get(null) + postfix);
+            } else if (field.getType() == Map.class) {
+                Map<?, ?> m = (Map<?, ?>) field.get(null);
+                TTY.print(prefix + printMap(m) + postfix);
+            } else {
+                TTY.print(prefix + field.get(null) + postfix);
+            }
+        } catch (IllegalAccessException e) {
+            // do nothing.
+        }
+    }
+
+    private static String printMap(Map<?, ?> m) {
+        StringBuilder sb = new StringBuilder();
+
+        List<String> keys = new ArrayList<>();
+        for (Object key : m.keySet()) {
+            keys.add((String) key);
+        }
+        Collections.sort(keys);
+
+        for (String key : keys) {
+            sb.append(key);
+            sb.append("\t");
+            sb.append(m.get(key));
+            sb.append("\n");
+        }
+
+        return sb.toString();
+    }
+
+    public static void flush() {
+        out().flush();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/simple/AssignRegisters.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.alloc.simple;
+
+import static com.oracle.max.graal.alloc.util.LocationUtil.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.alloc.util.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+public abstract class AssignRegisters {
+    public final LIR lir;
+    public final FrameMap frameMap;
+
+    public AssignRegisters(LIR lir, FrameMap frameMap) {
+        this.lir = lir;
+        this.frameMap = frameMap;
+    }
+
+    private CiBitMap curRegisterRefMap;
+    private CiBitMap curFrameRefMap;
+
+    public void execute() {
+        ValueProcedure useProc =          new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return use(value); } };
+        ValueProcedure defProc =          new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return def(value); } };
+        ValueProcedure setReferenceProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return setReference(value); } };
+
+        Debug.log("==== start assign registers ====");
+        for (int i = lir.linearScanOrder().size() - 1; i >= 0; i--) {
+            Block block = lir.linearScanOrder().get(i);
+            Debug.log("start block %s", block);
+
+            curRegisterRefMap = frameMap.initRegisterRefMap();
+            curFrameRefMap = frameMap.initFrameRefMap();
+
+            // Put all values live at the end of the block into the reference map.
+            locationsForBlockEnd(block).forEachLocation(setReferenceProc);
+
+            for (int j = block.lir.size() - 1; j >= 0; j--) {
+                LIRInstruction op = block.lir.get(j);
+                Debug.log("  op %d %s", op.id(), op);
+
+                op.forEachOutput(defProc);
+                op.forEachTemp(defProc);
+                op.forEachState(useProc);
+                op.forEachAlive(useProc);
+
+                if (op.info != null) {
+                    Debug.log("    registerRefMap: %s  frameRefMap: %s", curRegisterRefMap, curFrameRefMap);
+                    op.info.finish(new CiBitMap(curRegisterRefMap), new CiBitMap(curFrameRefMap), frameMap);
+
+                    if (op instanceof LIRXirInstruction) {
+                        LIRXirInstruction xir = (LIRXirInstruction) op;
+                        if (xir.infoAfter != null) {
+                            xir.infoAfter.finish(new CiBitMap(curRegisterRefMap), new CiBitMap(curFrameRefMap), frameMap);
+                        }
+                    }
+                }
+
+                // Process input operands after assigning the reference map, so that input operands that are used
+                // for the last time at this instruction are not part of the reference map.
+                op.forEachInput(useProc);
+            }
+            Debug.log("end block %s", block);
+        }
+        Debug.log("==== end assign registers ====");
+    }
+
+    private CiValue use(CiValue value) {
+        Debug.log("    use %s", value);
+        if (isLocation(value)) {
+            CiValue location = asLocation(value).location;
+            frameMap.setReference(location, curRegisterRefMap, curFrameRefMap);
+            return location;
+        } else {
+            frameMap.setReference(value, curRegisterRefMap, curFrameRefMap);
+            return value;
+        }
+    }
+
+    private CiValue def(CiValue value) {
+        Debug.log("    def %s", value);
+        if (isLocation(value)) {
+            CiValue location = asLocation(value).location;
+            frameMap.clearReference(location, curRegisterRefMap, curFrameRefMap);
+            return location;
+        } else {
+            frameMap.clearReference(value, curRegisterRefMap, curFrameRefMap);
+            return value;
+        }
+    }
+
+    private CiValue setReference(CiValue value) {
+        Debug.log("    setReference %s", value);
+        frameMap.setReference(asLocation(value).location, curRegisterRefMap, curFrameRefMap);
+        return value;
+    }
+
+    protected abstract LocationMap locationsForBlockEnd(Block block);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/simple/DataFlowAnalysis.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.alloc.simple;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.max.graal.lir.ValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+public class DataFlowAnalysis {
+    private final LIR lir;
+    private final RiRegisterConfig registerConfig;
+
+    public DataFlowAnalysis(LIR lir, RiRegisterConfig registerConfig) {
+        this.lir = lir;
+        this.registerConfig = registerConfig;
+    }
+
+    public void execute() {
+        numberInstructions();
+        backwardDataFlow();
+    }
+
+
+    private List<Block> blocks() {
+        return lir.linearScanOrder();
+    }
+
+    private int numVariables() {
+        return lir.numVariables();
+    }
+
+    private boolean isAllocatableRegister(CiValue value) {
+        return isRegister(value) && registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+    }
+
+
+    private int[] definitions;
+    private BitSet[] blockLiveIn;
+    private Block[] opIdBlock;
+    private Object[] opIdKilledValues;
+
+
+    public BitSet liveIn(Block block) {
+        return blockLiveIn[block.getId()];
+    }
+    private void setLiveIn(Block block, BitSet liveIn) {
+        blockLiveIn[block.getId()] = liveIn;
+    }
+
+    private Block blockOf(int opId) {
+        return opIdBlock[opId >> 1];
+    }
+    private void setBlockOf(int opId, Block block) {
+        opIdBlock[opId >> 1] = block;
+    }
+
+    private Object killedValues(int opId) {
+        return opIdKilledValues[opId];
+    }
+    private void setKilledValues(int opId, Object killedValues) {
+        opIdKilledValues[opId] = killedValues;
+    }
+
+    public void forEachKilled(LIRInstruction op, boolean end, ValueProcedure proc) {
+        Object entry = killedValues(op.id() + (end ? 1 : 0));
+        if (entry == null) {
+            // Nothing to do
+        } else if (entry instanceof CiValue) {
+            CiValue newValue = proc.doValue((CiValue) entry, null, null);
+            assert newValue == entry : "procedure does not allow to change values";
+        } else {
+            CiValue[] values = (CiValue[]) entry;
+            for (int i = 0; i < values.length; i++) {
+                if (values[i] != null) {
+                    CiValue newValue = proc.doValue(values[i], null, null);
+                    assert newValue == values[i] : "procedure does not allow to change values";
+                }
+            }
+        }
+    }
+
+    public int definition(Variable value) {
+        return definitions[value.index];
+    }
+
+    /**
+     * Numbers all instructions in all blocks. The numbering follows the {@linkplain ComputeLinearScanOrder linear scan order}.
+     */
+    private void numberInstructions() {
+        ValueProcedure defProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return setDef(value); } };
+
+        int numInstructions = 0;
+        for (Block block : blocks()) {
+            numInstructions += block.lir.size();
+        }
+        opIdBlock = new Block[numInstructions];
+        opIdKilledValues = new Object[numInstructions << 1];
+        definitions = new int[numVariables()];
+
+        curOpId = 0;
+        for (Block block : blocks()) {
+            for (LIRInstruction op : block.lir) {
+                op.setId(curOpId);
+                setBlockOf(curOpId, block);
+
+                op.forEachTemp(defProc);
+                op.forEachOutput(defProc);
+
+                curOpId += 2; // numbering of lirOps by two
+            }
+        }
+        assert curOpId == numInstructions << 1;
+    }
+
+    private CiValue setDef(CiValue value) {
+        if (isVariable(value)) {
+            assert definitions[asVariable(value).index] == 0 : "Variable defined twice";
+            definitions[asVariable(value).index] = curOpId;
+        }
+        return value;
+    }
+
+
+    private BitSet variableLive;
+    private BitSet registerLive;
+    private int curOpId;
+
+    private void backwardDataFlow() {
+        ValueProcedure inputProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return use(value, curOpId); } };
+        ValueProcedure aliveProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return use(value, curOpId + 1); } };
+        ValueProcedure tempProc =     new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return def(value, true); } };
+        ValueProcedure outputProc =   new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return def(value, false); } };
+
+        blockLiveIn = new BitSet[blocks().size()];
+        registerLive = new BitSet();
+
+        Debug.log("==== start backward data flow analysis ====");
+        for (int i = blocks().size() - 1; i >= 0; i--) {
+            Block block = blocks().get(i);
+            Debug.log("start block %s  loop %s", block, block.getLoop());
+
+            variableLive = new BitSet();
+            for (Block sux : block.getSuccessors()) {
+                BitSet suxLive = liveIn(sux);
+                if (suxLive != null) {
+                    Debug.log("  sux %s  suxLive: %s", sux, suxLive);
+                    variableLive.or(suxLive);
+                }
+            }
+
+            assert registerLive.isEmpty() : "no fixed register must be alive before processing a block";
+
+            for (int j = block.lir.size() - 1; j >= 0; j--) {
+                LIRInstruction op = block.lir.get(j);
+                curOpId = op.id();
+                Debug.log("  op %d %s  variableLive: %s  registerLive: %s", curOpId, op, variableLive, registerLive);
+
+                op.forEachOutput(outputProc);
+                op.forEachTemp(tempProc);
+                op.forEachState(aliveProc);
+                op.forEachAlive(aliveProc);
+                op.forEachInput(inputProc);
+            }
+
+            assert registerLive.isEmpty() : "no fixed register must be alive after processing a block";
+            assert liveIn(block) == null;
+            setLiveIn(block, variableLive);
+
+            if (block.isLoopHeader()) {
+                Debug.log("  loop header, propagating live set to loop blocks  variableLive: %s", variableLive);
+                // All variables that are live at the beginning of a loop are also live the whole loop.
+                // This is guaranteed by the SSA form.
+                for (Block loop : block.getLoop().blocks) {
+                    BitSet loopLiveIn = liveIn(loop);
+                    assert loopLiveIn != null : "All loop blocks must have been processed before the loop header";
+                    loopLiveIn.or(variableLive);
+                    Debug.log("    block %s  loopLiveIn %s", loop, loopLiveIn);
+                }
+            }
+
+            Debug.log("end block %s  variableLive: %s", block, variableLive);
+        }
+        Debug.log("==== end backward data flow analysis ====");
+    }
+
+    private CiValue use(CiValue value, int killOpId) {
+        Debug.log("    use %s", value);
+        if (isVariable(value)) {
+            int variableIdx = asVariable(value).index;
+            assert definitions[variableIdx] < curOpId;
+            if (!variableLive.get(variableIdx)) {
+                Debug.log("      set live variable %d", variableIdx);
+                variableLive.set(variableIdx);
+                kill(value, killOpId);
+            }
+
+        } else if (isAllocatableRegister(value)) {
+            int regNum = asRegister(value).number;
+            if (!registerLive.get(regNum)) {
+                Debug.log("      set live register %d", regNum);
+                registerLive.set(regNum);
+                kill(value, killOpId);
+            }
+        }
+        return value;
+    }
+
+    private CiValue def(CiValue value, boolean isTemp) {
+        Debug.log("    def %s", value);
+        if (isVariable(value)) {
+            int variableIdx = asVariable(value).index;
+            assert definitions[variableIdx] == curOpId;
+            if (variableLive.get(variableIdx)) {
+                Debug.log("      clear live variable %d", variableIdx);
+                assert !isTemp : "temp variable cannot be used after the operation";
+                variableLive.clear(variableIdx);
+            } else {
+                // Variable has never been used, so kill it immediately after the definition.
+                kill(value, curOpId + 1);
+            }
+
+        } else if (isAllocatableRegister(value)) {
+            int regNum = asRegister(value).number;
+            if (registerLive.get(regNum)) {
+                Debug.log("      clear live register %d", regNum);
+                assert !isTemp : "temp variable cannot be used after the operation";
+                registerLive.clear(regNum);
+            } else {
+                // Register has never been used, so kill it immediately after the definition.
+                kill(value, curOpId + 1);
+            }
+        }
+        return value;
+    }
+
+    private void kill(CiValue value, int opId) {
+        if (opId < 0) {
+            return;
+        }
+        if (isVariable(value)) {
+            int defOpId = definitions[asVariable(value).index];
+            assert defOpId > 0 && defOpId <= opId;
+
+            Block defBlock = blockOf(defOpId);
+            Block useBlock = blockOf(opId);
+
+            if (useBlock.getLoop() != null && useBlock.getLoop() != defBlock.getLoop()) {
+                // This is a value defined outside of the loop it is currently used in.  Therefore, it is live the whole loop
+                // and is not killed by the current instruction.
+                Debug.log("      no kill because use in %s, definition in %s", useBlock.getLoop(), defBlock.getLoop());
+                return;
+            }
+        }
+        Debug.log("      kill %s at %d", value, opId);
+
+        Object entry = killedValues(opId);
+        if (entry == null) {
+            setKilledValues(opId, value);
+        } else if (entry instanceof CiValue) {
+            setKilledValues(opId, new CiValue[] {(CiValue) entry, value});
+        } else {
+            CiValue[] killed = (CiValue[]) entry;
+            for (int i = 0; i < killed.length; i++) {
+                if (killed[i] == null) {
+                    killed[i] = value;
+                    return;
+                }
+            }
+            int oldLen = killed.length;
+            killed = Arrays.copyOf(killed, oldLen * 2);
+            setKilledValues(opId, killed);
+            killed[oldLen] = value;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/simple/LinearScanAllocator.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,573 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.alloc.simple;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.max.graal.alloc.util.LocationUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiRegister.RegisterFlag;
+import com.oracle.max.graal.alloc.util.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+public class LinearScanAllocator {
+    private final LIR lir;
+    private final FrameMap frameMap;
+
+    private final DataFlowAnalysis dataFlow;
+
+    public LinearScanAllocator(LIR lir, FrameMap frameMap) {
+        this.lir = lir;
+        this.frameMap = frameMap;
+
+        this.dataFlow = new DataFlowAnalysis(lir, frameMap.registerConfig);
+        this.blockBeginLocations = new LocationMap[lir.linearScanOrder().size()];
+        this.blockEndLocations = new LocationMap[lir.linearScanOrder().size()];
+        this.moveResolver = new MoveResolverImpl(lir, frameMap);
+
+        this.variableLastUse = new int[lir.numVariables()];
+    }
+
+    private class MoveResolverImpl extends MoveResolver {
+        public MoveResolverImpl(LIR lir, FrameMap frameMap) {
+            super(lir, frameMap);
+        }
+
+        @Override
+        protected CiValue scratchRegister(Variable spilled) {
+            GraalInternalError.shouldNotReachHere("needs working implementation");
+
+            EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
+            CiRegister[] availableRegs = categorizedRegs.get(spilled.flag);
+            for (CiRegister reg : availableRegs) {
+                if (curInRegisterState[reg.number] == null && curOutRegisterState[reg.number] == null) {
+                    return reg.asValue(spilled.kind);
+                }
+            }
+            throw new CiBailout("No register found");
+        }
+    }
+
+    private class ResolveDataFlowImpl extends ResolveDataFlow {
+        public ResolveDataFlowImpl(LIR lir, MoveResolver moveResolver, DataFlowAnalysis dataFlow) {
+            super(lir, moveResolver, dataFlow);
+        }
+
+        @Override
+        protected LocationMap locationsForBlockBegin(Block block) {
+            return beginLocationsFor(block);
+        }
+
+        @Override
+        protected LocationMap locationsForBlockEnd(Block block) {
+            return endLocationsFor(block);
+        }
+    }
+
+    private class AssignRegistersImpl extends AssignRegisters {
+        public AssignRegistersImpl(LIR lir, FrameMap frameMap) {
+            super(lir, frameMap);
+        }
+
+        @Override
+        protected LocationMap locationsForBlockEnd(Block block) {
+            return endLocationsFor(block);
+        }
+    }
+
+
+    private int maxRegisterNum() {
+        return frameMap.target.arch.registers.length;
+    }
+
+    private boolean isAllocatableRegister(CiValue value) {
+        return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+    }
+
+
+    private final LocationMap[] blockBeginLocations;
+
+    private LocationMap beginLocationsFor(Block block) {
+        return blockBeginLocations[block.getId()];
+    }
+    private void setBeginLocationsFor(Block block, LocationMap locations) {
+        blockBeginLocations[block.getId()] = locations;
+    }
+
+    private final LocationMap[] blockEndLocations;
+
+    private LocationMap endLocationsFor(Block block) {
+        return blockEndLocations[block.getId()];
+    }
+    private void setEndLocationsFor(Block block, LocationMap locations) {
+        blockEndLocations[block.getId()] = locations;
+    }
+
+    private final int[] variableLastUse;
+
+    private int lastUseFor(Variable variable) {
+        return variableLastUse[variable.index];
+    }
+
+    private void setLastUseFor(Variable variable, int lastUse) {
+        variableLastUse[variable.index] = lastUse;
+    }
+
+    private MoveResolver moveResolver;
+    private LocationMap curLocations;
+    private CiValue[] curInRegisterState;
+    private CiValue[] curOutRegisterState;
+    private BitSet curLiveIn;
+    private int curOpId;
+    private boolean curPhiDefs;
+
+    private LocationMap canonicalSpillLocations;
+
+    public void execute() {
+        assert LIRVerifier.verify(true, lir, frameMap);
+
+        dataFlow.execute();
+        IntervalPrinter.printBeforeAllocation("Before register allocation", lir, frameMap.registerConfig, dataFlow);
+
+        allocate();
+
+        IntervalPrinter.printAfterAllocation("After linear scan allocation", lir, frameMap.registerConfig, dataFlow, blockEndLocations);
+
+        ResolveDataFlow resolveDataFlow = new ResolveDataFlowImpl(lir, moveResolver, dataFlow);
+        resolveDataFlow.execute();
+        frameMap.finish();
+
+        IntervalPrinter.printAfterAllocation("After resolve data flow", lir, frameMap.registerConfig, dataFlow, blockEndLocations);
+        assert RegisterVerifier.verify(lir, frameMap);
+
+        AssignRegisters assignRegisters = new AssignRegistersImpl(lir, frameMap);
+        assignRegisters.execute();
+
+        Debug.dump(lir, "After register asignment");
+        assert LIRVerifier.verify(false, lir, frameMap);
+    }
+
+    private void allocate() {
+        ValueProcedure recordUseProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return recordUse(value); } };
+        ValueProcedure killNonLiveProc =  new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return killNonLive(value); } };
+        ValueProcedure unblockProc =      new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return unblock(value); } };
+        ValueProcedure killProc =         new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return kill(value); } };
+        ValueProcedure blockProc =        new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return block(value); } };
+        ValueProcedure useProc =          new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return use(value, mode, flags); } };
+        ValueProcedure defProc =          new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return def(value, mode, flags); } };
+
+        Debug.log("==== start linear scan allocation ====");
+        canonicalSpillLocations = new LocationMap(lir.numVariables());
+        curInRegisterState = new CiValue[maxRegisterNum()];
+        curOutRegisterState = new CiValue[maxRegisterNum()];
+        for (Block block : lir.linearScanOrder()) {
+            Debug.log("start block %s %s", block, block.getLoop());
+
+            Arrays.fill(curOutRegisterState, null);
+            if (block.getDominator() != null) {
+                LocationMap dominatorState = endLocationsFor(block.getDominator());
+                curLocations = new LocationMap(dominatorState);
+                // Clear out all variables that are not live at the begin of this block
+                curLiveIn = dataFlow.liveIn(block);
+                curLocations.forEachLocation(killNonLiveProc);
+                assert checkInputState(block);
+            } else {
+                curLocations = new LocationMap(lir.numVariables());
+            }
+            Debug.log(logCurrentState());
+
+            for (int opIdx = 0; opIdx < block.lir.size(); opIdx++) {
+                LIRInstruction op = block.lir.get(opIdx);
+                curOpId = op.id();
+                curPhiDefs = opIdx == 0;
+
+                Debug.log("  op %d %s", op.id(), op);
+
+                System.arraycopy(curOutRegisterState, 0, curInRegisterState, 0, curOutRegisterState.length);
+
+                // Unblock fixed registers that are only used for inputs in curOutRegisterState.
+                dataFlow.forEachKilled(op, false, unblockProc);
+                // Block fixed registers defined by this instruction in curOutRegisterState.
+                op.forEachTemp(blockProc);
+                op.forEachOutput(blockProc);
+
+                op.forEachInput(recordUseProc);
+                op.forEachAlive(recordUseProc);
+
+                moveResolver.init(block.lir, opIdx);
+                // Process Alive before Input because they are more restricted and the same variable can be Alive and Input.
+                op.forEachAlive(useProc);
+                op.forEachInput(useProc);
+
+                dataFlow.forEachKilled(op, false, killProc);
+
+                if (op.hasCall()) {
+                    spillCallerSaveRegisters();
+                }
+
+                op.forEachTemp(defProc);
+                op.forEachOutput(defProc);
+
+                // Fixed temp and output registers can evict variables from their assigned register, allocate new location for them.
+                fixupEvicted();
+                // State values are the least critical and can get the leftover registers (or stack slots if no more register available).
+                op.forEachState(useProc);
+
+                if (opIdx == 0) {
+                    assert !moveResolver.hasMappings() : "cannot insert spill moves before label";
+                    setBeginLocationsFor(block, new LocationMap(curLocations));
+                }
+                moveResolver.resolve();
+
+                dataFlow.forEachKilled(op, true, unblockProc);
+                dataFlow.forEachKilled(op, true, killProc);
+
+                curOpId = -1;
+            }
+
+            assert endLocationsFor(block) == null;
+            setEndLocationsFor(block, curLocations);
+
+            logCurrentState();
+            Debug.log("end block %s", block);
+        }
+
+        moveResolver.finish();
+        Debug.log("==== end linear scan allocation ====");
+    }
+
+    private CiValue killNonLive(CiValue value) {
+        assert isLocation(value);
+        if (!curLiveIn.get(asLocation(value).variable.index)) {
+            return null;
+
+        } else if (isAllocatableRegister(asLocation(value).location)) {
+            int regNum = asRegister(asLocation(value).location).number;
+            assert curOutRegisterState[regNum] == null;
+            curOutRegisterState[regNum] = value;
+        }
+        return value;
+    }
+
+    private CiValue unblock(CiValue value) {
+        if (isAllocatableRegister(value)) {
+            Debug.log("    unblock register %s", value);
+            int regNum = asRegister(value).number;
+            assert curOutRegisterState[regNum] == value;
+            curOutRegisterState[regNum] = null;
+        }
+        return value;
+    }
+
+    private CiValue kill(CiValue value) {
+        if (isVariable(value)) {
+            Location location = curLocations.get(asVariable(value));
+            Debug.log("    kill location %s", location);
+            if (isRegister(location.location)) {
+                int regNum = asRegister(location.location).number;
+                if (curOutRegisterState[regNum] == location) {
+                    curOutRegisterState[regNum] = null;
+                }
+            }
+            curLocations.clear(asVariable(value));
+        }
+        return value;
+    }
+
+
+    private CiValue block(CiValue value) {
+        if (isAllocatableRegister(value)) {
+            Debug.log("    block %s", value);
+            int regNum = asRegister(value).number;
+            assert curOutRegisterState[regNum] == null || curOutRegisterState[regNum] instanceof Location;
+            curOutRegisterState[regNum] = value;
+        }
+        return value;
+    }
+
+    private void spillCallerSaveRegisters() {
+        Debug.log("    spill caller save registers in curInRegisterState %s", Arrays.toString(curInRegisterState));
+        for (CiRegister reg : frameMap.registerConfig.getCallerSaveRegisters()) {
+            CiValue in = curInRegisterState[reg.number];
+            if (in != null && isLocation(in)) {
+                spill(asLocation(in));
+            }
+        }
+    }
+
+    private CiValue recordUse(CiValue value) {
+        if (isVariable(value)) {
+            assert lastUseFor(asVariable(value)) <= curOpId;
+            setLastUseFor(asVariable(value), curOpId);
+
+        }
+        return value;
+    }
+
+    private CiValue use(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+        assert mode == OperandMode.Input || mode == OperandMode.Alive;
+        if (isVariable(value)) {
+            // State values are not recorded beforehand because it does not matter if they are spilled. Still, it is necessary to record them as used now.
+            recordUse(value);
+
+            Location curLoc = curLocations.get(asVariable(value));
+            if (isStackSlot(curLoc.location) && flags.contains(OperandFlag.Stack)) {
+                Debug.log("    use %s %s: use current stack slot %s", mode, value, curLoc.location);
+                return curLoc;
+            }
+            if (isRegister(curLoc.location)) {
+                int regNum = asRegister(curLoc.location).number;
+                assert curInRegisterState[regNum] == curLoc;
+                if (mode == OperandMode.Input || curOutRegisterState[regNum] == curLoc) {
+                    Debug.log("    use %s %s: use current register %s", mode, value, curLoc.location);
+                    return curLoc;
+                }
+            }
+
+            Debug.log("    use %s %s", mode, value);
+
+            Location newLoc = allocateRegister(asVariable(value), mode, flags);
+            if (newLoc != curLoc) {
+                moveResolver.add(curLoc, newLoc);
+            }
+            return newLoc;
+        } else {
+            assert !isAllocatableRegister(value) || curInRegisterState[asRegister(value).number] == value;
+        }
+        return value;
+    }
+
+    private static final EnumSet<OperandFlag> SPILL_FLAGS = EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
+
+    private CiValue def(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+        assert mode == OperandMode.Temp || mode == OperandMode.Output;
+        if (isVariable(value)) {
+            Debug.log("    def %s %s", mode, value);
+            assert curLocations.get(asVariable(value)) == null;
+
+            Location newLoc = allocateRegister(asVariable(value), mode, flags);
+            return newLoc;
+        }
+        return value;
+    }
+
+
+    private void fixupEvicted() {
+        for (int i = 0; i < curInRegisterState.length; i++) {
+            CiValue in = curInRegisterState[i];
+            CiValue out = curOutRegisterState[i];
+
+            if (in != null && in != out && isLocation(in) && curLocations.get(asLocation(in).variable) == in) {
+                Debug.log("    %s was evicted by %s, need to allocate new location", in, out);
+                Location oldLoc = asLocation(in);
+                Location newLoc = allocateRegister(oldLoc.variable, OperandMode.Alive, SPILL_FLAGS);
+                assert oldLoc != newLoc;
+                moveResolver.add(oldLoc, newLoc);
+            }
+
+
+        }
+    }
+
+
+    private Location allocateRegister(final Variable variable, OperandMode mode, EnumSet<OperandFlag> flags) {
+//        if (flags.contains(OperandFlag.RegisterHint)) {
+//            CiValue result = curInstruction.forEachRegisterHint(variable, mode, new ValueProcedure() {
+//                @Override
+//                public CiValue doValue(CiValue registerHint) {
+//                    Debug.log("      registerHint %s", registerHint);
+//                    CiRegister hint = null;
+//                    if (isRegister(registerHint)) {
+//                        hint = asRegister(registerHint);
+//                    } else if (isLocation(registerHint) && isRegister(asLocation(registerHint).location)) {
+//                        hint = asRegister(asLocation(registerHint).location);
+//                    }
+//                    if (hint != null && hint.isSet(variable.flag) && isFree(hint, inRegisterState, outRegisterState)) {
+//                        return selectRegister(hint, variable, inRegisterState, outRegisterState);
+//                    }
+//                    return null;
+//                }
+//            });
+//
+//            if (result != null) {
+//                return asLocation(result);
+//            }
+//        }
+//
+        EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
+        CiRegister[] availableRegs = categorizedRegs.get(variable.flag);
+
+        Location bestSpillCandidate = null;
+        for (CiRegister reg : availableRegs) {
+            if (isFree(reg, mode)) {
+                return selectRegister(reg, variable, mode);
+            } else {
+                Location spillCandidate = spillCandidate(reg);
+                if (betterSpillCandidate(spillCandidate, bestSpillCandidate)) {
+                    bestSpillCandidate = spillCandidate;
+                }
+            }
+        }
+
+        if (flags.contains(OperandFlag.Stack) && betterSpillCandidate(curLocations.get(variable), bestSpillCandidate)) {
+            return selectSpillSlot(variable);
+        }
+
+        if (bestSpillCandidate == null) {
+            if (curPhiDefs) {
+                return selectSpillSlot(variable);
+            }
+
+            // This should not happen as long as all LIR instructions have fulfillable register constraints. But be safe in product mode and bail out.
+            assert false;
+            throw new GraalInternalError("No register available");
+        }
+
+        spill(bestSpillCandidate);
+
+        return selectRegister(asRegister(bestSpillCandidate.location), variable, mode);
+    }
+
+    private void spill(Location value) {
+        Location newLoc = spillLocation(value.variable);
+        Debug.log("      spill %s to %s", value, newLoc);
+        if (!curPhiDefs) {
+            moveResolver.add(value, newLoc);
+        }
+        curLocations.put(newLoc);
+
+        CiRegister reg = asRegister(value.location);
+        assert curInRegisterState[reg.number] == value;
+        curInRegisterState[reg.number] = null;
+        if (curOutRegisterState[reg.number] == value) {
+            curOutRegisterState[reg.number] = null;
+        }
+    }
+
+    private boolean isFree(CiRegister reg, OperandMode mode) {
+        switch (mode) {
+            case Input:  return curInRegisterState[reg.number] == null;
+            case Alive:  return curInRegisterState[reg.number] == null && curOutRegisterState[reg.number] == null;
+            case Temp:   return curOutRegisterState[reg.number] == null;
+            case Output: return curOutRegisterState[reg.number] == null;
+            default:     throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private Location spillCandidate(CiRegister reg) {
+        CiValue in = curInRegisterState[reg.number];
+        CiValue out = curOutRegisterState[reg.number];
+        if (in == out && in != null && isLocation(in) && lastUseFor(asLocation(in).variable) < curOpId) {
+            return asLocation(in);
+        }
+        return null;
+    }
+
+    private boolean betterSpillCandidate(Location loc, Location compare) {
+        if (loc == null) {
+            return false;
+        }
+        if (compare == null) {
+            return true;
+        }
+        if (canonicalSpillLocations.get(loc.variable) != null && canonicalSpillLocations.get(compare.variable) == null) {
+            return true;
+        }
+        return dataFlow.definition(loc.variable) < dataFlow.definition(compare.variable);
+    }
+
+    private Location spillLocation(Variable variable) {
+        Location result = canonicalSpillLocations.get(variable);
+        if (result == null) {
+            result = new Location(variable, frameMap.allocateSpillSlot(variable.kind));
+            canonicalSpillLocations.put(result);
+        }
+        return result;
+    }
+
+    private Location selectRegister(CiRegister reg, Variable variable, OperandMode mode) {
+        assert isFree(reg, mode);
+
+        Location loc = new Location(variable, reg.asValue(variable.kind));
+        if (mode == OperandMode.Input || mode == OperandMode.Alive) {
+            curInRegisterState[reg.number] = loc;
+        }
+        curOutRegisterState[reg.number] = loc;
+        curLocations.put(loc);
+        recordUse(variable);
+
+        Debug.log("      selected register %s", loc);
+        return loc;
+    }
+
+    private Location selectSpillSlot(Variable variable) {
+        Location loc = spillLocation(variable);
+        curLocations.put(loc);
+        recordUse(variable);
+
+        Debug.log("      selected spill slot %s", loc);
+        return loc;
+    }
+
+    private boolean checkInputState(final Block block) {
+        final BitSet liveState = new BitSet();
+        curLocations.forEachLocation(new ValueProcedure() {
+            @Override
+            public CiValue doValue(CiValue value) {
+                liveState.set(asLocation(value).variable.index);
+
+                for (Block pred : block.getPredecessors()) {
+                    LocationMap predState = endLocationsFor(pred);
+                    if (predState != null) {
+                        assert predState.get(asLocation(value).variable) != null;
+                    } else {
+                        assert block.isLoopHeader();
+                    }
+                }
+                return value;
+            }
+        });
+        assert liveState.equals(curLiveIn);
+        return true;
+    }
+
+
+    private String logCurrentState() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("  current lcoations: ");
+        curLocations.forEachLocation(new ValueProcedure() {
+            @Override
+            public CiValue doValue(CiValue value) {
+                sb.append(value).append(" ");
+                return value;
+            }
+        });
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/simple/ResolveDataFlow.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.alloc.simple;
+
+import static com.oracle.max.graal.alloc.util.LocationUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.alloc.util.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.StandardOp.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+public abstract class ResolveDataFlow {
+    public final LIR lir;
+    public final MoveResolver moveResolver;
+    public final DataFlowAnalysis dataFlow;
+
+    public ResolveDataFlow(LIR lir, MoveResolver moveResolver, DataFlowAnalysis dataFlow) {
+        this.lir = lir;
+        this.moveResolver = moveResolver;
+        this.dataFlow = dataFlow;
+    }
+
+    private LocationMap curFromLocations;
+
+    public void execute() {
+        ValueProcedure locMappingProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return locMapping(value); } };
+
+        Debug.log("==== start resolve data flow ====");
+        for (Block toBlock : lir.linearScanOrder()) {
+            PhiLabelOp phiDefs = null;
+            if (toBlock.lir.get(0) instanceof PhiLabelOp) {
+                phiDefs = (PhiLabelOp) toBlock.lir.get(0);
+            }
+
+            for (Block fromBlock : toBlock.getPredecessors()) {
+                Debug.log("start edge %s -> %s", fromBlock, toBlock);
+                findInsertPos(fromBlock, toBlock);
+
+                LocationMap toLocations = locationsForBlockBegin(toBlock);
+                curFromLocations = locationsForBlockEnd(fromBlock);
+                if (toLocations != curFromLocations) {
+                    toLocations.forEachLocation(locMappingProc);
+                }
+
+                if (phiDefs != null) {
+                    PhiJumpOp phiInputs = (PhiJumpOp) fromBlock.lir.get(fromBlock.lir.size() - 1);
+                    phiMapping(phiInputs.getPhiInputs(), phiDefs.getPhiDefinitions());
+                    phiInputs.markResolved();
+                }
+
+                moveResolver.resolve();
+                Debug.log("end edge %s -> %s", fromBlock, toBlock);
+            }
+
+            if (phiDefs != null) {
+                // Phi functions are resolved with moves now, so delete them.
+                phiDefs.markResolved();
+            }
+        }
+        moveResolver.finish();
+        Debug.log("==== end resolve data flow ====");
+    }
+
+    private CiValue locMapping(CiValue value) {
+        Location to = asLocation(value);
+        Location from = curFromLocations.get(to.variable);
+        if (value != from && from != null) {
+            moveResolver.add(from, to);
+        }
+        return value;
+    }
+
+    private void phiMapping(CiValue[] inputs, CiValue[] outputs) {
+        assert inputs.length == outputs.length;
+        for (int i = 0; i < inputs.length; i++) {
+            if (inputs[i] != outputs[i]) {
+                moveResolver.add(inputs[i], asLocation(outputs[i]));
+            }
+        }
+    }
+
+    private void findInsertPos(Block fromBlock, Block toBlock) {
+        assert fromBlock.getSuccessors().contains(toBlock) && toBlock.getPredecessors().contains(fromBlock);
+
+        if (fromBlock.numberOfSux() == 1) {
+            List<LIRInstruction> instructions = fromBlock.lir;
+            LIRInstruction instr = instructions.get(instructions.size() - 1);
+            assert instr instanceof StandardOp.JumpOp : "block does not end with an unconditional jump";
+            moveResolver.init(instructions, instructions.size() - 1);
+            Debug.log("  insert at end of %s before %d", fromBlock, instructions.size() - 1);
+
+        } else if (toBlock.numberOfPreds() == 1) {
+            moveResolver.init(toBlock.lir, 1);
+            Debug.log("  insert at beginning of %s before %d", toBlock, 1);
+
+        } else {
+            GraalInternalError.shouldNotReachHere("Critical edge not split");
+        }
+    }
+
+    protected abstract LocationMap locationsForBlockBegin(Block block);
+    protected abstract LocationMap locationsForBlockEnd(Block block);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/simple/SpillAllAllocator.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.alloc.simple;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.max.graal.alloc.util.LocationUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiRegister.RegisterFlag;
+import com.oracle.max.graal.alloc.util.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+public class SpillAllAllocator {
+    private final LIR lir;
+    private final FrameMap frameMap;
+
+    private final DataFlowAnalysis dataFlow;
+
+    public SpillAllAllocator(LIR lir, FrameMap frameMap) {
+        this.lir = lir;
+        this.frameMap = frameMap;
+
+        this.dataFlow = new DataFlowAnalysis(lir, frameMap.registerConfig);
+        this.blockLocations = new LocationMap[lir.linearScanOrder().size()];
+        this.moveResolver = new MoveResolverImpl(lir, frameMap);
+    }
+
+    private class MoveResolverImpl extends MoveResolver {
+        public MoveResolverImpl(LIR lir, FrameMap frameMap) {
+            super(lir, frameMap);
+        }
+
+        @Override
+        protected CiValue scratchRegister(Variable spilled) {
+            EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
+            CiRegister[] availableRegs = categorizedRegs.get(spilled.flag);
+            for (CiRegister reg : availableRegs) {
+                if (curInRegisterState[reg.number] == null && curOutRegisterState[reg.number] == null) {
+                    return reg.asValue(spilled.kind);
+                }
+            }
+            throw new CiBailout("No register found");
+        }
+    }
+
+    private class ResolveDataFlowImpl extends ResolveDataFlow {
+        public ResolveDataFlowImpl(LIR lir, MoveResolver moveResolver, DataFlowAnalysis dataFlow) {
+            super(lir, moveResolver, dataFlow);
+        }
+
+        @Override
+        protected LocationMap locationsForBlockBegin(Block block) {
+            assert block.numberOfPreds() > 0 && block.getDominator() != null;
+            return locationsFor(block.getDominator());
+        }
+
+        @Override
+        protected LocationMap locationsForBlockEnd(Block block) {
+            return locationsFor(block);
+        }
+    }
+
+    private class AssignRegistersImpl extends AssignRegisters {
+        public AssignRegistersImpl(LIR lir, FrameMap frameMap) {
+            super(lir, frameMap);
+        }
+
+        @Override
+        protected LocationMap locationsForBlockEnd(Block block) {
+            return locationsFor(block);
+        }
+    }
+
+
+    private int maxRegisterNum() {
+        return frameMap.target.arch.registers.length;
+    }
+
+    private boolean isAllocatableRegister(CiValue value) {
+        return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+    }
+
+
+    private final LocationMap[] blockLocations;
+
+    private LocationMap locationsFor(Block block) {
+        return blockLocations[block.getId()];
+    }
+    private void setLocationsFor(Block block, LocationMap locations) {
+        blockLocations[block.getId()] = locations;
+    }
+
+    private MoveResolver moveResolver;
+    private LocationMap curStackLocations;
+    private LocationMap curRegisterLocations;
+    private Object[] curInRegisterState;
+    private Object[] curOutRegisterState;
+    private BitSet curLiveIn;
+    private LIRInstruction curInstruction;
+
+    public void execute() {
+        assert LIRVerifier.verify(true, lir, frameMap);
+
+        dataFlow.execute();
+        IntervalPrinter.printBeforeAllocation("Before register allocation", lir, frameMap.registerConfig, dataFlow);
+
+        allocate();
+
+        IntervalPrinter.printAfterAllocation("After spill all allocation", lir, frameMap.registerConfig, dataFlow, blockLocations);
+
+        ResolveDataFlow resolveDataFlow = new ResolveDataFlowImpl(lir, moveResolver, dataFlow);
+        resolveDataFlow.execute();
+        frameMap.finish();
+
+        IntervalPrinter.printAfterAllocation("After resolve data flow", lir, frameMap.registerConfig, dataFlow, blockLocations);
+        assert RegisterVerifier.verify(lir, frameMap);
+
+        AssignRegisters assignRegisters = new AssignRegistersImpl(lir, frameMap);
+        assignRegisters.execute();
+
+        Debug.dump(lir, "After register asignment");
+        assert LIRVerifier.verify(false, lir, frameMap);
+    }
+
+    private void allocate() {
+        ValueProcedure killNonLiveProc =  new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return killNonLive(value); } };
+        ValueProcedure killBeginProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return kill(value, false); } };
+        ValueProcedure killEndProc =      new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return kill(value, true); } };
+        ValueProcedure killLocationProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return killLocation(value); } };
+        ValueProcedure blockProc =        new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return block(value); } };
+        ValueProcedure loadProc =         new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return load(value, mode, flags); } };
+        ValueProcedure spillProc =        new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return spill(value, mode, flags); } };
+        ValueProcedure useSlotProc =      new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return useSlot(value); } };
+
+        Debug.log("==== start spill all allocation ====");
+        curInRegisterState = new Object[maxRegisterNum()];
+        curOutRegisterState = new Object[maxRegisterNum()];
+        curRegisterLocations = new LocationMap(lir.numVariables());
+        for (Block block : lir.linearScanOrder()) {
+            Debug.log("start block %s %s", block, block.getLoop());
+            assert checkEmpty(curOutRegisterState);
+
+            if (block.getDominator() != null) {
+                LocationMap dominatorState = locationsFor(block.getDominator());
+                curStackLocations = new LocationMap(dominatorState);
+                // Clear out all variables that are not live at the begin of this block
+                curLiveIn = dataFlow.liveIn(block);
+                curStackLocations.forEachLocation(killNonLiveProc);
+                assert checkInputState(block);
+            } else {
+                curStackLocations = new LocationMap(lir.numVariables());
+            }
+            Debug.log(logCurrentState());
+
+            for (int opIdx = 0; opIdx < block.lir.size(); opIdx++) {
+                LIRInstruction op = block.lir.get(opIdx);
+                curInstruction = op;
+                Debug.log("  op %d %s", op.id(), op);
+
+                assert curRegisterLocations.checkEmpty();
+
+                System.arraycopy(curOutRegisterState, 0, curInRegisterState, 0, curOutRegisterState.length);
+
+                // Block fixed registers that are defined by this instruction, so that they are no longer available for normal allocation.
+                op.forEachTemp(blockProc);
+                op.forEachOutput(blockProc);
+
+                moveResolver.init(block.lir, opIdx);
+                // Process Alive before Input because they are more restricted and the same variable can be Alive and Input.
+                op.forEachAlive(loadProc);
+                op.forEachInput(loadProc);
+                moveResolver.resolve();
+                op.forEachState(useSlotProc);
+
+                dataFlow.forEachKilled(op, false, killBeginProc);
+                assert !op.hasCall() || checkNoCallerSavedRegister() : "caller saved register in use accross call site";
+
+                moveResolver.init(block.lir, opIdx + 1);
+                op.forEachTemp(spillProc);
+                op.forEachOutput(spillProc);
+                moveResolver.resolve();
+
+                dataFlow.forEachKilled(op, true, killEndProc);
+                curRegisterLocations.forEachLocation(killLocationProc);
+
+                assert curRegisterLocations.checkEmpty();
+                curInstruction = null;
+            }
+            assert checkEmpty(curOutRegisterState);
+            assert locationsFor(block) == null;
+            setLocationsFor(block, curStackLocations);
+
+            logCurrentState();
+            Debug.log("end block %s", block);
+        }
+
+        moveResolver.finish();
+        Debug.log("==== end spill all allocation ====");
+    }
+
+    private CiValue killNonLive(CiValue value) {
+        assert isLocation(value);
+        if (!curLiveIn.get(asLocation(value).variable.index)) {
+            return null;
+        }
+        return value;
+    }
+
+    private CiValue kill(CiValue value, boolean end) {
+        if (isVariable(value)) {
+            Debug.log("    kill variable %s", value);
+
+            Variable variable = asVariable(value);
+            curStackLocations.clear(variable);
+
+            Location loc = curRegisterLocations.get(variable);
+            if (loc != null) {
+                killLocation(loc);
+                curRegisterLocations.clear(variable);
+
+                Debug.log("      location %s", loc);
+                assert isAllocatableRegister(loc.location);
+
+                int regNum = asRegister(loc.location).number;
+                if (curOutRegisterState[regNum] == loc) {
+                    curOutRegisterState[regNum] = null;
+                }
+            }
+
+        } else if (isAllocatableRegister(value)) {
+            Debug.log("    kill register %s", value);
+            int regNum = asRegister(value).number;
+            assert curOutRegisterState[regNum] == null || curOutRegisterState[regNum] instanceof LIRInstruction && curInstruction != null;
+
+            if (end || curOutRegisterState[regNum] != curInstruction) {
+                curOutRegisterState[regNum] = null;
+            }
+
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+        return value;
+    }
+
+    private CiValue killLocation(CiValue value) {
+        Debug.log("    kill location %s", value);
+        assert isAllocatableRegister(asLocation(value).location);
+
+        int regNum = asRegister(asLocation(value).location).number;
+        if (curOutRegisterState[regNum] == value) {
+            curOutRegisterState[regNum] = null;
+        }
+        return null;
+    }
+
+    private CiValue block(CiValue value) {
+        if (isAllocatableRegister(value)) {
+            Debug.log("    block %s", value);
+            int regNum = asRegister(value).number;
+            assert curInstruction != null;
+            assert curOutRegisterState[regNum] == null || curOutRegisterState[regNum] instanceof LIRInstruction;
+            curOutRegisterState[regNum] = curInstruction;
+        }
+        return value;
+    }
+
+    private CiValue load(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+        assert mode == OperandMode.Input || mode == OperandMode.Alive;
+        if (flags.contains(OperandFlag.Stack)) {
+            return useSlot(value);
+        }
+        if (isVariable(value)) {
+            Debug.log("    load %s", value);
+            Location regLoc = curRegisterLocations.get(asVariable(value));
+            if (regLoc != null) {
+                // This variable has already been processed before.
+                Debug.log("      found location %s", regLoc);
+            } else {
+                regLoc = allocateRegister(asVariable(value), curInRegisterState, mode == OperandMode.Alive ? curOutRegisterState : null, mode, flags);
+                Location stackLoc = curStackLocations.get(asVariable(value));
+                assert stackLoc != null;
+                moveResolver.add(stackLoc, regLoc);
+            }
+            return regLoc;
+        } else {
+            assert !isAllocatableRegister(value) || curInRegisterState[asRegister(value).number] instanceof LIRInstruction;
+            return value;
+        }
+    }
+
+    private CiValue spill(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+        assert mode == OperandMode.Temp || mode == OperandMode.Output;
+        if (flags.contains(OperandFlag.Stack)) {
+            return defSlot(value);
+        }
+        if (isVariable(value)) {
+            Debug.log("    spill %s", value);
+            assert curStackLocations.get(asVariable(value)) == null;
+            Location regLoc = allocateRegister(asVariable(value), null, curOutRegisterState, mode, flags);
+            if (mode == OperandMode.Output) {
+                Location stackLoc = new Location(asVariable(value), frameMap.allocateSpillSlot(value.kind));
+                curStackLocations.put(stackLoc);
+                moveResolver.add(regLoc, stackLoc);
+            }
+            return regLoc;
+        } else {
+            assert !isAllocatableRegister(value) || curOutRegisterState[asRegister(value).number] == curInstruction && curInstruction != null;
+            return value;
+        }
+    }
+
+    private CiValue useSlot(CiValue value) {
+        if (isVariable(value)) {
+            Debug.log("    useSlot %s", value);
+            Location stackLoc = curStackLocations.get(asVariable(value));
+            assert stackLoc != null;
+            Debug.log("      slot %s", stackLoc);
+            return stackLoc;
+        } else {
+            return value;
+        }
+    }
+
+    private CiValue defSlot(CiValue value) {
+        if (isVariable(value)) {
+            Debug.log("    assignSlot %s", value);
+            Location stackLoc = new Location(asVariable(value), frameMap.allocateSpillSlot(value.kind));
+            assert curStackLocations.get(asVariable(value)) == null;
+            curStackLocations.put(stackLoc);
+            Debug.log("      slot %s", stackLoc);
+            return stackLoc;
+        } else {
+            return value;
+        }
+    }
+
+    private Location allocateRegister(final Variable variable, final Object[] inRegisterState, final Object[] outRegisterState, OperandMode mode, EnumSet<OperandFlag> flags) {
+        if (flags.contains(OperandFlag.RegisterHint)) {
+            CiValue result = curInstruction.forEachRegisterHint(variable, mode, new ValueProcedure() {
+                @Override
+                public CiValue doValue(CiValue registerHint) {
+                    Debug.log("      registerHint %s", registerHint);
+                    CiRegister hint = null;
+                    if (isRegister(registerHint)) {
+                        hint = asRegister(registerHint);
+                    } else if (isLocation(registerHint) && isRegister(asLocation(registerHint).location)) {
+                        hint = asRegister(asLocation(registerHint).location);
+                    }
+                    if (hint != null && hint.isSet(variable.flag) && isFree(hint, inRegisterState, outRegisterState)) {
+                        return selectRegister(hint, variable, inRegisterState, outRegisterState);
+                    }
+                    return null;
+                }
+            });
+
+            if (result != null) {
+                return asLocation(result);
+            }
+        }
+
+        EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
+        CiRegister[] availableRegs = categorizedRegs.get(variable.flag);
+
+        for (CiRegister reg : availableRegs) {
+            if (isFree(reg, inRegisterState, outRegisterState)) {
+                return selectRegister(reg, variable, inRegisterState, outRegisterState);
+            }
+
+        }
+        throw new CiBailout("No register found");
+    }
+
+    private static boolean isFree(CiRegister reg, Object[] inRegisterState, Object[] outRegisterState) {
+        return (inRegisterState == null || inRegisterState[reg.number] == null) && (outRegisterState == null || outRegisterState[reg.number] == null);
+    }
+
+    private Location selectRegister(CiRegister reg, Variable variable, Object[] inRegisterState, Object[] outRegisterState) {
+        Location loc = new Location(variable, reg.asValue(variable.kind));
+        if (inRegisterState != null) {
+            inRegisterState[reg.number] = loc;
+        }
+        if (outRegisterState != null) {
+            outRegisterState[reg.number] = loc;
+        }
+        assert curRegisterLocations.get(variable) == null;
+        curRegisterLocations.put(loc);
+        Debug.log("      selected register %s", loc);
+        return loc;
+    }
+
+    private boolean checkInputState(final Block block) {
+        final BitSet liveState = new BitSet();
+        curStackLocations.forEachLocation(new ValueProcedure() {
+            @Override
+            public CiValue doValue(CiValue value) {
+                liveState.set(asLocation(value).variable.index);
+
+                for (Block pred : block.getPredecessors()) {
+                    LocationMap predState = locationsFor(pred);
+                    if (predState != null) {
+                        assert predState.get(asLocation(value).variable) == value;
+                    } else {
+                        assert block.isLoopHeader();
+                    }
+                }
+                return value;
+            }
+        });
+        assert liveState.equals(curLiveIn);
+        return true;
+    }
+
+    private boolean checkNoCallerSavedRegister() {
+        for (CiRegister reg : frameMap.registerConfig.getCallerSaveRegisters()) {
+            assert curOutRegisterState[reg.number] == null || curOutRegisterState[reg.number] == curInstruction : "caller saved register in use accross call site";
+        }
+        return true;
+    }
+
+    private static boolean checkEmpty(Object[] array) {
+        for (Object o : array) {
+            assert o == null;
+        }
+        return true;
+    }
+
+
+    private String logCurrentState() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("  curVariableLocations: ");
+        curStackLocations.forEachLocation(new ValueProcedure() {
+            @Override
+            public CiValue doValue(CiValue value) {
+                sb.append(value).append(" ");
+                return value;
+            }
+        });
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/util/IntervalPrinter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2012, 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.max.graal.alloc.util;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.max.graal.alloc.util.LocationUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.alloc.simple.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+public final class IntervalPrinter {
+
+    public static void printBeforeAllocation(String label, LIR lir, RiRegisterConfig registerConfig, DataFlowAnalysis dataFlow) {
+        if (Debug.isDumpEnabled()) {
+            IntervalPrinter printer = new IntervalPrinter(lir, registerConfig, dataFlow, null);
+            Debug.dump(lir, label);
+            Debug.dump(printer.execute(), label);
+        }
+    }
+
+    public static void printAfterAllocation(String label, LIR lir, RiRegisterConfig registerConfig, DataFlowAnalysis dataFlow, LocationMap[] blockEndLocations) {
+        if (Debug.isDumpEnabled()) {
+            IntervalPrinter printer = new IntervalPrinter(lir, registerConfig, dataFlow, blockEndLocations);
+            Debug.dump(lir, label);
+            Debug.dump(printer.execute(), label);
+        }
+    }
+
+
+    public static class Range {
+        public final int from;
+        public final int to;
+
+        public Range(int from, int to) {
+            this.from = from;
+            this.to = to;
+        }
+    }
+
+    public static class UsePosition {
+        public final int pos;
+        public final String kind;
+
+        public UsePosition(int pos, String kind) {
+            this.pos = pos;
+            this.kind = kind;
+        }
+    }
+
+    public static class Interval {
+        public final String name;
+        public final String description;
+        public final String variable;
+        public final String type;
+        public final List<Range> ranges;
+        public final List<UsePosition> uses;
+
+        protected final int orderNum;
+        protected int lastTo;
+
+        public Interval(int orderNum, String name, String description, String variable, String type) {
+            this.orderNum = orderNum;
+            this.name = name;
+            this.description = description;
+            this.variable = variable;
+            this.type = type;
+            this.ranges = new ArrayList<>();
+            this.uses = new ArrayList<>();
+        }
+    }
+
+
+    private final LIR lir;
+    private final RiRegisterConfig registerConfig;
+    private final DataFlowAnalysis dataFlow;
+    private final LocationMap[] blockEndLocations;
+    private final Variable[] variables;
+    private final Map<String, Interval> intervals;
+
+    private IntervalPrinter(LIR lir, RiRegisterConfig registerConfig, DataFlowAnalysis dataFlow, LocationMap[] blockEndLocations) {
+        this.lir = lir;
+        this.registerConfig = registerConfig;
+        this.dataFlow = dataFlow;
+        this.blockEndLocations = blockEndLocations;
+        this.variables = new Variable[lir.numVariables()];
+        this.intervals = new HashMap<>();
+    }
+
+    private boolean isAllocatableRegister(CiValue value) {
+        return isRegister(value) && registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+    }
+
+    private int curOpId;
+    private String curUseKind;
+
+    public Interval[] execute() {
+        ValueProcedure varProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return var(value); } };
+
+        for (Block block : lir.linearScanOrder()) {
+            for (LIRInstruction op : block.lir) {
+                op.forEachOutput(varProc);
+            }
+        }
+
+        ValueProcedure useProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return use(value, mode, flags); } };
+        ValueProcedure defProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return def(value, flags); } };
+
+        intervals.put("call", new Interval(-2, "call", "", "call", "hasCall"));
+        intervals.put("st", new Interval(-1, "st", "", "st", "hasState"));
+
+        for (int i = lir.linearScanOrder().size() - 1; i >= 0; i--) {
+            Block block = lir.linearScanOrder().get(i);
+
+            curOpId = block.getLastLirInstructionId() + 2;
+            for (Block sux : block.getSuccessors()) {
+                BitSet suxIn = dataFlow.liveIn(sux);
+                for (int idx = suxIn.nextSetBit(0); idx >= 0; idx = suxIn.nextSetBit(idx + 1)) {
+                    if (blockEndLocations != null) {
+                        out(blockEndLocations[block.getId()].get(variables[idx]));
+                    } else {
+                        out(variables[idx]);
+                    }
+                }
+            }
+
+            for (int j = block.lir.size() - 1; j >= 0; j--) {
+                LIRInstruction op = block.lir.get(j);
+                if (op.id() >= 0) {
+                    curOpId = op.id();
+                } else {
+                    curOpId = (curOpId - 1) | 1;
+                }
+
+                op.forEachOutput(defProc);
+                op.forEachTemp(defProc);
+                op.forEachInput(useProc);
+                op.forEachAlive(useProc);
+                curUseKind = "L";
+                op.forEachState(useProc);
+                curUseKind = null;
+
+                if (op.hasCall()) {
+                    intervals.get("call").ranges.add(new Range(curOpId, curOpId + 1));
+                }
+                if (op.info != null) {
+                    intervals.get("st").ranges.add(new Range(curOpId, curOpId + 1));
+                }
+            }
+
+            for (Interval interval : intervals.values()) {
+                if (interval.lastTo != 0) {
+                    interval.ranges.add(new Range(block.getFirstLirInstructionId(), interval.lastTo));
+                    interval.lastTo = 0;
+                }
+            }
+        }
+
+        Interval[] intervalsArray = intervals.values().toArray(new Interval[0]);
+        Arrays.sort(intervalsArray, new Comparator<Interval>() {
+            @Override
+            public int compare(Interval o1, Interval o2) {
+                return o1.orderNum - o2.orderNum;
+            }
+        });
+        return intervalsArray;
+    }
+
+    public CiValue var(CiValue value) {
+        if (isLocation(value)) {
+            variables[asLocation(value).variable.index] = asLocation(value).variable;
+        } else if (isVariable(value)) {
+            variables[asVariable(value).index] = asVariable(value);
+        }
+        return value;
+    }
+
+    private Interval findInterval(CiValue value) {
+        Interval interval;
+        if (isLocation(value)) {
+            Interval parent = findInterval(asLocation(value).variable);
+            String name = "v" + asLocation(value).variable.index + ":" + asLocation(value).location;
+            String description = isStackSlot(asLocation(value).location) ? "stack" : "";
+            interval = new Interval(asLocation(value).variable.index * 2 + 1001, name, description, parent.name, value.kind.javaName);
+
+        } else if (isVariable(value)) {
+            interval = new Interval(asVariable(value).index * 2 + 1000, value.toString(), "", value.toString(), value.kind.javaName);
+
+        } else if (isAllocatableRegister(value)) {
+            interval = new Interval(asRegister(value).number, asRegister(value).toString(), "", asRegister(value).toString(), "fixed");
+
+        } else {
+            return null;
+        }
+
+        Interval existing = intervals.get(interval.name);
+        if (existing != null) {
+            return existing;
+        }
+        intervals.put(interval.name, interval);
+        return interval;
+    }
+
+    private String useKind(EnumSet<OperandFlag> flags) {
+        if (curUseKind != null) {
+            return curUseKind;
+        } else if (flags.contains(OperandFlag.Stack)) {
+            return "S";
+        } else {
+            return "M";
+        }
+    }
+
+    private CiValue use(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+        Interval interval = findInterval(value);
+        if (interval != null) {
+            if (interval.uses.size() == 0 || interval.uses.get(interval.uses.size() - 1).pos != curOpId) {
+                interval.uses.add(new UsePosition(curOpId, useKind(flags)));
+            }
+            if (interval.lastTo == 0) {
+                interval.lastTo = curOpId + (mode == OperandMode.Alive ? 1 : 0);
+            }
+        }
+        return value;
+    }
+
+    private CiValue def(CiValue value, EnumSet<OperandFlag> flags) {
+        Interval interval = findInterval(value);
+        if (interval != null) {
+            interval.uses.add(new UsePosition(curOpId, useKind(flags)));
+            if (interval.lastTo == 0) {
+                interval.ranges.add(new Range(curOpId, curOpId + 1));
+            } else {
+                interval.ranges.add(new Range(curOpId, interval.lastTo));
+            }
+            interval.lastTo = 0;
+        }
+        return value;
+    }
+
+    private CiValue out(CiValue value) {
+        Interval interval = findInterval(value);
+        if (interval != null) {
+            interval.lastTo = curOpId;
+        }
+        return value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/util/Location.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.alloc.util;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.lir.*;
+
+public class Location extends CiValue {
+    private static final long serialVersionUID = -1786677729152726126L;
+
+    public final Variable variable;
+    public final CiValue location;
+
+    public Location(Variable variable, CiValue location) {
+        super(variable.kind);
+        this.variable = variable;
+        this.location = location;
+
+        assert variable.kind == location.kind;
+    }
+
+    @Override
+    public String toString() {
+        return variable + "[" + location + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/util/LocationMap.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.alloc.util;
+
+import static com.oracle.max.graal.alloc.util.LocationUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+
+public class LocationMap {
+    private final Location[] locations;
+
+    public LocationMap(int numVariables) {
+        locations = new Location[numVariables];
+    }
+
+    public LocationMap(LocationMap template) {
+        locations = Arrays.copyOf(template.locations, template.locations.length);
+    }
+
+    public Location get(Variable variable) {
+        assert locations[variable.index] == null || locations[variable.index].variable == variable;
+        return locations[variable.index];
+    }
+
+    public void put(Location location) {
+        locations[location.variable.index] = location;
+    }
+
+    public void clear(Variable variable) {
+        locations[variable.index] = null;
+    }
+
+    public void forEachLocation(ValueProcedure proc) {
+        for (int i = 0; i < locations.length; i++) {
+            if (locations[i] != null) {
+                CiValue newValue = proc.doValue(locations[i], null, null);
+                assert newValue == null || asLocation(newValue).variable == locations[i].variable;
+                locations[i] = (Location) newValue;
+            }
+        }
+    }
+
+    public boolean checkEmpty() {
+        for (int i = 0; i < locations.length; i++) {
+            assert locations[i] == null;
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/util/LocationUtil.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.alloc.util;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.lir.*;
+
+public class LocationUtil extends ValueUtil {
+
+    public static boolean isLocation(CiValue value) {
+        assert value != null;
+        return value instanceof Location;
+    }
+
+    public static Location asLocation(CiValue value) {
+        assert value != null;
+        return (Location) value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/util/MoveResolver.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.alloc.util;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.max.graal.alloc.util.LocationUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+
+public abstract class MoveResolver {
+    private final LIR lir;
+    private final FrameMap frameMap;
+    private final int[] registersBlocked;
+    private final Map<CiValue, Integer> valuesBlocked;
+    private final List<CiValue> mappingFrom;
+    private final List<Location> mappingTo;
+    private final LIRInsertionBuffer insertionBuffer;
+    private int insertPos;
+
+    public MoveResolver(LIR lir, FrameMap frameMap) {
+        this.lir = lir;
+        this.frameMap = frameMap;
+
+        registersBlocked = new int[frameMap.target.arch.registers.length];
+        valuesBlocked = new HashMap<>();
+
+        mappingFrom = new ArrayList<>();
+        mappingTo = new ArrayList<>();
+        insertionBuffer = new LIRInsertionBuffer();
+        insertPos = -1;
+
+        assert checkEmpty();
+    }
+
+    public void init(List<LIRInstruction> newInsertList, int newInsertPos) {
+        assert checkEmpty();
+
+        if (insertionBuffer.lirList() != newInsertList) {
+            // Block changed, so append insertionBuffer because it is bound to a specific block
+            finish();
+            insertionBuffer.init(newInsertList);
+        }
+        insertPos = newInsertPos;
+
+        assert checkValid();
+    }
+
+    public void add(CiValue from, Location to) {
+        assert checkValid();
+        assert isLocation(from) || isConstant(from);
+        assert from != to;
+
+        Debug.log("mr    add mapping from %s to %s", from, to);
+        mappingFrom.add(from);
+        mappingTo.add(to);
+
+        assert checkValid();
+    }
+
+    public boolean hasMappings() {
+        return mappingFrom.size() > 0;
+    }
+
+    public void resolve() {
+        assert checkValid();
+
+        if (mappingFrom.size() == 1) {
+            // If there is only one mapping, it is trivial that this mapping is safe to resolve.
+            Debug.log("mr    resolve  mappings: %d", mappingFrom.size());
+            insertMove(mappingFrom.get(0), mappingTo.get(0));
+            mappingFrom.remove(0);
+            mappingTo.remove(0);
+        } else if (mappingFrom.size() > 1) {
+            Debug.log("mr    resolve  mappings: %d", mappingFrom.size());
+            doResolve();
+        }
+        insertPos = -1;
+
+        assert checkEmpty();
+    }
+
+    public void finish() {
+        assert checkEmpty();
+
+        if (insertionBuffer.initialized()) {
+            insertionBuffer.finish();
+        }
+
+        assert !insertionBuffer.initialized() : "must be uninitialized now";
+        assert checkEmpty();
+    }
+
+
+    private void doResolve() {
+        // Block all registers and stack slots that are used as inputs of a move.
+        // When a register is blocked, no move to this register is emitted.
+        // This is necessary for detecting cycles in moves.
+        for (CiValue from : mappingFrom) {
+            block(from);
+        }
+
+        while (mappingFrom.size() > 0) {
+            boolean processed = false;
+            for (int i = mappingFrom.size() - 1; i >= 0; i--) {
+                CiValue from = mappingFrom.get(i);
+                Location to = mappingTo.get(i);
+
+                if (safeToProcessMove(from, to)) {
+                    insertMove(from, to);
+                    unblock(from);
+                    mappingFrom.remove(i);
+                    mappingTo.remove(i);
+                    processed = true;
+                }
+            }
+
+            if (!processed) {
+                // No move could be processed because there is a cycle in the move list
+                // (e.g., r1 -> r2, r2 -> r1), so one location must be spilled.
+                spill();
+            }
+        }
+    }
+
+    private void spill() {
+        Location spillCandidate = null;
+        int exchangeCandidate = -1;
+        int exchangeOther = -1;
+
+        for (int i = mappingFrom.size() - 1; i >= 0; i--) {
+            CiValue from = mappingFrom.get(i);
+            Location to = mappingTo.get(i);
+            assert !safeToProcessMove(from, to) : "would not be in this code otherwise";
+
+            if (isConstant(from)) {
+                continue;
+            }
+            CiValue fromLoc = asLocation(from).location;
+
+            // Check if we can insert an exchange to save us from spilling.
+            if (isRegister(fromLoc) && isRegister(to) && asRegister(fromLoc) != asRegister(to) && blockedCount(to) == 1) {
+                for (int j = mappingFrom.size() - 1; j >= 0; j--) {
+                    CiValue possibleOther = mappingFrom.get(j);
+                    if (isLocation(possibleOther)) {
+                        if (asLocation(possibleOther).location == to.location) {
+                            assert exchangeCandidate == -1 : "must not find twice because of blocked check above";
+                            exchangeCandidate = i;
+                            exchangeOther = j;
+                        } else if (i != j && asLocation(possibleOther).location == fromLoc) {
+                            // From is read multiple times, so exchange would be too complicated.
+                            exchangeCandidate = -1;
+                            break;
+                        }
+                    }
+                }
+            }
+
+            if (exchangeCandidate != -1) {
+                // Already found a result, no need to search further
+                break;
+            }
+            if (spillCandidate == null || isStackSlot(spillCandidate.location)) {
+                // this interval cannot be processed now because target is not free
+                spillCandidate = asLocation(from);
+            }
+        }
+
+        if (exchangeCandidate != -1) {
+            Location from = asLocation(mappingFrom.get(exchangeCandidate));
+            Location to = mappingTo.get(exchangeCandidate);
+            Location other = asLocation(mappingFrom.get(exchangeOther));
+
+            Location newOther = new Location(other.variable, from.variable);
+            mappingFrom.set(exchangeOther, newOther);
+
+            insertExchange(newOther, to);
+            unblock(to);
+            mappingFrom.remove(exchangeCandidate);
+            mappingTo.remove(exchangeCandidate);
+
+        } else {
+            assert spillCandidate != null : "no location for spilling found";
+
+            Location spillLocation = new Location(spillCandidate.variable, frameMap.allocateSpillSlot(spillCandidate.kind));
+            insertMove(spillCandidate, spillLocation);
+
+            for (int i = mappingFrom.size() - 1; i >= 0; i--) {
+                if (mappingFrom.get(i) == spillCandidate) {
+                    mappingFrom.set(i, spillLocation);
+                    unblock(spillCandidate);
+                    block(spillLocation);
+                }
+            }
+            assert blockedCount(spillCandidate) == 0 : "register must be unblocked after spilling";
+        }
+    }
+
+    private void block(CiValue value) {
+        if (isLocation(value)) {
+            CiValue location = asLocation(value).location;
+            if (isRegister(location)) {
+                registersBlocked[asRegister(location).number]++;
+            } else {
+                Integer count = valuesBlocked.get(location);
+                valuesBlocked.put(location, count == null ? 1 : count + 1);
+            }
+        }
+    }
+
+    private void unblock(CiValue value) {
+        if (isLocation(value)) {
+            assert blockedCount(asLocation(value)) > 0;
+            CiValue location = asLocation(value).location;
+            if (isRegister(location)) {
+                registersBlocked[asRegister(location).number]--;
+            } else {
+                Integer count = valuesBlocked.remove(location);
+                if (count > 1) {
+                    valuesBlocked.put(location, count - 1);
+                }
+            }
+        }
+    }
+
+    private int blockedCount(Location value) {
+        CiValue location = asLocation(value).location;
+        if (isRegister(location)) {
+            return registersBlocked[asRegister(location).number];
+        } else {
+            Integer count = valuesBlocked.get(location);
+            return count == null ? 0 : count;
+        }
+    }
+
+    private boolean safeToProcessMove(CiValue from, Location to) {
+        int count = blockedCount(to);
+        return count == 0 || (count == 1 && isLocation(from) && asLocation(from).location == to.location);
+    }
+
+    private void insertExchange(Location from, Location to) {
+        Debug.log("mr      XCHG %s, %s", from, to);
+        // TODO create XCHG instruction and use it here
+        insertionBuffer.append(insertPos, null);
+        throw GraalInternalError.unimplemented();
+    }
+
+    private void insertMove(CiValue src, Location dst) {
+        if (isStackSlot(dst.location) && isLocation(src) && isStackSlot(asLocation(src).location)) {
+            // Move between two stack slots. We need a temporary registers. If the allocator can give
+            // us a free register, we need two moves: src->scratch, scratch->dst
+            // If the allocator cannot give us a free register (it returns a Location in this case),
+            // we need to spill the scratch register first, so we need four moves in total.
+
+            CiValue scratch = scratchRegister(dst.variable);
+
+            Location scratchSaved = null;
+            CiValue scratchRegister = scratch;
+            if (isLocation(scratch)) {
+                scratchSaved = new Location(asLocation(scratch).variable, frameMap.allocateSpillSlot(scratch.kind));
+                insertMove(scratch, scratchSaved);
+                scratchRegister = asLocation(scratch).location;
+            }
+            assert isRegister(scratchRegister);
+
+            Location scratchLocation = new Location(dst.variable, scratchRegister);
+            insertMove(src, scratchLocation);
+            insertMove(scratchLocation, dst);
+
+            if (scratchSaved != null) {
+                insertMove(scratchSaved, asLocation(scratch));
+            }
+
+        } else {
+            Debug.log("mr      MOV %s -> %s", src, dst);
+            insertionBuffer.append(insertPos, lir.spillMoveFactory.createMove(dst,  src));
+        }
+    }
+
+    /**
+     * Provides a register that can be used by the move resolver. If the returned value is a
+     * {@link CiRegisterValue}, the register can be overwritten without precautions. If the
+     * returned value is a {@link Location}, it needs to be spilled and rescued itself.
+     */
+    protected abstract CiValue scratchRegister(Variable spilled);
+
+    private boolean checkEmpty() {
+        assert insertPos == -1;
+        assert mappingFrom.size() == 0 && mappingTo.size() == 0;
+        for (int registerBlocked : registersBlocked) {
+            assert registerBlocked == 0;
+        }
+        assert valuesBlocked.size() == 0;
+        return true;
+    }
+
+    private boolean checkValid() {
+        assert insertPos != -1;
+        for (int registerBlocked : registersBlocked) {
+            assert registerBlocked == 0;
+        }
+        assert mappingFrom.size() == mappingTo.size();
+        assert insertionBuffer.initialized() && insertPos != -1;
+
+        for (int i = 0; i < mappingTo.size(); i++) {
+            CiValue from = mappingFrom.get(i);
+            Location to = mappingTo.get(i);
+
+            assert from.kind.stackKind() == to.kind;
+
+            for (int j = i + 1; j < mappingTo.size(); j++) {
+                Location otherTo = mappingTo.get(j);
+                assert to != otherTo && to.variable != otherTo.variable && to.location != otherTo.location : "Cannot write to same location twice";
+            }
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/util/RegisterVerifier.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.alloc.util;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.max.graal.alloc.util.LocationUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+public final class RegisterVerifier {
+    private final FrameMap frameMap;
+
+    /**
+     * All blocks that must be processed.
+     */
+    private final List<Block> workList;
+
+    /**
+     * Saved information of previous check.
+     * <br>
+     * State mapping: mapping from registers and stack slots ({@link CiRegister} and {@link Integer} stack slot offsets) to the
+     * value that is currently contained in there ({@link Location} for operands that were variables; {@link CiRegisterValue} or
+     * {@link CiStackSlot} for operands that used fixed registers or stack slots).
+     */
+    private final Map<Object, CiValue>[] blockStates;
+
+    private void addToWorkList(Block block) {
+        if (!workList.contains(block)) {
+            workList.add(block);
+        }
+    }
+
+    private Map<Object, CiValue> stateFor(Block block) {
+        return blockStates[block.getId()];
+    }
+
+    private void setStateFor(Block block, Map<Object, CiValue> savedState) {
+        blockStates[block.getId()] = savedState;
+    }
+
+    private static Map<Object, CiValue> copy(Map<Object, CiValue> inputState) {
+        return new HashMap<>(inputState);
+    }
+
+    public static boolean verify(LIR lir, FrameMap frameMap) {
+        RegisterVerifier verifier = new RegisterVerifier(lir, frameMap);
+        verifier.verify(lir.cfg.getStartBlock());
+        return true;
+    }
+
+    @SuppressWarnings("unchecked")
+    private RegisterVerifier(LIR lir, FrameMap frameMap) {
+        this.frameMap = frameMap;
+        this.workList = new LinkedList<>();
+        this.blockStates = new Map[lir.linearScanOrder().size()];
+    }
+
+    private Map<Object, CiValue> curInputState;
+
+    private void verify(Block startBlock) {
+        ValueProcedure useProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return use(value, flags); } };
+        ValueProcedure tempProc =   new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return temp(value); } };
+        ValueProcedure outputProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return output(value); } };
+
+        curInputState = new HashMap<>();
+        setStateFor(startBlock, curInputState);
+        addToWorkList(startBlock);
+
+        Debug.log("==== start verify register allocation ====");
+        do {
+            Block block = workList.remove(0);
+
+            // Must copy state because it is modified.
+            curInputState = copy(stateFor(block));
+            Debug.log("start block %s %s", block, block.getLoop());
+            Debug.log(logCurrentState());
+
+            for (LIRInstruction op : block.lir) {
+                Debug.log("  op %d %s", op.id(), op);
+
+                op.forEachInput(useProc);
+                if (op.hasCall()) {
+                    invalidateRegisters();
+                }
+                op.forEachAlive(useProc);
+                op.forEachState(useProc);
+                op.forEachTemp(tempProc);
+                op.forEachOutput(outputProc);
+            }
+
+            for (Block succ : block.getSuccessors()) {
+                processSuccessor(succ);
+            }
+
+            Debug.log("end block %s", block);
+        } while (!workList.isEmpty());
+        Debug.log("==== end verify register allocation ====");
+    }
+
+    private void processSuccessor(Block succ) {
+        Map<Object, CiValue> savedState = stateFor(succ);
+        if (savedState == null) {
+            // Block was not processed before, so set initial inputState.
+            Debug.log("  successor %s: initial visit", succ);
+            setStateFor(succ, copy(curInputState));
+            addToWorkList(succ);
+
+        } else {
+            // This block was already processed before.
+            // Check if new inputState is consistent with savedState.
+            Debug.log("  successor %s: state present", succ);
+            Iterator<Map.Entry<Object, CiValue>> iter = savedState.entrySet().iterator();
+            while (iter.hasNext()) {
+                Map.Entry<Object, CiValue> entry = iter.next();
+                CiValue savedValue = entry.getValue();
+                CiValue inputValue = curInputState.get(entry.getKey());
+
+                if (savedValue != inputValue) {
+                    // Current inputState and previous savedState assume a different value in this register.
+                    // Assume that this register is invalid and remove it from the saved state.
+                    Debug.log("    invalidating %s because it is inconsistent with %s", savedValue, inputValue);
+                    iter.remove();
+                    // Must re-visit this block.
+                    addToWorkList(succ);
+                }
+            }
+        }
+    }
+
+    private void invalidateRegisters() {
+        // Invalidate all caller save registers at calls.
+        Iterator<Object> iter = curInputState.keySet().iterator();
+        while (iter.hasNext()) {
+            Object value1 = iter.next();
+            if (value1 instanceof CiRegister && frameMap.registerConfig.getAttributesMap()[((CiRegister) value1).number].isCallerSave) {
+                Debug.log("    remove caller save register %s", value1);
+                iter.remove();
+            }
+        }
+    }
+
+    /**
+     * Gets the mapping key for a value. The key should be as narrow as possible, e.g., it should not
+     * include the kind of the value because we do not want to distinguish between the same register with
+     * different kinds.
+     */
+    private Object key(CiValue value) {
+        if (isLocation(value)) {
+            return key(asLocation(value).location);
+        } else if (isRegister(value)) {
+            return asRegister(value);
+        } else if (isStackSlot(value)) {
+            return Integer.valueOf(frameMap.offsetForStackSlot(asStackSlot(value)));
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private boolean isIgnoredRegister(CiValue value) {
+        return isRegister(value) && !frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+    }
+
+    private CiValue use(CiValue value, EnumSet<OperandFlag> flags) {
+        if (!isConstant(value) && value != CiValue.IllegalValue && !isIgnoredRegister(value)) {
+            CiValue actual = curInputState.get(key(value));
+            if (actual == null && flags.contains(OperandFlag.Uninitialized)) {
+                // OK, since uninitialized values are allowed explicitly.
+            } else if (value != actual) {
+                Debug.log("Error in register allocation: %s != %s for key %s", value, actual, key(value));
+                Debug.log(logCurrentState());
+                throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+        return value;
+    }
+
+    private CiValue temp(CiValue value) {
+        if (!isConstant(value) && value != CiValue.IllegalValue && !isIgnoredRegister(value)) {
+            Debug.log("    temp %s -> remove key %s", value, key(value));
+            curInputState.remove(key(value));
+        }
+        return value;
+    }
+
+    private CiValue output(CiValue value) {
+        if (value != CiValue.IllegalValue && !isIgnoredRegister(value)) {
+            Debug.log("    output %s -> set key %s", value, key(value));
+            curInputState.put(key(value), value);
+        }
+        return value;
+    }
+
+
+    private String logCurrentState() {
+        ArrayList<Object> keys = new ArrayList<>(curInputState.keySet());
+        Collections.sort(keys, new Comparator<Object>() {
+            @Override
+            public int compare(Object o1, Object o2) {
+                if (o1 instanceof CiRegister) {
+                    if (o2 instanceof CiRegister) {
+                        return ((CiRegister) o1).number - ((CiRegister) o2).number;
+                    } else {
+                        return -1;
+                    }
+                } else {
+                    if (o2 instanceof CiRegister) {
+                        return 1;
+                    } else {
+                        return ((Integer) o1).intValue() - ((Integer) o2).intValue();
+                    }
+                }
+            }
+        });
+
+        StringBuilder sb = new StringBuilder("    state: ");
+        for (Object key : keys) {
+            sb.append(key).append("=").append(curInputState.get(key)).append(" ");
+        }
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.compiler;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.cri.xir.*;
+import com.oracle.max.graal.alloc.simple.*;
+import com.oracle.max.graal.compiler.alloc.*;
+import com.oracle.max.graal.compiler.gen.*;
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.compiler.phases.PhasePlan.PhasePosition;
+import com.oracle.max.graal.compiler.schedule.*;
+import com.oracle.max.graal.compiler.target.*;
+import com.oracle.max.graal.compiler.types.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.asm.*;
+import com.oracle.max.graal.lir.cfg.*;
+import com.oracle.max.graal.nodes.*;
+
+public class GraalCompiler {
+
+    /**
+     * The target that this compiler has been configured for.
+     */
+    public final CiTarget target;
+
+    /**
+     * The runtime that this compiler has been configured for.
+     */
+    public final GraalRuntime runtime;
+
+    /**
+     * The XIR generator that lowers Java operations to machine operations.
+     */
+    public final RiXirGenerator xir;
+
+    /**
+     * The backend that this compiler has been configured for.
+     */
+    public final Backend backend;
+
+    public GraalCompiler(GraalRuntime runtime, CiTarget target, Backend backend, RiXirGenerator xirGen) {
+        this.runtime = runtime;
+        this.target = target;
+        this.xir = xirGen;
+        this.backend = backend;
+    }
+
+    public CiTargetMethod compileMethod(RiResolvedMethod method, int osrBCI, PhasePlan plan) {
+        return compileMethod(method, new StructuredGraph(method), osrBCI, plan);
+    }
+
+    public CiTargetMethod compileMethod(final RiResolvedMethod method, final StructuredGraph graph, int osrBCI, final PhasePlan plan) {
+        if (osrBCI != -1) {
+            throw new CiBailout("No OSR supported");
+        }
+        Debug.dump(this, "compiler");
+        Debug.dump(method, "method");
+
+        return Debug.scope(createScopeName(method), graph, new Callable<CiTargetMethod>() {
+            public CiTargetMethod call() {
+                final CiAssumptions assumptions = GraalOptions.OptAssumptions ? new CiAssumptions() : null;
+                final LIR lir = Debug.scope("FrontEnd", new Callable<LIR>() {
+                    public LIR call() {
+                        return emitHIR(graph, assumptions, plan);
+                    }
+                });
+                final FrameMap frameMap = Debug.scope("BackEnd", lir, new Callable<FrameMap>() {
+                    public FrameMap call() {
+                        return emitLIR(lir, graph, method);
+                    }
+                });
+                return Debug.scope("CodeGen", frameMap, new Callable<CiTargetMethod>() {
+                    public CiTargetMethod call() {
+                        return emitCode(assumptions, method, lir, frameMap);
+                    }
+                });
+            }
+        });
+    }
+
+    private static String createScopeName(RiResolvedMethod method) {
+        if (Debug.isEnabled()) {
+            return String.format("[%s::%s]", createSimpleName(method.holder()), method.name());
+        } else {
+            return null;
+        }
+    }
+
+    private static String createSimpleName(RiResolvedType holder) {
+        String base = holder.name();
+        int slashIndex = base.lastIndexOf('/');
+        if (slashIndex == -1) {
+            slashIndex = 0;
+        }
+        return base.substring(slashIndex + 1, base.length() - 1);
+    }
+
+    /**
+     * Builds the graph, optimizes it.
+     */
+    public LIR emitHIR(StructuredGraph graph, CiAssumptions assumptions, PhasePlan plan) {
+
+        if (graph.start().next() == null) {
+            plan.runPhases(PhasePosition.AFTER_PARSING, graph);
+            new DeadCodeEliminationPhase().apply(graph);
+        } else {
+            Debug.dump(graph, "initial state");
+        }
+
+        new PhiStampPhase().apply(graph);
+
+        if (GraalOptions.ProbabilityAnalysis && graph.start().probability() == 0) {
+            new ComputeProbabilityPhase().apply(graph);
+        }
+
+        if (GraalOptions.Intrinsify) {
+            new IntrinsificationPhase(runtime).apply(graph);
+        }
+
+        if (GraalOptions.PropagateTypes) {
+            if (GraalOptions.OptCanonicalizer) {
+                new CanonicalizerPhase(target, runtime, assumptions).apply(graph);
+            }
+
+            new PropagateTypesPhase(target, runtime, assumptions).apply(graph);
+        }
+
+        if (GraalOptions.Inline && !plan.isPhaseDisabled(InliningPhase.class)) {
+            new InliningPhase(target, runtime, null, assumptions, plan).apply(graph);
+            new DeadCodeEliminationPhase().apply(graph);
+            new PhiStampPhase().apply(graph);
+        }
+
+        if (GraalOptions.OptCanonicalizer) {
+            new CanonicalizerPhase(target, runtime, assumptions).apply(graph);
+        }
+
+        if (GraalOptions.PropagateTypes) {
+            new PropagateTypesPhase(target, runtime, assumptions).apply(graph);
+        }
+
+        plan.runPhases(PhasePosition.HIGH_LEVEL, graph);
+
+        if (GraalOptions.OptLoops) {
+            new SafepointPollingEliminationPhase().apply(graph);
+        }
+
+        if (GraalOptions.EscapeAnalysis && !plan.isPhaseDisabled(EscapeAnalysisPhase.class)) {
+            new EscapeAnalysisPhase(target, runtime, assumptions, plan).apply(graph);
+            new PhiStampPhase().apply(graph);
+            if (GraalOptions.OptCanonicalizer) {
+                new CanonicalizerPhase(target, runtime, assumptions).apply(graph);
+            }
+        }
+
+        if (GraalOptions.OptGVN) {
+            new GlobalValueNumberingPhase().apply(graph);
+        }
+
+        graph.mark();
+        new LoweringPhase(runtime).apply(graph);
+        new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph);
+
+        if (GraalOptions.Lower) {
+            new FloatingReadPhase().apply(graph);
+            if (GraalOptions.OptGVN) {
+                new GlobalValueNumberingPhase().apply(graph);
+            }
+            if (GraalOptions.OptReadElimination) {
+                new ReadEliminationPhase().apply(graph);
+            }
+        }
+        new DeadCodeEliminationPhase().apply(graph);
+
+        plan.runPhases(PhasePosition.MID_LEVEL, graph);
+
+        plan.runPhases(PhasePosition.LOW_LEVEL, graph);
+
+        final SchedulePhase schedule = new SchedulePhase();
+        schedule.apply(graph);
+        Debug.dump(schedule, "final schedule");
+
+        final Block[] blocks = schedule.getCFG().getBlocks();
+        final Block startBlock = schedule.getCFG().getStartBlock();
+        assert startBlock != null;
+        assert startBlock.numberOfPreds() == 0;
+
+        return Debug.scope("Compute Linear Scan Order", new Callable<LIR>() {
+
+            @Override
+            public LIR call() {
+                ComputeLinearScanOrder clso = new ComputeLinearScanOrder(blocks.length, schedule.getCFG().getLoops().length, startBlock);
+                List<Block> linearScanOrder = clso.linearScanOrder();
+                List<Block> codeEmittingOrder = clso.codeEmittingOrder();
+
+                int z = 0;
+                for (Block b : linearScanOrder) {
+                    b.linearScanNumber = z++;
+                }
+
+                LIR lir = new LIR(schedule.getCFG(), schedule.getNodesFor(), linearScanOrder, codeEmittingOrder);
+                Debug.dump(lir, "After linear scan order");
+                return lir;
+
+            }
+        });
+    }
+
+    public FrameMap emitLIR(final LIR lir, StructuredGraph graph, final RiResolvedMethod method) {
+        final FrameMap frameMap = backend.newFrameMap(runtime.getRegisterConfig(method));
+        final LIRGenerator lirGenerator = backend.newLIRGenerator(graph, frameMap, method, lir, xir);
+        Debug.dump(lirGenerator, "LIRGenerator");
+
+        Debug.scope("LIRGen", new Runnable() {
+            public void run() {
+                for (Block b : lir.linearScanOrder()) {
+                    lirGenerator.doBlock(b);
+                }
+
+                Debug.dump(lir, "After LIR generation");
+            }
+        });
+
+        Debug.scope("Allocator", new Runnable() {
+            public void run() {
+                if (GraalOptions.AllocSSA) {
+                    new LinearScanAllocator(lir, frameMap).execute();
+                    // new SpillAllAllocator(context, lir, frameMap).execute();
+                } else {
+                    new LinearScan(target, method, lir, lirGenerator, frameMap).allocate();
+                }
+            }
+        });
+        return frameMap;
+    }
+
+    private TargetMethodAssembler createAssembler(FrameMap frameMap, LIR lir) {
+        AbstractAssembler masm = backend.newAssembler(frameMap.registerConfig);
+        TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime, frameMap, lir.slowPaths, masm);
+        tasm.setFrameSize(frameMap.frameSize());
+        tasm.targetMethod.setCustomStackAreaOffset(frameMap.offsetToCustomArea());
+        return tasm;
+    }
+
+    public CiTargetMethod emitCode(CiAssumptions assumptions, RiResolvedMethod method, LIR lir, FrameMap frameMap) {
+        TargetMethodAssembler tasm = createAssembler(frameMap, lir);
+        lir.emitCode(tasm);
+
+        CiTargetMethod targetMethod = tasm.finishTargetMethod(method, false);
+        if (assumptions != null && !assumptions.isEmpty()) {
+            targetMethod.setAssumptions(assumptions);
+        }
+
+        Debug.dump(lir, "After code generation");
+        Debug.dump(targetMethod, "After code generation");
+        return targetMethod;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.compiler;
+
+/**
+ * This class encapsulates options that control the behavior of the Graal compiler.
+ * The help message for each option is specified by a {@linkplain #helpMap help map}.
+ *
+ * (tw) WARNING: Fields of this class are treated as final by Graal.
+ */
+public final class GraalOptions {
+
+    // Checkstyle: stop
+    private static final boolean ____ = false;
+    // Checkstyle: resume
+
+
+    public static int     Threads                            = 4;
+    public static boolean Lower                              = true;
+
+    // inlining settings
+    public static boolean Inline                             = true;
+    public static boolean Intrinsify                         = true;
+    public static boolean CacheGraphs                        = ____;
+    public static boolean InlineMonomorphicCalls             = true;
+    public static boolean InlinePolymorphicCalls             = true;
+    public static boolean InlineMegamorphicCalls             = ____;
+    public static int     InliningPolicy                     = 4;
+    public static int     WeightComputationPolicy            = 2;
+    public static int     MaximumTrivialSize                 = 10;
+    public static int     MaximumInlineLevel                 = 30;
+    public static int     MaximumDesiredSize                 = 3000;
+    public static int     MaximumRecursiveInlining           = 1;
+    public static int     SmallCompiledCodeSize              = 2000;
+    public static boolean LimitInlinedProbability            = ____;
+    // WeightBasedInliningPolicy (0)
+    public static boolean ParseBeforeInlining                = ____;
+    public static float   InliningSizePenaltyExp             = 20;
+    public static float   MaximumInlineWeight                = 1.25f;
+    public static float   InliningSizePenalty                = 1;
+    // StaticSizeBasedInliningPolicy (1), MinimumCodeSizeBasedInlining (2),
+    // DynamicSizeBasedInliningPolicy (3)
+    public static int     MaximumInlineSize                  = 35;
+    // GreedySizeBasedInlining (4)
+    public static int     MaximumGreedyInlineSize            = 200;
+    // Common options for inlining policies 1 to 4
+    public static float   NestedInliningSizeRatio            = 1f;
+    public static float   BoostInliningForEscapeAnalysis     = 2f;
+    public static float   ProbabilityCapForInlining          = 1f;
+
+    // escape analysis settings
+    public static boolean EscapeAnalysis                     = true;
+    public static int     ForcedInlineEscapeWeight           = 100;
+    public static boolean PrintEscapeAnalysis                = ____;
+
+    // absolute probability analysis
+    public static boolean ProbabilityAnalysis                = true;
+    public static int     LoopFrequencyPropagationPolicy     = 1;
+
+    // profiling information
+    public static int     MatureExecutionsBranch             = 50;
+    public static int     MatureExecutionsPerSwitchCase      = 15;
+    public static int     MatureExecutionsTypeProfile        = 100;
+
+    //rematerialize settings
+    public static float   MinimumUsageProbability            = 0.95f;
+
+    // debugging settings
+    public static int     MethodEndBreakpointGuards          = 0;
+    public static boolean ZapStackOnMethodEntry              = ____;
+    public static boolean StressLinearScan                   = ____;
+    public static boolean DeoptALot                          = ____;
+    public static boolean VerifyPhases                       = true;
+    public static boolean CreateDeoptInfo                    = ____;
+
+    /**
+     * See {@link Filter#Filter(String, Object)}.
+     */
+    public static String  PrintFilter                        = null;
+
+    // printing settings
+    public static boolean PrintLIR                           = ____;
+    public static boolean PrintCFGToFile                     = ____;
+
+    // statistics independent from debug mode
+    public static boolean PrintCompilationStatistics         = ____;
+
+    // Debug settings:
+    public static boolean Debug                              = true;
+    public static boolean SummarizeDebugValues               = ____;
+    public static String Dump                                = null;
+    public static String Meter                               = null;
+    public static String Time                                = null;
+    public static String Log                                 = null;
+    public static String MethodFilter                        = null;
+
+    // Ideal graph visualizer output settings
+    public static boolean PlotOnError                        = ____;
+    public static int     PlotLevel                          = 3;
+    public static boolean PlotSnippets                       = ____;
+    public static int     PrintIdealGraphLevel               = 0;
+    public static boolean PrintIdealGraphFile                = ____;
+    public static String  PrintIdealGraphAddress             = "127.0.0.1";
+    public static int     PrintIdealGraphPort                = 4444;
+
+    // Other printing settings
+    public static boolean PrintQueue                         = ____;
+    public static boolean PrintCompilation                   = ____;
+    public static boolean PrintXirTemplates                  = ____;
+    public static boolean PrintIRWithLIR                     = ____;
+    public static boolean PrintAssembly                      = ____;
+    public static boolean PrintCodeBytes                     = ____;
+    public static int     PrintAssemblyBytesPerLine          = 16;
+    public static int     TraceLinearScanLevel               = 0;
+    public static boolean TraceRegisterAllocation            = false;
+    public static int     TraceLIRGeneratorLevel             = 0;
+    public static boolean TraceEscapeAnalysis                = ____;
+    public static int     TraceBytecodeParserLevel           = 0;
+    public static boolean ExitVMOnBailout                    = ____;
+    public static boolean ExitVMOnException                  = true;
+
+    // state merging settings
+    public static boolean AssumeVerifiedBytecode             = true;
+
+    // Code generator settings
+    public static boolean PropagateTypes                     = ____;
+    public static boolean UseBranchPrediction                = true;
+    public static boolean UseExceptionProbability            = true;
+    public static boolean AllowExplicitExceptionChecks       = true;
+    public static boolean OmitHotExceptionStacktrace         = ____;
+    public static boolean GenSafepoints                      = true;
+    public static boolean GenLoopSafepoints                  = true;
+    public static boolean UseTypeCheckHints                  = true;
+
+    public static boolean GenAssertionCode                   = ____;
+    public static boolean AlignCallsForPatching              = true;
+    public static boolean ResolveClassBeforeStaticInvoke     = true;
+
+    // Translating tableswitch instructions
+    public static int     SequentialSwitchLimit              = 4;
+    public static int     RangeTestsSwitchDensity            = 5;
+
+    public static boolean DetailedAsserts                    = ____;
+
+    // Runtime settings
+    public static int     ReadPrefetchInstr                  = 0;
+    public static int     StackShadowPages                   = 2;
+
+    // Assembler settings
+    public static boolean CommentedAssembly                  = ____;
+    public static boolean PrintLIRWithAssembly               = ____;
+
+    public static boolean SupportJsrBytecodes                = true;
+
+    public static boolean OptAssumptions                     = true;
+    public static boolean OptReadElimination                 = true;
+    public static boolean OptGVN                             = true;
+    public static boolean OptCanonicalizer                   = true;
+    public static boolean OptLoops                           = ____;
+    public static boolean ScheduleOutOfLoops                 = true;
+    public static boolean OptReorderLoops                    = true;
+    public static boolean OptEliminateGuards                 = true;
+    public static boolean OptImplicitNullChecks              = true;
+
+    /**
+     * Flag to turn on SSA-based register allocation, which is currently under development.
+     */
+    public static boolean AllocSSA                           = false;
+
+    static {
+        // turn detailed assertions on when the general assertions are on (misusing the assert keyword for this)
+        assert (DetailedAsserts = true) == true;
+        assert (CommentedAssembly = true) == true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ComputeLinearScanOrder.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,322 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.compiler.alloc;
+
+import java.util.*;
+
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.cfg.*;
+import com.oracle.max.graal.nodes.*;
+
+public final class ComputeLinearScanOrder {
+
+    private int numBlocks; // total number of blocks (smaller than maxBlockId)
+
+    List<Block> linearScanOrder; // the resulting list of blocks in correct order
+    List<Block> codeEmittingOrder;
+
+    final BitMap visitedBlocks; // used for recursive processing of blocks
+    final BitMap activeBlocks; // used for recursive processing of blocks
+    final BitMap dominatorBlocks; // temporary BitMap used for computation of dominator
+    final int[] forwardBranches; // number of incoming forward branches for each block
+    final List<Block> workList; // temporary list (used in markLoops and computeOrder)
+    final Block[] loopHeaders;
+
+    // accessors for visitedBlocks and activeBlocks
+    void initVisited() {
+        activeBlocks.clearAll();
+        visitedBlocks.clearAll();
+    }
+
+    boolean isVisited(Block b) {
+        return visitedBlocks.get(b.getId());
+    }
+
+    boolean isActive(Block b) {
+        return activeBlocks.get(b.getId());
+    }
+
+    void setVisited(Block b) {
+        assert !isVisited(b) : "already set";
+        visitedBlocks.set(b.getId());
+    }
+
+    void setActive(Block b) {
+        assert !isActive(b) : "already set";
+        activeBlocks.set(b.getId());
+    }
+
+    void clearActive(Block b) {
+        assert isActive(b) : "not already";
+        activeBlocks.clear(b.getId());
+    }
+
+    // accessors for forwardBranches
+    void incForwardBranches(Block b) {
+        forwardBranches[b.getId()]++;
+    }
+
+    int decForwardBranches(Block b) {
+        return --forwardBranches[b.getId()];
+    }
+
+    // accessors for final result
+    public List<Block> linearScanOrder() {
+        return linearScanOrder;
+    }
+
+    public ComputeLinearScanOrder(int maxBlockId, int loopCount, Block startBlock) {
+        loopHeaders = new Block[loopCount];
+
+        visitedBlocks = new BitMap(maxBlockId);
+        activeBlocks = new BitMap(maxBlockId);
+        dominatorBlocks = new BitMap(maxBlockId);
+        forwardBranches = new int[maxBlockId];
+        workList = new ArrayList<>(8);
+
+        countEdges(startBlock, null);
+        computeOrder(startBlock);
+    }
+
+    /**
+     * Traverses the CFG to analyze block and edge info. The analysis performed is:
+     *
+     * 1. Count of total number of blocks.
+     * 2. Count of all incoming edges and backward incoming edges.
+     * 3. Number loop header blocks.
+     * 4. Create a list with all loop end blocks.
+     */
+    void countEdges(Block cur, Block parent) {
+        if (GraalOptions.TraceLinearScanLevel >= 3) {
+            TTY.println("Counting edges for block B%d%s", cur.getId(), parent == null ? "" : " coming from B" + parent.getId());
+        }
+
+        if (isActive(cur)) {
+            return;
+        }
+
+        // increment number of incoming forward branches
+        incForwardBranches(cur);
+
+        if (isVisited(cur)) {
+            if (GraalOptions.TraceLinearScanLevel >= 3) {
+                TTY.println("block already visited");
+            }
+            return;
+        }
+
+        numBlocks++;
+        setVisited(cur);
+        setActive(cur);
+
+        // recursive call for all successors
+        int i;
+        for (i = cur.numberOfSux() - 1; i >= 0; i--) {
+            countEdges(cur.suxAt(i), cur);
+        }
+
+        clearActive(cur);
+
+        if (GraalOptions.TraceLinearScanLevel >= 3) {
+            TTY.println("Finished counting edges for block B%d", cur.getId());
+        }
+    }
+
+    static int computeWeight(Block cur) {
+
+        // limit loop-depth to 15 bit (only for security reason, it will never be so big)
+        int weight = (cur.getLoopDepth() & 0x7FFF) << 16;
+
+        int curBit = 15;
+
+        // this is necessary for the (very rare) case that two successive blocks have
+        // the same loop depth, but a different loop index (can happen for endless loops
+        // with exception handlers)
+//        if (!cur.isLinearScanLoopHeader()) {
+//            weight |= 1 << curBit;
+//        }
+//        curBit--;
+
+        // loop end blocks (blocks that end with a backward branch) are added
+        // after all other blocks of the loop.
+        if (!cur.isLoopEnd()) {
+            weight |= 1 << curBit;
+        }
+        curBit--;
+
+        // critical edge split blocks are preferred because then they have a greater
+        // probability to be completely empty
+        //if (cur.isCriticalEdgeSplit()) {
+        //    weight |= 1 << curBit;
+        //}
+        //curBit--;
+
+        // exceptions should not be thrown in normal control flow, so these blocks
+        // are added as late as possible
+//        if (!(cur.end() instanceof Throw) && (singleSux == null || !(singleSux.end() instanceof Throw))) {
+//            weight |= 1 << curBit;
+//        }
+//        curBit--;
+//        if (!(cur.end() instanceof Return) && (singleSux == null || !(singleSux.end() instanceof Return))) {
+//            weight |= 1 << curBit;
+//        }
+//        curBit--;
+
+        // exceptions handlers are added as late as possible
+        if (!cur.isExceptionEntry()) {
+            weight |= 1 << curBit;
+        }
+        curBit--;
+
+        // guarantee that weight is > 0
+        weight |= 1;
+
+        assert curBit >= 0 : "too many flags";
+        assert weight > 0 : "weight cannot become negative";
+
+        return weight;
+    }
+
+    private boolean readyForProcessing(Block cur) {
+        // Discount the edge just traveled.
+        // When the number drops to zero, all forward branches were processed
+        if (decForwardBranches(cur) != 0) {
+            return false;
+        }
+
+        assert !linearScanOrder.contains(cur) : "block already processed (block can be ready only once)";
+        assert !workList.contains(cur) : "block already in work-list (block can be ready only once)";
+        return true;
+    }
+
+    private void sortIntoWorkList(Block cur) {
+        assert !workList.contains(cur) : "block already in work list";
+
+        int curWeight = computeWeight(cur);
+
+        // the linearScanNumber is used to cache the weight of a block
+        cur.linearScanNumber = curWeight;
+
+        if (GraalOptions.StressLinearScan) {
+            workList.add(0, cur);
+            return;
+        }
+
+        workList.add(null); // provide space for new element
+
+        int insertIdx = workList.size() - 1;
+        while (insertIdx > 0 && workList.get(insertIdx - 1).linearScanNumber > curWeight) {
+            workList.set(insertIdx, workList.get(insertIdx - 1));
+            insertIdx--;
+        }
+        workList.set(insertIdx, cur);
+
+        if (GraalOptions.TraceLinearScanLevel >= 3) {
+            TTY.println("Sorted B%d into worklist. new worklist:", cur.getId());
+            for (int i = 0; i < workList.size(); i++) {
+                TTY.println(String.format("%8d B%02d  weight:%6x", i, workList.get(i).getId(), workList.get(i).linearScanNumber));
+            }
+        }
+
+        for (int i = 0; i < workList.size(); i++) {
+            assert workList.get(i).linearScanNumber > 0 : "weight not set";
+            assert i == 0 || workList.get(i - 1).linearScanNumber <= workList.get(i).linearScanNumber : "incorrect order in worklist";
+        }
+    }
+
+    private void appendBlock(Block cur) {
+        if (GraalOptions.TraceLinearScanLevel >= 3) {
+            TTY.println("appending block B%d (weight 0x%06x) to linear-scan order", cur.getId(), cur.linearScanNumber);
+        }
+        assert !linearScanOrder.contains(cur) : "cannot add the same block twice";
+
+        // currently, the linear scan order and code emit order are equal.
+        // therefore the linearScanNumber and the weight of a block must also
+        // be equal.
+        cur.linearScanNumber = linearScanOrder.size();
+        linearScanOrder.add(cur);
+
+        if (cur.isLoopEnd() && cur.isLoopHeader()) {
+            codeEmittingOrder.add(cur);
+        } else {
+            if (!cur.isLoopHeader() || ((LoopBeginNode) cur.getBeginNode()).loopEnds().count() > 1 || !GraalOptions.OptReorderLoops) {
+                codeEmittingOrder.add(cur);
+
+                if (cur.isLoopEnd() && GraalOptions.OptReorderLoops) {
+                    Block loopHeader = loopHeaders[cur.getLoop().index];
+                    if (loopHeader != null) {
+                        codeEmittingOrder.add(loopHeader);
+
+                        for (int i = 0; i < loopHeader.numberOfSux(); i++) {
+                            Block succ = loopHeader.suxAt(i);
+                            if (succ.getLoopDepth() == loopHeader.getLoopDepth()) {
+                                succ.align = true;
+                            }
+                        }
+                    }
+                }
+            } else {
+                loopHeaders[cur.getLoop().index] = cur;
+            }
+        }
+    }
+
+    private void computeOrder(Block startBlock) {
+        if (GraalOptions.TraceLinearScanLevel >= 3) {
+            TTY.println("----- computing final block order");
+        }
+
+        // the start block is always the first block in the linear scan order
+        linearScanOrder = new ArrayList<>(numBlocks);
+
+        codeEmittingOrder = new ArrayList<>(numBlocks);
+
+        // start processing with standard entry block
+        assert workList.isEmpty() : "list must be empty before processing";
+
+        assert readyForProcessing(startBlock);
+        sortIntoWorkList(startBlock);
+
+        do {
+            Block cur = workList.remove(workList.size() - 1);
+            appendBlock(cur);
+
+            int i;
+            int numSux = cur.numberOfSux();
+            // changed loop order to get "intuitive" order of if- and else-blocks
+            for (i = 0; i < numSux; i++) {
+                Block sux = cur.suxAt(i);
+                if (readyForProcessing(sux)) {
+                    sortIntoWorkList(sux);
+                }
+            }
+        } while (workList.size() > 0);
+    }
+
+    public List<Block> codeEmittingOrder() {
+        return codeEmittingOrder;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.compiler.alloc;
+
+import java.util.*;
+
+import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+/**
+ * This class performs basic optimizations on the control flow graph after LIR generation.
+ */
+final class ControlFlowOptimizer {
+
+    /**
+     * Performs control flow optimizations on the given LIR graph.
+     * @param ir the LIR graph that should be optimized
+     */
+    public static void optimize(LIR ir) {
+        ControlFlowOptimizer optimizer = new ControlFlowOptimizer(ir);
+        List<Block> code = ir.codeEmittingOrder();
+        //optimizer.reorderShortLoops(code);
+        optimizer.deleteEmptyBlocks(code);
+        ControlFlowOptimizer.deleteUnnecessaryJumps(code);
+        //ControlFlowOptimizer.deleteJumpsToReturn(code);
+    }
+
+    private final LIR ir;
+
+    private ControlFlowOptimizer(LIR ir) {
+        this.ir = ir;
+    }
+/*
+    private void reorderShortLoop(List<LIRBlock> code, LIRBlock headerBlock, int headerIdx) {
+        int i = headerIdx + 1;
+        int maxEnd = Math.min(headerIdx + GraalOptions.MaximumShortLoopSize, code.size());
+        while (i < maxEnd && code.get(i).loopDepth() >= headerBlock.loopDepth()) {
+            i++;
+        }
+
+        if (i == code.size() || code.get(i).loopDepth() < headerBlock.loopDepth()) {
+            int endIdx = i - 1;
+            LIRBlock endBlock = code.get(endIdx);
+
+            if (endBlock.numberOfSux() == 1 && endBlock.suxAt(0) == headerBlock) {
+                // short loop from headerIdx to endIdx found . reorder blocks such that
+                // the headerBlock is the last block instead of the first block of the loop
+
+                for (int j = headerIdx; j < endIdx; j++) {
+                    code.set(j, code.get(j + 1));
+                }
+                code.set(endIdx, headerBlock);
+            }
+        }
+    }*/
+/*
+    private void reorderShortLoops(List<LIRBlock> code) {
+        for (int i = code.size() - 1; i >= 0; i--) {
+            LIRBlock block = code.get(i);
+
+            if (block.isLinearScanLoopHeader()) {
+                reorderShortLoop(code, block, i);
+            }
+        }
+
+        assert verify(code);
+    }*/
+
+    // only blocks with exactly one successor can be deleted. Such blocks
+    // must always end with an unconditional branch to its successor
+    private boolean canDeleteBlock(Block block) {
+        if (block.numberOfSux() != 1 ||
+            block == ir.cfg.getStartBlock() ||
+            block.suxAt(0) == block) {
+            return false;
+        }
+
+        List<LIRInstruction> instructions = block.lir;
+
+        assert instructions.size() >= 2 : "block must have label and branch";
+        assert instructions.get(0) instanceof StandardOp.LabelOp : "first instruction must always be a label";
+        assert instructions.get(instructions.size() - 1) instanceof StandardOp.JumpOp : "last instruction must always be a branch";
+        assert ((StandardOp.JumpOp) instructions.get(instructions.size() - 1)).destination().label() == ((StandardOp.LabelOp) block.suxAt(0).lir.get(0)).getLabel() : "branch target must be the successor";
+
+        // block must have exactly one successor
+
+        return instructions.size() == 2 && instructions.get(instructions.size() - 1).info == null;
+    }
+
+    private void deleteEmptyBlocks(List<Block> code) {
+        int oldPos = 0;
+        int newPos = 0;
+        int numBlocks = code.size();
+
+        assert verify(code);
+        while (oldPos < numBlocks) {
+            Block block = code.get(oldPos);
+
+            if (canDeleteBlock(block)) {
+                // adjust successor and predecessor lists
+                Block other = block.suxAt(0);
+                for (Block pred : block.getPredecessors()) {
+                    Util.replaceAllInList(block, other, pred.getSuccessors());
+                }
+                for (int i = 0; i < other.getPredecessors().size(); i++) {
+                    if (other.getPredecessors().get(i) == block) {
+                        other.getPredecessors().remove(i);
+                        other.getPredecessors().addAll(i, block.getPredecessors());
+                    }
+                }
+                block.getSuccessors().clear();
+                block.getPredecessors().clear();
+                Debug.metric("BlocksDeleted").increment();
+            } else {
+                // adjust position of this block in the block list if blocks before
+                // have been deleted
+                if (newPos != oldPos) {
+                    code.set(newPos, code.get(oldPos));
+                }
+                newPos++;
+            }
+            oldPos++;
+        }
+        assert verify(code);
+        Util.truncate(code, newPos);
+
+        assert verify(code);
+    }
+
+    private static void deleteUnnecessaryJumps(List<Block> code) {
+        // skip the last block because there a branch is always necessary
+        for (int i = code.size() - 2; i >= 0; i--) {
+            Block block = code.get(i);
+            List<LIRInstruction> instructions = block.lir;
+
+            LIRInstruction lastOp = instructions.get(instructions.size() - 1);
+            if (lastOp instanceof StandardOp.JumpOp) {
+                StandardOp.JumpOp lastJump = (StandardOp.JumpOp) lastOp;
+
+                if (lastOp.info == null) {
+                    if (lastJump.destination().label() == ((StandardOp.LabelOp) code.get(i + 1).lir.get(0)).getLabel()) {
+                        // delete last branch instruction
+                        Util.truncate(instructions, instructions.size() - 1);
+
+                    } else {
+                        LIRInstruction prevOp = instructions.get(instructions.size() - 2);
+                        if (prevOp instanceof StandardOp.BranchOp) {
+                            StandardOp.BranchOp prevBranch = (StandardOp.BranchOp) prevOp;
+
+                            if (prevBranch.destination().label() == ((StandardOp.LabelOp) code.get(i + 1).lir.get(0)).getLabel() && prevOp.info == null) {
+                                // eliminate a conditional branch to the immediate successor
+                                prevBranch.negate(lastJump.destination());
+                                Util.truncate(instructions, instructions.size() - 1);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        assert verify(code);
+    }
+
+/*
+    private static void deleteJumpsToReturn(List<LIRBlock> code) {
+        for (int i = code.size() - 1; i >= 0; i--) {
+            LIRBlock block = code.get(i);
+            List<LIRInstruction> curInstructions = block.lir();
+            LIRInstruction curLastOp = curInstructions.get(curInstructions.size() - 1);
+
+            assert curInstructions.get(0).code == StandardOpcode.LABEL : "first instruction must always be a label";
+            if (curInstructions.size() == 2 && curLastOp.code == StandardOpcode.RETURN) {
+                // the block contains only a label and a return
+                // if a predecessor ends with an unconditional jump to this block, then the jump
+                // can be replaced with a return instruction
+                //
+                // Note: the original block with only a return statement cannot be deleted completely
+                // because the predecessors might have other (conditional) jumps to this block.
+                // this may lead to unnecesary return instructions in the final code
+
+                assert curLastOp.info == null : "return instructions do not have debug information";
+                CiValue returnOpr = curLastOp.input(0);
+
+                for (int j = block.numberOfPreds() - 1; j >= 0; j--) {
+                    LIRBlock pred = block.predAt(j);
+                    List<LIRInstruction> predInstructions = pred.lir();
+                    LIRInstruction predLastOp = predInstructions.get(predInstructions.size() - 1);
+
+                    if (predLastOp instanceof LIRBranch) {
+                        LIRBranch predLastBranch = (LIRBranch) predLastOp;
+
+                        if (predLastBranch.destination().label() == block.label() && predLastBranch.code == StandardOpcode.JUMP && predLastBranch.info == null) {
+                            // replace the jump to a return with a direct return
+                            // Note: currently the edge between the blocks is not deleted
+                            predInstructions.set(predInstructions.size() - 1, StandardOpcode.RETURN.create(returnOpr));
+                        }
+                    }
+                }
+            }
+        }
+    }
+*/
+
+    private static boolean verify(List<Block> code) {
+        for (Block block : code) {
+            for (Block sux : block.getSuccessors()) {
+                assert code.contains(sux) : "missing successor from: " + block + "to: " + sux;
+            }
+
+            for (Block pred : block.getPredecessors()) {
+                assert code.contains(pred) : "missing predecessor from: " + block + "to: " + pred;
+            }
+        }
+
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.compiler.alloc;
+
+import java.util.*;
+
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.StandardOp.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+/**
+ * This class optimizes moves, particularly those that result from eliminating SSA form.
+ *
+ * When a block has more than one predecessor, and all predecessors end with
+ * the {@linkplain #same(LIRInstruction, LIRInstruction) same} sequence of
+ * {@linkplain LIROpcode#Move move} instructions, then these sequences
+ * can be replaced with a single copy of the sequence at the beginning of the block.
+ *
+ * Similarly, when a block has more than one successor, then same sequences of
+ * moves at the beginning of the successors can be placed once at the end of
+ * the block. But because the moves must be inserted before all branch
+ * instructions, this works only when there is exactly one conditional branch
+ * at the end of the block (because the moves must be inserted before all
+ * branches, but after all compares).
+ *
+ * This optimization affects all kind of moves (reg->reg, reg->stack and
+ * stack->reg). Because this optimization works best when a block contains only
+ * a few moves, it has a huge impact on the number of blocks that are totally
+ * empty.
+ */
+final class EdgeMoveOptimizer {
+
+    /**
+     * Optimizes moves on block edges.
+     *
+     * @param blockList a list of blocks whose moves should be optimized
+     */
+    public static void optimize(List<Block> blockList) {
+        EdgeMoveOptimizer optimizer = new EdgeMoveOptimizer();
+
+        // ignore the first block in the list (index 0 is not processed)
+        for (int i = blockList.size() - 1; i >= 1; i--) {
+            Block block = blockList.get(i);
+
+            if (block.numberOfPreds() > 1) {
+                optimizer.optimizeMovesAtBlockEnd(block);
+            }
+            if (block.numberOfSux() == 2) {
+                optimizer.optimizeMovesAtBlockBegin(block);
+            }
+        }
+    }
+
+    private final List<List<LIRInstruction>> edgeInstructionSeqences;
+
+    private EdgeMoveOptimizer() {
+        edgeInstructionSeqences = new ArrayList<>(4);
+    }
+
+    /**
+     * Determines if two operations are both {@linkplain LIROpcode#Move moves}
+     * that have the same {@linkplain LIRInstruction#operand() source} and {@linkplain LIRInstruction#result() destination}
+     * operands and they have the same {@linkplain LIRInstruction#info debug info}.
+     *
+     * @param op1 the first instruction to compare
+     * @param op2 the second instruction to compare
+     * @return {@code true} if {@code op1} and {@code op2} are the same by the above algorithm
+     */
+    private static boolean same(LIRInstruction op1, LIRInstruction op2) {
+        assert op1 != null;
+        assert op2 != null;
+
+        if (op1 instanceof MoveOp && op2 instanceof MoveOp) {
+            MoveOp move1 = (MoveOp) op1;
+            MoveOp move2 = (MoveOp) op2;
+            if (move1.getInput() == move2.getInput() && move1.getResult() == move2.getResult()) {
+                // these moves are exactly equal and can be optimized
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Moves the longest {@linkplain #same common} subsequence at the end all
+     * predecessors of {@code block} to the start of {@code block}.
+     */
+    private void optimizeMovesAtBlockEnd(Block block) {
+        for (Block pred : block.getPredecessors()) {
+            if (pred == block) {
+                // currently we can't handle this correctly.
+                return;
+            }
+        }
+
+        // clear all internal data structures
+        edgeInstructionSeqences.clear();
+
+        int numPreds = block.numberOfPreds();
+        assert numPreds > 1 : "do not call otherwise";
+
+        // setup a list with the LIR instructions of all predecessors
+        for (Block pred : block.getPredecessors()) {
+            assert pred != null;
+            assert pred.lir != null;
+            List<LIRInstruction> predInstructions = pred.lir;
+
+            if (pred.numberOfSux() != 1) {
+                // this can happen with switch-statements where multiple edges are between
+                // the same blocks.
+                return;
+            }
+
+            if (predInstructions.get(predInstructions.size() - 1) instanceof LIRXirInstruction) {
+                return;
+            }
+
+            assert pred.suxAt(0) == block : "invalid control flow";
+            assert predInstructions.get(predInstructions.size() - 1) instanceof StandardOp.JumpOp : "block must end with unconditional jump";
+
+            if (predInstructions.get(predInstructions.size() - 1).info != null) {
+                // can not optimize instructions that have debug info
+                return;
+            }
+
+            // ignore the unconditional branch at the end of the block
+            List<LIRInstruction> seq = predInstructions.subList(0, predInstructions.size() - 1);
+            edgeInstructionSeqences.add(seq);
+        }
+
+        // process lir-instructions while all predecessors end with the same instruction
+        while (true) {
+            List<LIRInstruction> seq = edgeInstructionSeqences.get(0);
+            if (seq.isEmpty()) {
+                return;
+            }
+
+            LIRInstruction op = last(seq);
+            for (int i = 1; i < numPreds; ++i) {
+                List<LIRInstruction> otherSeq = edgeInstructionSeqences.get(i);
+                if (otherSeq.isEmpty() || !same(op, last(otherSeq))) {
+                    return;
+                }
+            }
+
+            // insert the instruction at the beginning of the current block
+            block.lir.add(1, op);
+
+            // delete the instruction at the end of all predecessors
+            for (int i = 0; i < numPreds; i++) {
+                seq = edgeInstructionSeqences.get(i);
+                removeLast(seq);
+            }
+        }
+    }
+
+    /**
+     * Moves the longest {@linkplain #same common} subsequence at the start of all
+     * successors of {@code block} to the end of {@code block} just prior to the
+     * branch instruction ending {@code block}.
+     */
+    private void optimizeMovesAtBlockBegin(Block block) {
+
+        edgeInstructionSeqences.clear();
+        int numSux = block.numberOfSux();
+
+        List<LIRInstruction> instructions = block.lir;
+
+        assert numSux == 2 : "method should not be called otherwise";
+
+        if (instructions.get(instructions.size() - 1) instanceof LIRXirInstruction) {
+            // cannot optimize when last instruction is Xir.
+            return;
+        }
+
+        assert instructions.get(instructions.size() - 1) instanceof StandardOp.JumpOp : "block must end with unconditional jump";
+
+        if (instructions.get(instructions.size() - 1).info != null) {
+            // cannot optimize instructions when debug info is needed
+            return;
+        }
+
+        LIRInstruction branch = instructions.get(instructions.size() - 2);
+        if (!(branch instanceof StandardOp.BranchOp) || branch.info != null) {
+            // not a valid case for optimization
+            // currently, only blocks that end with two branches (conditional branch followed
+            // by unconditional branch) are optimized
+            return;
+        }
+
+        // now it is guaranteed that the block ends with two branch instructions.
+        // the instructions are inserted at the end of the block before these two branches
+        int insertIdx = instructions.size() - 2;
+
+        // setup a list with the lir-instructions of all successors
+        for (int i = 0; i < numSux; i++) {
+            Block sux = block.suxAt(i);
+            List<LIRInstruction> suxInstructions = sux.lir;
+
+            assert suxInstructions.get(0) instanceof StandardOp.LabelOp : "block must start with label";
+
+            if (sux.numberOfPreds() != 1) {
+                // this can happen with switch-statements where multiple edges are between
+                // the same blocks.
+                return;
+            }
+            assert sux.predAt(0) == block : "invalid control flow";
+
+            // ignore the label at the beginning of the block
+            List<LIRInstruction> seq = suxInstructions.subList(1, suxInstructions.size());
+            edgeInstructionSeqences.add(seq);
+        }
+
+        // process LIR instructions while all successors begin with the same instruction
+        while (true) {
+            List<LIRInstruction> seq = edgeInstructionSeqences.get(0);
+            if (seq.isEmpty()) {
+                return;
+            }
+
+            LIRInstruction op = first(seq);
+            for (int i = 1; i < numSux; i++) {
+                List<LIRInstruction> otherSeq = edgeInstructionSeqences.get(i);
+                if (otherSeq.isEmpty() || !same(op, first(otherSeq))) {
+                    // these instructions are different and cannot be optimized .
+                    // no further optimization possible
+                    return;
+                }
+            }
+
+            // insert instruction at end of current block
+            block.lir.add(insertIdx, op);
+            insertIdx++;
+
+            // delete the instructions at the beginning of all successors
+            for (int i = 0; i < numSux; i++) {
+                seq = edgeInstructionSeqences.get(i);
+                removeFirst(seq);
+            }
+        }
+    }
+
+    /**
+     * Gets the first element from a LIR instruction sequence.
+     */
+    private static LIRInstruction first(List<LIRInstruction> seq) {
+        return seq.get(0);
+    }
+
+    /**
+     * Gets the last element from a LIR instruction sequence.
+     */
+    private static LIRInstruction last(List<LIRInstruction> seq) {
+        return seq.get(seq.size() - 1);
+    }
+
+    /**
+     * Removes the first element from a LIR instruction sequence.
+     */
+    private static void removeFirst(List<LIRInstruction> seq) {
+        seq.remove(0);
+    }
+
+    /**
+     * Removes the last element from a LIR instruction sequence.
+     */
+    private static void removeLast(List<LIRInstruction> seq) {
+        seq.remove(seq.size() - 1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/Interval.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1172 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.compiler.alloc;
+
+import static com.oracle.max.graal.alloc.util.LocationUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+
+/**
+ * Represents an interval in the {@linkplain LinearScan linear scan register allocator}.
+ */
+public final class Interval {
+
+    /**
+     * A pair of intervals.
+     */
+    static final class Pair {
+        public final Interval first;
+        public final Interval second;
+        public Pair(Interval first, Interval second) {
+            this.first = first;
+            this.second = second;
+        }
+    }
+
+    /**
+     * A set of interval lists, one per {@linkplain RegisterBinding binding} type.
+     */
+    static final class RegisterBindingLists {
+
+        /**
+         * List of intervals whose binding is currently {@link RegisterBinding#Fixed}.
+         */
+        public Interval fixed;
+
+        /**
+         * List of intervals whose binding is currently {@link RegisterBinding#Any}.
+         */
+        public Interval any;
+
+        public RegisterBindingLists(Interval fixed, Interval any) {
+            this.fixed = fixed;
+            this.any = any;
+        }
+
+        /**
+         * Gets the list for a specified binding.
+         *
+         * @param binding specifies the list to be returned
+         * @return the list of intervals whose binding is {@code binding}
+         */
+        public Interval get(RegisterBinding binding) {
+            if (binding == RegisterBinding.Any) {
+                return any;
+            }
+            assert binding == RegisterBinding.Fixed;
+            return fixed;
+        }
+
+        /**
+         * Sets the list for a specified binding.
+         *
+         * @param binding specifies the list to be replaced
+         * @param a list of intervals whose binding is {@code binding}
+         */
+        public void set(RegisterBinding binding, Interval list) {
+            assert list != null;
+            if (binding == RegisterBinding.Any) {
+                any = list;
+            } else {
+                assert binding == RegisterBinding.Fixed;
+                fixed = list;
+            }
+        }
+
+        /**
+         * Adds an interval to a list sorted by {@linkplain Interval#currentFrom() current from} positions.
+         *
+         * @param binding specifies the list to be updated
+         * @param interval the interval to add
+         */
+        public void addToListSortedByCurrentFromPositions(RegisterBinding binding, Interval interval) {
+            Interval list = get(binding);
+            Interval prev = null;
+            Interval cur = list;
+            while (cur.currentFrom() < interval.currentFrom()) {
+                prev = cur;
+                cur = cur.next;
+            }
+            Interval result = list;
+            if (prev == null) {
+                // add to head of list
+                result = interval;
+            } else {
+                // add before 'cur'
+                prev.next = interval;
+            }
+            interval.next = cur;
+            set(binding, result);
+        }
+
+        /**
+         * Adds an interval to a list sorted by {@linkplain Interval#from() start} positions and
+         * {@linkplain Interval#firstUsage(RegisterPriority) first usage} positions.
+         *
+         * @param binding specifies the list to be updated
+         * @param interval the interval to add
+         */
+        public void addToListSortedByStartAndUsePositions(RegisterBinding binding, Interval interval) {
+            Interval list = get(binding);
+            Interval prev = null;
+            Interval cur = list;
+            while (cur.from() < interval.from() || (cur.from() == interval.from() && cur.firstUsage(RegisterPriority.None) < interval.firstUsage(RegisterPriority.None))) {
+                prev = cur;
+                cur = cur.next;
+            }
+            if (prev == null) {
+                list = interval;
+            } else {
+                prev.next = interval;
+            }
+            interval.next = cur;
+            set(binding, list);
+        }
+
+        /**
+         * Removes an interval from a list.
+         *
+         * @param binding specifies the list to be updated
+         * @param interval the interval to remove
+         */
+        public void remove(RegisterBinding binding, Interval i) {
+            Interval list = get(binding);
+            Interval prev = null;
+            Interval cur = list;
+            while (cur != i) {
+                assert cur != null && cur != Interval.EndMarker : "interval has not been found in list: " + i;
+                prev = cur;
+                cur = cur.next;
+            }
+            if (prev == null) {
+                set(binding, cur.next);
+            } else {
+                prev.next = cur.next;
+            }
+        }
+    }
+
+    /**
+     * Constants denoting the register usage priority for an interval.
+     * The constants are declared in increasing order of priority are
+     * are used to optimize spilling when multiple overlapping intervals
+     * compete for limited registers.
+     */
+    enum RegisterPriority {
+        /**
+         * No special reason for an interval to be allocated a register.
+         */
+        None,
+
+        /**
+         * Priority level for intervals live at the end of a loop.
+         */
+        LiveAtLoopEnd,
+
+        /**
+         * Priority level for intervals that should be allocated to a register.
+         */
+        ShouldHaveRegister,
+
+        /**
+         * Priority level for intervals that must be allocated to a register.
+         */
+        MustHaveRegister;
+
+        public static final RegisterPriority[] VALUES = values();
+
+        /**
+         * Determines if this priority is higher than or equal to a given priority.
+         */
+        public boolean greaterEqual(RegisterPriority other) {
+            return ordinal() >= other.ordinal();
+        }
+
+        /**
+         * Determines if this priority is lower than a given priority.
+         */
+        public boolean lessThan(RegisterPriority other) {
+            return ordinal() < other.ordinal();
+        }
+    }
+
+    /**
+     * Constants denoting whether an interval is bound to a specific register. This models
+     * platform dependencies on register usage for certain instructions.
+     */
+    enum RegisterBinding {
+        /**
+         * Interval is bound to a specific register as required by the platform.
+         */
+        Fixed,
+
+        /**
+         * Interval has no specific register requirements.
+         */
+        Any;
+
+        public static final RegisterBinding[] VALUES = values();
+    }
+
+    /**
+     * Constants denoting the linear-scan states an interval may be in with respect to the
+     * {@linkplain Interval#from() start} {@code position} of the interval being processed.
+     */
+    enum State {
+        /**
+         * An interval that starts after {@code position}.
+         */
+        Unhandled,
+
+        /**
+         * An interval that {@linkplain Interval#covers covers} {@code position} and has an assigned register.
+         */
+        Active,
+
+        /**
+         * An interval that starts before and ends after {@code position} but does not
+         * {@linkplain Interval#covers cover} it due to a lifetime hole.
+         */
+        Inactive,
+
+        /**
+         * An interval that ends before {@code position} or is spilled to memory.
+         */
+        Handled;
+    }
+
+    /**
+     * Constants used in optimization of spilling of an interval.
+     */
+    enum SpillState {
+        /**
+         * Starting state of calculation: no definition found yet.
+         */
+        NoDefinitionFound,
+
+        /**
+         * One definition has already been found. Two consecutive definitions are treated as one
+         * (e.g. a consecutive move and add because of two-operand LIR form).
+         * The position of this definition is given by {@link Interval#spillDefinitionPos()}.
+         */
+        NoSpillStore,
+
+        /**
+         * One spill move has already been inserted.
+         */
+        OneSpillStore,
+
+        /**
+         * The interval should be stored immediately after its definition to prevent
+         * multiple redundant stores.
+         */
+        StoreAtDefinition,
+
+        /**
+         * The interval starts in memory (e.g. method parameter), so a store is never necessary.
+         */
+        StartInMemory,
+
+        /**
+         * The interval has more than one definition (e.g. resulting from phi moves), so stores
+         * to memory are not optimized.
+         */
+        NoOptimization
+    }
+
+    /**
+     * List of use positions. Each entry in the list records the use position and register
+     * priority associated with the use position. The entries in the list are in descending
+     * order of use position.
+     *
+     */
+    public static final class UsePosList {
+        private IntList list;
+
+        /**
+         * Creates a use list.
+         *
+         * @param initialCapacity the initial capacity of the list in terms of entries
+         */
+        public UsePosList(int initialCapacity) {
+            list = new IntList(initialCapacity * 2);
+        }
+
+        private UsePosList(IntList list) {
+            this.list = list;
+        }
+
+        /**
+         * Splits this list around a given position. All entries in this list with a use position greater or equal than
+         * {@code splitPos} are removed from this list and added to the returned list.
+         *
+         * @param splitPos the position for the split
+         * @return a use position list containing all entries removed from this list that have a use position greater or equal
+         *         than {@code splitPos}
+         */
+        public UsePosList splitAt(int splitPos) {
+            int i = size() - 1;
+            int len = 0;
+            while (i >= 0 && usePos(i) < splitPos) {
+                --i;
+                len += 2;
+            }
+            int listSplitIndex = (i + 1) * 2;
+            IntList childList = list;
+            list = IntList.copy(this.list, listSplitIndex, len);
+            childList.setSize(listSplitIndex);
+            UsePosList child = new UsePosList(childList);
+            return child;
+        }
+
+        /**
+         * Gets the use position at a specified index in this list.
+         *
+         * @param index the index of the entry for which the use position is returned
+         * @return the use position of entry {@code index} in this list
+         */
+        public int usePos(int index) {
+            return list.get(index << 1);
+        }
+
+        /**
+         * Gets the register priority for the use position at a specified index in this list.
+         *
+         * @param index the index of the entry for which the register priority is returned
+         * @return the register priority of entry {@code index} in this list
+         */
+        public RegisterPriority registerPriority(int index) {
+            return RegisterPriority.VALUES[list.get((index << 1) + 1)];
+        }
+
+        public void add(int usePos, RegisterPriority registerPriority) {
+            assert list.size() == 0 || usePos(size() - 1) > usePos;
+            list.add(usePos);
+            list.add(registerPriority.ordinal());
+        }
+
+        public int size() {
+            return list.size() >> 1;
+        }
+
+        public void removeLowestUsePos() {
+            list.setSize(list.size() - 2);
+        }
+
+        public void setRegisterPriority(int index, RegisterPriority registerPriority) {
+            list.set(index * 2, registerPriority.ordinal());
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder buf = new StringBuilder("[");
+            for (int i = size() - 1; i >= 0; --i) {
+                if (buf.length() != 1) {
+                    buf.append(", ");
+                }
+                RegisterPriority prio = registerPriority(i);
+                buf.append(usePos(i)).append(" -> ").append(prio.ordinal()).append(':').append(prio);
+            }
+            return buf.append("]").toString();
+        }
+    }
+
+    /**
+     * The {@linkplain CiRegisterValue register} or {@linkplain Variable variable} for this interval prior to register allocation.
+     */
+    public final CiValue operand;
+
+    /**
+     * The {@linkplain OperandPool#operandNumber(CiValue) operand number} for this interval's {@linkplain #operand operand}.
+     */
+    public final int operandNumber;
+
+    /**
+     * The {@linkplain CiRegisterValue register}, {@linkplain CiStackSlot spill slot} or {@linkplain CiAddress address} assigned to this interval.
+     */
+    private CiValue location;
+
+    /**
+     * The stack slot to which all splits of this interval are spilled if necessary.
+     */
+    private CiStackSlot spillSlot;
+
+    /**
+     * The kind of this interval.
+     * Only valid if this is a {@linkplain #xxisVariable() variable}.
+     */
+    private CiKind kind;
+
+    /**
+     * The head of the list of ranges describing this interval. This list is sorted by {@linkplain LIRInstruction#id instruction ids}.
+     */
+    private Range first;
+
+    /**
+     * List of (use-positions, register-priorities) pairs, sorted by use-positions.
+     */
+    private UsePosList usePosList;
+
+    /**
+     * Iterator used to traverse the ranges of an interval.
+     */
+    private Range current;
+
+    /**
+     * Link to next interval in a sorted list of intervals that ends with {@link #EndMarker}.
+     */
+    Interval next;
+
+    /**
+     * The linear-scan state of this interval.
+     */
+    State state;
+
+    private int cachedTo; // cached value: to of last range (-1: not cached)
+
+    /**
+     * The interval from which this one is derived. If this is a {@linkplain #isSplitParent() split parent}, it points to itself.
+     */
+    private Interval splitParent;
+
+    /**
+     * List of all intervals that are split off from this interval. This is only used if this is a {@linkplain #isSplitParent() split parent}.
+     */
+    private List<Interval> splitChildren = Collections.emptyList();
+
+    /**
+     * Current split child that has been active or inactive last (always stored in split parents).
+     */
+    private Interval currentSplitChild;
+
+    /**
+     * Specifies if move is inserted between currentSplitChild and this interval when interval gets active the first time.
+     */
+    private boolean insertMoveWhenActivated;
+
+    /**
+     * For spill move optimization.
+     */
+    private SpillState spillState;
+
+    /**
+     * Position where this interval is defined (if defined only once).
+     */
+    private int spillDefinitionPos;
+
+    /**
+     * This interval should be assigned the same location as the hint interval.
+     */
+    private Interval locationHint;
+
+    void assignLocation(CiValue newLocation) {
+        if (isRegister(newLocation)) {
+            assert this.location == null : "cannot re-assign location for " + this;
+            if (newLocation.kind == CiKind.Illegal && kind != CiKind.Illegal) {
+                this.location = asRegister(newLocation).asValue(kind);
+                return;
+            }
+        } else {
+            assert this.location == null || isRegister(this.location) : "cannot re-assign location for " + this;
+            assert isStackSlot(newLocation);
+            assert newLocation.kind != CiKind.Illegal;
+            assert newLocation.kind == this.kind;
+        }
+        this.location = newLocation;
+    }
+
+    /**
+     * Gets the {@linkplain CiRegisterValue register}, {@linkplain CiStackSlot spill slot} or {@linkplain CiAddress address} assigned to this interval.
+     */
+    public CiValue location() {
+        return location;
+    }
+
+    public CiKind kind() {
+        assert !isRegister(operand) : "cannot access type for fixed interval";
+        return kind;
+    }
+
+    void setKind(CiKind kind) {
+        assert isRegister(operand) || this.kind() == CiKind.Illegal || this.kind() == kind : "overwriting existing type";
+        assert kind == kind.stackKind() || kind == CiKind.Short : "these kinds should have int type registers";
+        this.kind = kind;
+    }
+
+    public Range first() {
+        return first;
+    }
+
+    int from() {
+        return first.from;
+    }
+
+    int to() {
+        if (cachedTo == -1) {
+            cachedTo = calcTo();
+        }
+        assert cachedTo == calcTo() : "invalid cached value";
+        return cachedTo;
+    }
+
+    int numUsePositions() {
+        return usePosList.size();
+    }
+
+    void setLocationHint(Interval interval) {
+        locationHint = interval;
+    }
+
+    boolean isSplitParent() {
+        return splitParent == this;
+    }
+
+    boolean isSplitChild() {
+        return splitParent != this;
+    }
+
+    /**
+     * Gets the split parent for this interval.
+     */
+    public Interval splitParent() {
+        assert splitParent.isSplitParent() : "not a split parent: " + this;
+        return splitParent;
+    }
+
+    /**
+     * Gets the canonical spill slot for this interval.
+     */
+    CiStackSlot spillSlot() {
+        return splitParent().spillSlot;
+    }
+
+    void setSpillSlot(CiStackSlot slot) {
+        assert splitParent().spillSlot == null : "connot overwrite existing spill slot";
+        splitParent().spillSlot = slot;
+    }
+
+    Interval currentSplitChild() {
+        return splitParent().currentSplitChild;
+    }
+
+    void makeCurrentSplitChild() {
+        splitParent().currentSplitChild = this;
+    }
+
+    boolean insertMoveWhenActivated() {
+        return insertMoveWhenActivated;
+    }
+
+    void setInsertMoveWhenActivated(boolean b) {
+        insertMoveWhenActivated = b;
+    }
+
+    // for spill optimization
+    public SpillState spillState() {
+        return splitParent().spillState;
+    }
+
+    int spillDefinitionPos() {
+        return splitParent().spillDefinitionPos;
+    }
+
+    void setSpillState(SpillState state) {
+        assert state.ordinal() >= spillState().ordinal() : "state cannot decrease";
+        splitParent().spillState = state;
+    }
+
+    void setSpillDefinitionPos(int pos) {
+        assert spillDefinitionPos() == -1 : "cannot set the position twice";
+        splitParent().spillDefinitionPos = pos;
+    }
+
+    // returns true if this interval has a shadow copy on the stack that is always correct
+    boolean alwaysInMemory() {
+        return splitParent().spillState == SpillState.StoreAtDefinition || splitParent().spillState == SpillState.StartInMemory;
+    }
+
+    void removeFirstUsePos() {
+        usePosList.removeLowestUsePos();
+    }
+
+    // test intersection
+    boolean intersects(Interval i) {
+        return first.intersects(i.first);
+    }
+
+    int intersectsAt(Interval i) {
+        return first.intersectsAt(i.first);
+    }
+
+    // range iteration
+    void rewindRange() {
+        current = first;
+    }
+
+    void nextRange() {
+        assert this != EndMarker : "not allowed on sentinel";
+        current = current.next;
+    }
+
+    int currentFrom() {
+        return current.from;
+    }
+
+    int currentTo() {
+        return current.to;
+    }
+
+    boolean currentAtEnd() {
+        return current == Range.EndMarker;
+    }
+
+    boolean currentIntersects(Interval it) {
+        return current.intersects(it.current);
+    }
+
+    int currentIntersectsAt(Interval it) {
+        return current.intersectsAt(it.current);
+    }
+
+    /**
+     * Sentinel interval to denote the end of an interval list.
+     */
+    static final Interval EndMarker = new Interval(CiValue.IllegalValue, -1);
+
+    Interval(CiValue operand, int operandNumber) {
+        assert operand != null;
+        this.operand = operand;
+        this.operandNumber = operandNumber;
+        if (isRegister(operand)) {
+            location = operand;
+        } else {
+            assert isIllegal(operand) || isVariable(operand);
+        }
+        this.kind = CiKind.Illegal;
+        this.first = Range.EndMarker;
+        this.usePosList = new UsePosList(4);
+        this.current = Range.EndMarker;
+        this.next = EndMarker;
+        this.cachedTo = -1;
+        this.spillState = SpillState.NoDefinitionFound;
+        this.spillDefinitionPos = -1;
+        splitParent = this;
+        currentSplitChild = this;
+    }
+
+    int calcTo() {
+        assert first != Range.EndMarker : "interval has no range";
+
+        Range r = first;
+        while (r.next != Range.EndMarker) {
+            r = r.next;
+        }
+        return r.to;
+    }
+
+    // consistency check of split-children
+    boolean checkSplitChildren() {
+        if (!splitChildren.isEmpty()) {
+            assert isSplitParent() : "only split parents can have children";
+
+            for (int i = 0; i < splitChildren.size(); i++) {
+                Interval i1 = splitChildren.get(i);
+
+                assert i1.splitParent() == this : "not a split child of this interval";
+                assert i1.kind()  == kind() : "must be equal for all split children";
+                assert i1.spillSlot() == spillSlot() : "must be equal for all split children";
+
+                for (int j = i + 1; j < splitChildren.size(); j++) {
+                    Interval i2 = splitChildren.get(j);
+
+                    assert i1.operand != i2.operand : "same register number";
+
+                    if (i1.from() < i2.from()) {
+                        assert i1.to() <= i2.from() && i1.to() < i2.to() : "intervals overlapping";
+                    } else {
+                        assert i2.from() < i1.from() : "intervals start at same opId";
+                        assert i2.to() <= i1.from() && i2.to() < i1.to() : "intervals overlapping";
+                    }
+                }
+            }
+        }
+
+        return true;
+    }
+
+    public Interval locationHint(boolean searchSplitChild) {
+        if (!searchSplitChild) {
+            return locationHint;
+        }
+
+        if (locationHint != null) {
+            assert locationHint.isSplitParent() : "ony split parents are valid hint registers";
+
+            if (locationHint.location != null && isRegister(locationHint.location)) {
+                return locationHint;
+            } else if (!locationHint.splitChildren.isEmpty()) {
+                // search the first split child that has a register assigned
+                int len = locationHint.splitChildren.size();
+                for (int i = 0; i < len; i++) {
+                    Interval interval = locationHint.splitChildren.get(i);
+                    if (interval.location != null && isRegister(interval.location)) {
+                        return interval;
+                    }
+                }
+            }
+        }
+
+        // no hint interval found that has a register assigned
+        return null;
+    }
+
+    Interval getSplitChildAtOpId(int opId, LIRInstruction.OperandMode mode, LinearScan allocator) {
+        assert isSplitParent() : "can only be called for split parents";
+        assert opId >= 0 : "invalid opId (method cannot be called for spill moves)";
+
+        if (splitChildren.isEmpty()) {
+            assert this.covers(opId, mode) : this + " does not cover " + opId;
+            return this;
+        } else {
+            Interval result = null;
+            int len = splitChildren.size();
+
+            // in outputMode, the end of the interval (opId == cur.to()) is not valid
+            int toOffset = (mode == LIRInstruction.OperandMode.Output ? 0 : 1);
+
+            int i;
+            for (i = 0; i < len; i++) {
+                Interval cur = splitChildren.get(i);
+                if (cur.from() <= opId && opId < cur.to() + toOffset) {
+                    if (i > 0) {
+                        // exchange current split child to start of list (faster access for next call)
+                        Util.atPutGrow(splitChildren, i, splitChildren.get(0), null);
+                        Util.atPutGrow(splitChildren, 0, cur, null);
+                    }
+
+                    // interval found
+                    result = cur;
+                    break;
+                }
+            }
+
+            assert checkSplitChild(result, opId, allocator, toOffset, mode);
+            return result;
+        }
+    }
+
+    private boolean checkSplitChild(Interval result, int opId, LinearScan allocator, int toOffset, LIRInstruction.OperandMode mode) {
+        if (result == null) {
+            // this is an error
+            StringBuilder msg = new StringBuilder(this.toString()).append(" has no child at ").append(opId);
+            if (!splitChildren.isEmpty()) {
+                Interval firstChild = splitChildren.get(0);
+                Interval lastChild = splitChildren.get(splitChildren.size() - 1);
+                msg.append(" (first = ").append(firstChild).append(", last = ").append(lastChild).append(")");
+            }
+            throw new GraalInternalError("Linear Scan Error: %s", msg);
+        }
+
+        if (!splitChildren.isEmpty()) {
+            for (Interval interval : splitChildren) {
+                if (interval != result && interval.from() <= opId && opId < interval.to() + toOffset) {
+                    TTY.println(String.format("two valid result intervals found for opId %d: %d and %d", opId, result.operandNumber, interval.operandNumber));
+                    TTY.println(result.logString(allocator));
+                    TTY.println(interval.logString(allocator));
+                    throw new CiBailout("two valid result intervals found");
+                }
+            }
+        }
+        assert result.covers(opId, mode) : "opId not covered by interval";
+        return true;
+    }
+
+    // returns the last split child that ends before the given opId
+    Interval getSplitChildBeforeOpId(int opId) {
+        assert opId >= 0 : "invalid opId";
+
+        Interval parent = splitParent();
+        Interval result = null;
+
+        assert !parent.splitChildren.isEmpty() : "no split children available";
+        int len = parent.splitChildren.size();
+
+        for (int i = len - 1; i >= 0; i--) {
+            Interval cur = parent.splitChildren.get(i);
+            if (cur.to() <= opId && (result == null || result.to() < cur.to())) {
+                result = cur;
+            }
+        }
+
+        assert result != null : "no split child found";
+        return result;
+    }
+
+    // checks if opId is covered by any split child
+    boolean splitChildCovers(int opId, LIRInstruction.OperandMode mode) {
+        assert isSplitParent() : "can only be called for split parents";
+        assert opId >= 0 : "invalid opId (method can not be called for spill moves)";
+
+        if (splitChildren.isEmpty()) {
+            // simple case if interval was not split
+            return covers(opId, mode);
+
+        } else {
+            // extended case: check all split children
+            int len = splitChildren.size();
+            for (int i = 0; i < len; i++) {
+                Interval cur = splitChildren.get(i);
+                if (cur.covers(opId, mode)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    // Note: use positions are sorted descending . first use has highest index
+    int firstUsage(RegisterPriority minRegisterPriority) {
+        assert isVariable(operand) : "cannot access use positions for fixed intervals";
+
+        for (int i = usePosList.size() - 1; i >= 0; --i) {
+            RegisterPriority registerPriority = usePosList.registerPriority(i);
+            if (registerPriority.greaterEqual(minRegisterPriority)) {
+                return usePosList.usePos(i);
+            }
+        }
+        return Integer.MAX_VALUE;
+    }
+
+    int nextUsage(RegisterPriority minRegisterPriority, int from) {
+        assert isVariable(operand) : "cannot access use positions for fixed intervals";
+
+        for (int i = usePosList.size() - 1; i >= 0; --i) {
+            int usePos = usePosList.usePos(i);
+            if (usePos >= from && usePosList.registerPriority(i).greaterEqual(minRegisterPriority)) {
+                return usePos;
+            }
+        }
+        return Integer.MAX_VALUE;
+    }
+
+    int nextUsageExact(RegisterPriority exactRegisterPriority, int from) {
+        assert isVariable(operand) : "cannot access use positions for fixed intervals";
+
+        for (int i = usePosList.size() - 1; i >= 0; --i) {
+            int usePos = usePosList.usePos(i);
+            if (usePos >= from && usePosList.registerPriority(i) == exactRegisterPriority) {
+                return usePos;
+            }
+        }
+        return Integer.MAX_VALUE;
+    }
+
+    int previousUsage(RegisterPriority minRegisterPriority, int from) {
+        assert isVariable(operand) : "cannot access use positions for fixed intervals";
+
+        int prev = 0;
+        for (int i = usePosList.size() - 1; i >= 0; --i) {
+            int usePos = usePosList.usePos(i);
+            if (usePos > from) {
+                return prev;
+            }
+            if (usePosList.registerPriority(i).greaterEqual(minRegisterPriority)) {
+                prev = usePos;
+            }
+        }
+        return prev;
+    }
+
+    void addUsePos(int pos, RegisterPriority registerPriority) {
+        assert covers(pos, LIRInstruction.OperandMode.Input) : "use position not covered by live range";
+
+        // do not add use positions for precolored intervals because they are never used
+        if (registerPriority != RegisterPriority.None && isVariable(operand)) {
+            if (GraalOptions.DetailedAsserts) {
+                for (int i = 0; i < usePosList.size(); i++) {
+                    assert pos <= usePosList.usePos(i) : "already added a use-position with lower position";
+                    if (i > 0) {
+                        assert usePosList.usePos(i) < usePosList.usePos(i - 1) : "not sorted descending";
+                    }
+                }
+            }
+
+            // Note: addUse is called in descending order, so list gets sorted
+            // automatically by just appending new use positions
+            int len = usePosList.size();
+            if (len == 0 || usePosList.usePos(len - 1) > pos) {
+                usePosList.add(pos, registerPriority);
+            } else if (usePosList.registerPriority(len - 1).lessThan(registerPriority)) {
+                assert usePosList.usePos(len - 1) == pos : "list not sorted correctly";
+                usePosList.setRegisterPriority(len - 1, registerPriority);
+            }
+        }
+    }
+
+    void addRange(int from, int to) {
+        assert from < to : "invalid range";
+        assert first() == Range.EndMarker || to < first().next.from : "not inserting at begin of interval";
+        assert from <= first().to : "not inserting at begin of interval";
+
+        if (first.from <= to) {
+            assert first != Range.EndMarker;
+            // join intersecting ranges
+            first.from = Math.min(from, first().from);
+            first.to = Math.max(to, first().to);
+        } else {
+            // insert new range
+            first = new Range(from, to, first());
+        }
+    }
+
+    Interval newSplitChild(LinearScan allocator) {
+        // allocate new interval
+        Interval parent = splitParent();
+        Interval result = allocator.createDerivedInterval(parent);
+        result.setKind(kind());
+
+        result.splitParent = parent;
+        result.setLocationHint(parent);
+
+        // insert new interval in children-list of parent
+        if (parent.splitChildren.isEmpty()) {
+            assert isSplitParent() : "list must be initialized at first split";
+
+            // Create new non-shared list
+            parent.splitChildren = new ArrayList<>(4);
+            parent.splitChildren.add(this);
+        }
+        parent.splitChildren.add(result);
+
+        return result;
+    }
+
+    /**
+     * Splits this interval at a specified position and returns the remainder as a new <i>child</i> interval
+     * of this interval's {@linkplain #splitParent() parent} interval.
+     * <p>
+     * When an interval is split, a bi-directional link is established between the original <i>parent</i>
+     * interval and the <i>children</i> intervals that are split off this interval.
+     * When a split child is split again, the new created interval is a direct child
+     * of the original parent. That is, there is no tree of split children stored, just a flat list.
+     * All split children are spilled to the same {@linkplain #spillSlot spill slot}.
+     *
+     * @param splitPos the position at which to split this interval
+     * @param allocator the register allocator context
+     * @return the child interval split off from this interval
+     */
+    Interval split(int splitPos, LinearScan allocator) {
+        assert isVariable(operand) : "cannot split fixed intervals";
+
+        // allocate new interval
+        Interval result = newSplitChild(allocator);
+
+        // split the ranges
+        Range prev = null;
+        Range cur = first;
+        while (cur != Range.EndMarker && cur.to <= splitPos) {
+            prev = cur;
+            cur = cur.next;
+        }
+        assert cur != Range.EndMarker : "split interval after end of last range";
+
+        if (cur.from < splitPos) {
+            result.first = new Range(splitPos, cur.to, cur.next);
+            cur.to = splitPos;
+            cur.next = Range.EndMarker;
+
+        } else {
+            assert prev != null : "split before start of first range";
+            result.first = cur;
+            prev.next = Range.EndMarker;
+        }
+        result.current = result.first;
+        cachedTo = -1; // clear cached value
+
+        // split list of use positions
+        result.usePosList = usePosList.splitAt(splitPos);
+
+        if (GraalOptions.DetailedAsserts) {
+            for (int i = 0; i < usePosList.size(); i++) {
+                assert usePosList.usePos(i) < splitPos;
+            }
+            for (int i = 0; i < result.usePosList.size(); i++) {
+                assert result.usePosList.usePos(i) >= splitPos;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Splits this interval at a specified position and returns
+     * the head as a new interval (this interval is the tail).
+     *
+     * Currently, only the first range can be split, and the new interval must not have split positions
+     */
+    Interval splitFromStart(int splitPos, LinearScan allocator) {
+        assert isVariable(operand) : "cannot split fixed intervals";
+        assert splitPos > from() && splitPos < to() : "can only split inside interval";
+        assert splitPos > first.from && splitPos <= first.to : "can only split inside first range";
+        assert firstUsage(RegisterPriority.None) > splitPos : "can not split when use positions are present";
+
+        // allocate new interval
+        Interval result = newSplitChild(allocator);
+
+        // the new interval has only one range (checked by assertion above,
+        // so the splitting of the ranges is very simple
+        result.addRange(first.from, splitPos);
+
+        if (splitPos == first.to) {
+            assert first.next != Range.EndMarker : "must not be at end";
+            first = first.next;
+        } else {
+            first.from = splitPos;
+        }
+
+        return result;
+    }
+
+    // returns true if the opId is inside the interval
+    boolean covers(int opId, LIRInstruction.OperandMode mode) {
+        Range cur = first;
+
+        while (cur != Range.EndMarker && cur.to < opId) {
+            cur = cur.next;
+        }
+        if (cur != Range.EndMarker) {
+            assert cur.to != cur.next.from : "ranges not separated";
+
+            if (mode == LIRInstruction.OperandMode.Output) {
+                return cur.from <= opId && opId < cur.to;
+            } else {
+                return cur.from <= opId && opId <= cur.to;
+            }
+        }
+        return false;
+    }
+
+    // returns true if the interval has any hole between holeFrom and holeTo
+    // (even if the hole has only the length 1)
+    boolean hasHoleBetween(int holeFrom, int holeTo) {
+        assert holeFrom < holeTo : "check";
+        assert from() <= holeFrom && holeTo <= to() : "index out of interval";
+
+        Range cur = first;
+        while (cur != Range.EndMarker) {
+            assert cur.to < cur.next.from : "no space between ranges";
+
+            // hole-range starts before this range . hole
+            if (holeFrom < cur.from) {
+                return true;
+
+                // hole-range completely inside this range . no hole
+            } else {
+                if (holeTo <= cur.to) {
+                    return false;
+
+                    // overlapping of hole-range with this range . hole
+                } else {
+                    if (holeFrom <= cur.to) {
+                        return true;
+                    }
+                }
+            }
+
+            cur = cur.next;
+        }
+
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        String from = "?";
+        String to = "?";
+        if (first != null && first != Range.EndMarker) {
+            from = String.valueOf(from());
+            to = String.valueOf(to());
+        }
+        String locationString = this.location == null ? "" : "@" + this.location;
+        return operandNumber + ":" + operand + (isRegister(operand) ? "" : locationString) + "[" + from + "," + to + "]";
+    }
+
+    /**
+     * Gets the use position information for this interval.
+     */
+    public UsePosList usePosList() {
+        return usePosList;
+    }
+
+    /**
+     * Gets a single line string for logging the details of this interval to a log stream.
+     *
+     * @param allocator the register allocator context
+     */
+    public String logString(LinearScan allocator) {
+        StringBuilder buf = new StringBuilder(100);
+        buf.append(operandNumber).append(':').append(operand).append(' ');
+        if (!isRegister(operand)) {
+            if (location != null) {
+                buf.append("location{").append(location).append("} ");
+            }
+        }
+
+        buf.append("hints{").append(splitParent.operandNumber);
+        Interval hint = locationHint(false);
+        if (hint != null && hint.operandNumber != splitParent.operandNumber) {
+            buf.append(", ").append(hint.operandNumber);
+        }
+        buf.append("} ranges{");
+
+        // print ranges
+        Range cur = first;
+        while (cur != Range.EndMarker) {
+            if (cur != first) {
+                buf.append(", ");
+            }
+            buf.append(cur);
+            cur = cur.next;
+            assert cur != null : "range list not closed with range sentinel";
+        }
+        buf.append("} uses{");
+
+        // print use positions
+        int prev = 0;
+        for (int i = usePosList.size() - 1; i >= 0; --i) {
+            assert prev < usePosList.usePos(i) : "use positions not sorted";
+            if (i != usePosList.size() - 1) {
+                buf.append(", ");
+            }
+            buf.append(usePosList.usePos(i)).append(':').append(usePosList.registerPriority(i));
+            prev = usePosList.usePos(i);
+        }
+        return buf.append("} spill-state{").append(spillState()).append("}").toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/IntervalWalker.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.compiler.alloc;
+
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.alloc.Interval.RegisterBinding;
+import com.oracle.max.graal.compiler.alloc.Interval.RegisterBindingLists;
+import com.oracle.max.graal.compiler.alloc.Interval.State;
+
+/**
+ */
+public class IntervalWalker {
+
+    protected final LinearScan allocator;
+
+    /**
+     * Sorted list of intervals, not live before the current position.
+     */
+    RegisterBindingLists unhandledLists;
+
+    /**
+     * Sorted list of intervals, live at the current position.
+     */
+    RegisterBindingLists activeLists;
+
+    /**
+     * Sorted list of intervals in a life time hole at the current position.
+     */
+    RegisterBindingLists inactiveLists;
+
+    /**
+     * The current interval (taken from the unhandled list) being processed.
+     */
+    protected Interval currentInterval;
+
+    /**
+     * The current position (intercept point through the intervals).
+     */
+    protected int currentPosition;
+
+    /**
+     * The binding of the current interval being processed.
+     */
+    protected RegisterBinding currentBinding;
+
+    /**
+     * Processes the {@linkplain #currentInterval} interval in an attempt to allocate a physical
+     * register to it and thus allow it to be moved to a list of {@linkplain #activeLists active} intervals.
+     *
+     * @return {@code true} if a register was allocated to the {@linkplain #currentInterval} interval
+     */
+    boolean activateCurrent() {
+        return true;
+    }
+
+    void walkBefore(int lirOpId) {
+        walkTo(lirOpId - 1);
+    }
+
+    void walk() {
+        walkTo(Integer.MAX_VALUE);
+    }
+
+    /**
+     * Creates a new interval walker.
+     *
+     * @param allocator the register allocator context
+     * @param unhandledFixed the list of unhandled {@linkplain RegisterBinding#Fixed fixed} intervals
+     * @param unhandledAny the list of unhandled {@linkplain RegisterBinding#Any non-fixed} intervals
+     */
+    IntervalWalker(LinearScan allocator, Interval unhandledFixed, Interval unhandledAny) {
+        this.allocator = allocator;
+
+        unhandledLists = new RegisterBindingLists(unhandledFixed, unhandledAny);
+        activeLists = new RegisterBindingLists(Interval.EndMarker, Interval.EndMarker);
+        inactiveLists = new RegisterBindingLists(Interval.EndMarker, Interval.EndMarker);
+        currentPosition = -1;
+        currentInterval = null;
+        nextInterval();
+    }
+
+    void removeFromList(Interval interval) {
+        if (interval.state == State.Active) {
+            activeLists.remove(RegisterBinding.Any, interval);
+        } else {
+            assert interval.state == State.Inactive : "invalid state";
+            inactiveLists.remove(RegisterBinding.Any, interval);
+        }
+    }
+
+    void walkTo(State state, int from) {
+        assert state == State.Active || state == State.Inactive : "wrong state";
+        for (RegisterBinding binding : RegisterBinding.VALUES) {
+            Interval prevprev = null;
+            Interval prev = (state == State.Active) ? activeLists.get(binding) : inactiveLists.get(binding);
+            Interval next = prev;
+            while (next.currentFrom() <= from) {
+                Interval cur = next;
+                next = cur.next;
+
+                boolean rangeHasChanged = false;
+                while (cur.currentTo() <= from) {
+                    cur.nextRange();
+                    rangeHasChanged = true;
+                }
+
+                // also handle move from inactive list to active list
+                rangeHasChanged = rangeHasChanged || (state == State.Inactive && cur.currentFrom() <= from);
+
+                if (rangeHasChanged) {
+                    // remove cur from list
+                    if (prevprev == null) {
+                        if (state == State.Active) {
+                            activeLists.set(binding, next);
+                        } else {
+                            inactiveLists.set(binding, next);
+                        }
+                    } else {
+                        prevprev.next = next;
+                    }
+                    prev = next;
+                    if (cur.currentAtEnd()) {
+                        // move to handled state (not maintained as a list)
+                        cur.state = State.Handled;
+                        intervalMoved(cur, state, State.Handled);
+                    } else if (cur.currentFrom() <= from) {
+                        // sort into active list
+                        activeLists.addToListSortedByCurrentFromPositions(binding, cur);
+                        cur.state = State.Active;
+                        if (prev == cur) {
+                            assert state == State.Active : "check";
+                            prevprev = prev;
+                            prev = cur.next;
+                        }
+                        intervalMoved(cur, state, State.Active);
+                    } else {
+                        // sort into inactive list
+                        inactiveLists.addToListSortedByCurrentFromPositions(binding, cur);
+                        cur.state = State.Inactive;
+                        if (prev == cur) {
+                            assert state == State.Inactive : "check";
+                            prevprev = prev;
+                            prev = cur.next;
+                        }
+                        intervalMoved(cur, state, State.Inactive);
+                    }
+                } else {
+                    prevprev = prev;
+                    prev = cur.next;
+                }
+            }
+        }
+    }
+
+    void nextInterval() {
+        RegisterBinding binding;
+        Interval any = unhandledLists.any;
+        Interval fixed = unhandledLists.fixed;
+
+        if (any != Interval.EndMarker) {
+            // intervals may start at same position . prefer fixed interval
+            binding = fixed != Interval.EndMarker && fixed.from() <= any.from() ? RegisterBinding.Fixed : RegisterBinding.Any;
+
+            assert binding == RegisterBinding.Fixed && fixed.from() <= any.from() || binding == RegisterBinding.Any && any.from() <= fixed.from() : "wrong interval!!!";
+            assert any == Interval.EndMarker || fixed == Interval.EndMarker || any.from() != fixed.from() || binding == RegisterBinding.Fixed : "if fixed and any-Interval start at same position, fixed must be processed first";
+
+        } else if (fixed != Interval.EndMarker) {
+            binding = RegisterBinding.Fixed;
+        } else {
+            currentInterval = null;
+            return;
+        }
+        currentBinding = binding;
+        currentInterval = unhandledLists.get(binding);
+        unhandledLists.set(binding, currentInterval.next);
+        currentInterval.next = Interval.EndMarker;
+        currentInterval.rewindRange();
+    }
+
+    void walkTo(int toOpId) {
+        assert currentPosition <= toOpId : "can not walk backwards";
+        while (currentInterval != null) {
+            boolean isActive = currentInterval.from() <= toOpId;
+            int opId = isActive ? currentInterval.from() : toOpId;
+
+            if (GraalOptions.TraceLinearScanLevel >= 2 && !TTY.isSuppressed()) {
+                if (currentPosition < opId) {
+                    TTY.println();
+                    TTY.println("walkTo(%d) *", opId);
+                }
+            }
+
+            // set currentPosition prior to call of walkTo
+            currentPosition = opId;
+
+            // call walkTo even if currentPosition == id
+            walkTo(State.Active, opId);
+            walkTo(State.Inactive, opId);
+
+            if (isActive) {
+                currentInterval.state = State.Active;
+                if (activateCurrent()) {
+                    activeLists.addToListSortedByCurrentFromPositions(currentBinding, currentInterval);
+                    intervalMoved(currentInterval, State.Unhandled, State.Active);
+                }
+
+                nextInterval();
+            } else {
+                return;
+            }
+        }
+    }
+
+    private void intervalMoved(Interval interval, State from, State to) {
+        // intervalMoved() is called whenever an interval moves from one interval list to another.
+        // In the implementation of this method it is prohibited to move the interval to any list.
+        if (GraalOptions.TraceLinearScanLevel >= 4 && !TTY.isSuppressed()) {
+            TTY.print(from.toString() + " to " + to.toString());
+            TTY.fillTo(23);
+            TTY.out().println(interval.logString(allocator));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2100 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.compiler.alloc;
+
+import static com.oracle.max.cri.ci.CiUtil.*;
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.max.graal.alloc.util.LocationUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.alloc.Interval.RegisterBinding;
+import com.oracle.max.graal.compiler.alloc.Interval.RegisterPriority;
+import com.oracle.max.graal.compiler.alloc.Interval.SpillState;
+import com.oracle.max.graal.compiler.gen.*;
+import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.StandardOp.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+/**
+ * An implementation of the linear scan register allocator algorithm described
+ * in <a href="http://doi.acm.org/10.1145/1064979.1064998">"Optimized Interval Splitting in a Linear Scan Register Allocator"</a>
+ * by Christian Wimmer and Hanspeter Moessenboeck.
+ */
+public final class LinearScan {
+
+    final CiTarget target;
+    final RiMethod method;
+    final LIR ir;
+    final LIRGenerator gen;
+    final FrameMap frameMap;
+    final RiRegisterAttributes[] registerAttributes;
+    final CiRegister[] registers;
+
+    private static final int INITIAL_SPLIT_INTERVALS_CAPACITY = 32;
+
+    public static class BlockData {
+        /**
+         * Bit map specifying which {@linkplain OperandPool operands} are live upon entry to this block.
+         * These are values used in this block or any of its successors where such value are not defined
+         * in this block.
+         * The bit index of an operand is its {@linkplain OperandPool#operandNumber(com.sun.cri.ci.CiValue) operand number}.
+         */
+        public BitMap liveIn;
+
+        /**
+         * Bit map specifying which {@linkplain OperandPool operands} are live upon exit from this block.
+         * These are values used in a successor block that are either defined in this block or were live
+         * upon entry to this block.
+         * The bit index of an operand is its {@linkplain OperandPool#operandNumber(com.sun.cri.ci.CiValue) operand number}.
+         */
+        public BitMap liveOut;
+
+        /**
+         * Bit map specifying which {@linkplain OperandPool operands} are used (before being defined) in this block.
+         * That is, these are the values that are live upon entry to the block.
+         * The bit index of an operand is its {@linkplain OperandPool#operandNumber(com.sun.cri.ci.CiValue) operand number}.
+         */
+        public BitMap liveGen;
+
+        /**
+         * Bit map specifying which {@linkplain OperandPool operands} are defined/overwritten in this block.
+         * The bit index of an operand is its {@linkplain OperandPool#operandNumber(com.sun.cri.ci.CiValue) operand number}.
+         */
+        public BitMap liveKill;
+    }
+
+    public final BlockMap<BlockData> blockData;
+
+    /**
+     * List of blocks in linear-scan order. This is only correct as long as the CFG does not change.
+     */
+    final Block[] sortedBlocks;
+
+    /**
+     * Map from {@linkplain #operandNumber(CiValue) operand numbers} to intervals.
+     */
+    Interval[] intervals;
+
+    /**
+     * The number of valid entries in {@link #intervals}.
+     */
+    int intervalsSize;
+
+    /**
+     * The index of the first entry in {@link #intervals} for a {@linkplain #createDerivedInterval(Interval) derived interval}.
+     */
+    int firstDerivedIntervalIndex = -1;
+
+    /**
+     * Intervals sorted by {@link Interval#from()}.
+     */
+    Interval[] sortedIntervals;
+
+    /**
+     * Map from an instruction {@linkplain LIRInstruction#id id} to the instruction.
+     * Entries should be retrieved with {@link #instructionForId(int)} as the id is
+     * not simply an index into this array.
+     */
+    LIRInstruction[] opIdToInstructionMap;
+
+    /**
+     * Map from an instruction {@linkplain LIRInstruction#id id} to the {@linkplain
+     * Block block} containing the instruction. Entries should be retrieved with
+     * {@link #blockForId(int)} as the id is not simply an index into this array.
+     */
+    Block[] opIdToBlockMap;
+
+    /**
+     * Bit set for each variable that is contained in each loop.
+     */
+    BitMap2D intervalInLoop;
+
+    /**
+     * The variable operands allocated from this pool. The {@linkplain #operandNumber(CiValue) number}
+     * of the first variable operand in this pool is one greater than the number of the last
+     * register operand in the pool.
+     */
+    private final ArrayList<Variable> variables;
+
+    /**
+     * The {@linkplain #operandNumber(CiValue) number} of the first variable operand
+     * {@linkplain #newVariable(CiKind) allocated} from this pool.
+     */
+    private final int firstVariableNumber;
+
+
+    public LinearScan(CiTarget target, RiResolvedMethod method, LIR ir, LIRGenerator gen, FrameMap frameMap) {
+        this.target = target;
+        this.method = method;
+        this.ir = ir;
+        this.gen = gen;
+        this.frameMap = frameMap;
+        this.sortedBlocks = ir.linearScanOrder().toArray(new Block[ir.linearScanOrder().size()]);
+        this.registerAttributes = frameMap.registerConfig.getAttributesMap();
+
+        this.registers = target.arch.registers;
+        this.firstVariableNumber = registers.length;
+        this.variables = new ArrayList<>(ir.numVariables() * 3 / 2);
+        this.blockData = new BlockMap<>(ir.cfg);
+    }
+
+    public static boolean isVariableOrRegister(CiValue value) {
+        return isVariable(value) || isRegister(value);
+    }
+
+
+    /**
+     * Converts an operand (variable or register) to an index in a flat address space covering all the
+     * {@linkplain Variable variables} and {@linkplain CiRegisterValue registers} being processed by this
+     * allocator.
+     */
+    private int operandNumber(CiValue operand) {
+        if (isRegister(operand)) {
+            int number = asRegister(operand).number;
+            assert number < firstVariableNumber;
+            return number;
+        }
+        assert isVariable(operand) : operand;
+        return firstVariableNumber + ((Variable) operand).index;
+    }
+
+    /**
+     * Gets the operand denoted by a given operand number.
+     */
+    private CiValue operandFor(int operandNumber) {
+        if (operandNumber < firstVariableNumber) {
+            assert operandNumber >= 0;
+            return registers[operandNumber].asValue();
+        }
+        int index = operandNumber - firstVariableNumber;
+        Variable variable = variables.get(index);
+        assert variable.index == index;
+        return variable;
+    }
+
+    /**
+     * Gets the number of operands. This value will increase by 1 for new variable.
+     */
+    private int operandSize() {
+        return firstVariableNumber + ir.numVariables();
+    }
+
+    /**
+     * Gets the highest operand number for a register operand. This value will never change.
+     */
+    public int maxRegisterNumber() {
+        return firstVariableNumber - 1;
+    }
+
+
+    static final IntervalPredicate IS_PRECOLORED_INTERVAL = new IntervalPredicate() {
+        @Override
+        public boolean apply(Interval i) {
+            return isRegister(i.operand);
+        }
+    };
+
+    static final IntervalPredicate IS_VARIABLE_INTERVAL = new IntervalPredicate() {
+        @Override
+        public boolean apply(Interval i) {
+            return isVariable(i.operand);
+        }
+    };
+
+    static final IntervalPredicate IS_OOP_INTERVAL = new IntervalPredicate() {
+        @Override
+        public boolean apply(Interval i) {
+            return !isRegister(i.operand) && i.kind()  == CiKind.Object;
+        }
+    };
+
+    /**
+     * Gets an object describing the attributes of a given register according to this register configuration.
+     */
+    RiRegisterAttributes attributes(CiRegister reg) {
+        return registerAttributes[reg.number];
+    }
+
+    void assignSpillSlot(Interval interval) {
+        // assign the canonical spill slot of the parent (if a part of the interval
+        // is already spilled) or allocate a new spill slot
+        if (interval.spillSlot() != null) {
+            interval.assignLocation(interval.spillSlot());
+        } else {
+            CiStackSlot slot = frameMap.allocateSpillSlot(interval.kind());
+            interval.setSpillSlot(slot);
+            interval.assignLocation(slot);
+        }
+    }
+
+    /**
+     * Creates a new interval.
+     *
+     * @param operand the operand for the interval
+     * @return the created interval
+     */
+    Interval createInterval(CiValue operand) {
+        assert isProcessed(operand);
+        assert isLegal(operand);
+        int operandNumber = operandNumber(operand);
+        Interval interval = new Interval(operand, operandNumber);
+        assert operandNumber < intervalsSize;
+        assert intervals[operandNumber] == null;
+        intervals[operandNumber] = interval;
+        return interval;
+    }
+
+    /**
+     * Creates an interval as a result of splitting or spilling another interval.
+     *
+     * @param source an interval being split of spilled
+     * @return a new interval derived from {@code source}
+     */
+    Interval createDerivedInterval(Interval source) {
+        if (firstDerivedIntervalIndex == -1) {
+            firstDerivedIntervalIndex = intervalsSize;
+        }
+        if (intervalsSize == intervals.length) {
+            intervals = Arrays.copyOf(intervals, intervals.length * 2);
+        }
+        intervalsSize++;
+        Variable variable = new Variable(source.kind(), ir.nextVariable(), asVariable(source.operand).flag);
+        assert variables.size() == variable.index;
+        variables.add(variable);
+
+        Interval interval = createInterval(variable);
+        assert intervals[intervalsSize - 1] == interval;
+        return interval;
+    }
+
+    // access to block list (sorted in linear scan order)
+    int blockCount() {
+        assert sortedBlocks.length == ir.linearScanOrder().size() : "invalid cached block list";
+        return sortedBlocks.length;
+    }
+
+    Block blockAt(int index) {
+        assert sortedBlocks[index] == ir.linearScanOrder().get(index) : "invalid cached block list";
+        return sortedBlocks[index];
+    }
+
+    /**
+     * Gets the size of the {@link Block#liveIn} and {@link Block#liveOut} sets for a basic block. These sets do
+     * not include any operands allocated as a result of creating {@linkplain #createDerivedInterval(Interval) derived
+     * intervals}.
+     */
+    int liveSetSize() {
+        return firstDerivedIntervalIndex == -1 ? operandSize() : firstDerivedIntervalIndex;
+    }
+
+    int numLoops() {
+        return ir.cfg.getLoops().length;
+    }
+
+    boolean isIntervalInLoop(int interval, int loop) {
+        return intervalInLoop.at(interval, loop);
+    }
+
+    Interval intervalFor(CiValue operand) {
+        int operandNumber = operandNumber(operand);
+        assert operandNumber < intervalsSize;
+        return intervals[operandNumber];
+    }
+
+    /**
+     * Gets the highest instruction id allocated by this object.
+     */
+    int maxOpId() {
+        assert opIdToInstructionMap.length > 0 : "no operations";
+        return (opIdToInstructionMap.length - 1) << 1;
+    }
+
+    /**
+     * Converts an {@linkplain LIRInstruction#id instruction id} to an instruction index.
+     * All LIR instructions in a method have an index one greater than their linear-scan order predecesor
+     * with the first instruction having an index of 0.
+     */
+    static int opIdToIndex(int opId) {
+        return opId >> 1;
+    }
+
+    /**
+     * Retrieves the {@link LIRInstruction} based on its {@linkplain LIRInstruction#id id}.
+     *
+     * @param opId an instruction {@linkplain LIRInstruction#id id}
+     * @return the instruction whose {@linkplain LIRInstruction#id} {@code == id}
+     */
+    LIRInstruction instructionForId(int opId) {
+        assert isEven(opId) : "opId not even";
+        LIRInstruction instr = opIdToInstructionMap[opIdToIndex(opId)];
+        assert instr.id() == opId;
+        return instr;
+    }
+
+    /**
+     * Gets the block containing a given instruction.
+     *
+     * @param opId an instruction {@linkplain LIRInstruction#id id}
+     * @return the block containing the instruction denoted by {@code opId}
+     */
+    Block blockForId(int opId) {
+        assert opIdToBlockMap.length > 0 && opId >= 0 && opId <= maxOpId() + 1 : "opId out of range";
+        return opIdToBlockMap[opIdToIndex(opId)];
+    }
+
+    boolean isBlockBegin(int opId) {
+        return opId == 0 || blockForId(opId) != blockForId(opId - 1);
+    }
+
+    boolean coversBlockBegin(int opId1, int opId2) {
+        return blockForId(opId1) != blockForId(opId2);
+    }
+
+    /**
+     * Determines if an {@link LIRInstruction} destroys all caller saved registers.
+     *
+     * @param opId an instruction {@linkplain LIRInstruction#id id}
+     * @return {@code true} if the instruction denoted by {@code id} destroys all caller saved registers.
+     */
+    boolean hasCall(int opId) {
+        assert isEven(opId) : "opId not even";
+        return instructionForId(opId).hasCall();
+    }
+
+    /**
+     * Eliminates moves from register to stack if the stack slot is known to be correct.
+     */
+    void changeSpillDefinitionPos(Interval interval, int defPos) {
+        assert interval.isSplitParent() : "can only be called for split parents";
+
+        switch (interval.spillState()) {
+            case NoDefinitionFound:
+                assert interval.spillDefinitionPos() == -1 : "must no be set before";
+                interval.setSpillDefinitionPos(defPos);
+                interval.setSpillState(SpillState.NoSpillStore);
+                break;
+
+            case NoSpillStore:
+                assert defPos <= interval.spillDefinitionPos() : "positions are processed in reverse order when intervals are created";
+                if (defPos < interval.spillDefinitionPos() - 2 || instructionForId(interval.spillDefinitionPos()) instanceof LIRXirInstruction) {
+                    // second definition found, so no spill optimization possible for this interval
+                    interval.setSpillState(SpillState.NoOptimization);
+                } else {
+                    // two consecutive definitions (because of two-operand LIR form)
+                    assert blockForId(defPos) == blockForId(interval.spillDefinitionPos()) : "block must be equal";
+                }
+                break;
+
+            case NoOptimization:
+                // nothing to do
+                break;
+
+            default:
+                throw new CiBailout("other states not allowed at this time");
+        }
+    }
+
+    // called during register allocation
+    void changeSpillState(Interval interval, int spillPos) {
+        switch (interval.spillState()) {
+            case NoSpillStore: {
+                int defLoopDepth = blockForId(interval.spillDefinitionPos()).getLoopDepth();
+                int spillLoopDepth = blockForId(spillPos).getLoopDepth();
+
+                if (defLoopDepth < spillLoopDepth) {
+                    // the loop depth of the spilling position is higher then the loop depth
+                    // at the definition of the interval . move write to memory out of loop
+                    // by storing at definitin of the interval
+                    interval.setSpillState(SpillState.StoreAtDefinition);
+                } else {
+                    // the interval is currently spilled only once, so for now there is no
+                    // reason to store the interval at the definition
+                    interval.setSpillState(SpillState.OneSpillStore);
+                }
+                break;
+            }
+
+            case OneSpillStore: {
+                // the interval is spilled more then once, so it is better to store it to
+                // memory at the definition
+                interval.setSpillState(SpillState.StoreAtDefinition);
+                break;
+            }
+
+            case StoreAtDefinition:
+            case StartInMemory:
+            case NoOptimization:
+            case NoDefinitionFound:
+                // nothing to do
+                break;
+
+            default:
+                throw new CiBailout("other states not allowed at this time");
+        }
+    }
+
+    abstract static class IntervalPredicate {
+        abstract boolean apply(Interval i);
+    }
+
+    private static final IntervalPredicate mustStoreAtDefinition = new IntervalPredicate() {
+        @Override
+        public boolean apply(Interval i) {
+            return i.isSplitParent() && i.spillState() == SpillState.StoreAtDefinition;
+        }
+    };
+
+    // called once before assignment of register numbers
+    void eliminateSpillMoves() {
+        if (GraalOptions.TraceLinearScanLevel >= 3) {
+            TTY.println(" Eliminating unnecessary spill moves");
+        }
+
+        // collect all intervals that must be stored after their definition.
+        // the list is sorted by Interval.spillDefinitionPos
+        Interval interval;
+        interval = createUnhandledLists(mustStoreAtDefinition, null).first;
+        if (GraalOptions.DetailedAsserts) {
+            checkIntervals(interval);
+        }
+
+        LIRInsertionBuffer insertionBuffer = new LIRInsertionBuffer();
+        int numBlocks = blockCount();
+        for (int i = 0; i < numBlocks; i++) {
+            Block block = blockAt(i);
+            List<LIRInstruction> instructions = block.lir;
+            int numInst = instructions.size();
+
+            // iterate all instructions of the block. skip the first because it is always a label
+            for (int j = 1; j < numInst; j++) {
+                LIRInstruction op = instructions.get(j);
+                int opId = op.id();
+
+                if (opId == -1) {
+                    MoveOp move = (MoveOp) op;
+                    // remove move from register to stack if the stack slot is guaranteed to be correct.
+                    // only moves that have been inserted by LinearScan can be removed.
+                    assert isVariable(move.getResult()) : "LinearScan inserts only moves to variables";
+
+                    Interval curInterval = intervalFor(move.getResult());
+
+                    if (!isRegister(curInterval.location()) && curInterval.alwaysInMemory()) {
+                        // move target is a stack slot that is always correct, so eliminate instruction
+                        if (GraalOptions.TraceLinearScanLevel >= 4) {
+                            TTY.println("eliminating move from interval %d to %d", operandNumber(move.getInput()), operandNumber(move.getResult()));
+                        }
+                        instructions.set(j, null); // null-instructions are deleted by assignRegNum
+                    }
+
+                } else {
+                    // insert move from register to stack just after the beginning of the interval
+                    assert interval == Interval.EndMarker || interval.spillDefinitionPos() >= opId : "invalid order";
+                    assert interval == Interval.EndMarker || (interval.isSplitParent() && interval.spillState() == SpillState.StoreAtDefinition) : "invalid interval";
+
+                    while (interval != Interval.EndMarker && interval.spillDefinitionPos() == opId) {
+                        if (!insertionBuffer.initialized()) {
+                            // prepare insertion buffer (appended when all instructions of the block are processed)
+                            insertionBuffer.init(block.lir);
+                        }
+
+                        CiValue fromLocation = interval.location();
+                        CiValue toLocation = canonicalSpillOpr(interval);
+
+                        assert isRegister(fromLocation) : "from operand must be a register but is: " + fromLocation + " toLocation=" + toLocation + " spillState=" + interval.spillState();
+                        assert isStackSlot(toLocation) : "to operand must be a stack slot";
+
+                        insertionBuffer.append(j + 1, ir.spillMoveFactory.createMove(toLocation, fromLocation));
+
+                        if (GraalOptions.TraceLinearScanLevel >= 4) {
+                            CiStackSlot slot = interval.spillSlot();
+                            TTY.println("inserting move after definition of interval %d to stack slot %s at opId %d",
+                                            interval.operandNumber, slot, opId);
+                        }
+
+                        interval = interval.next;
+                    }
+                }
+            } // end of instruction iteration
+
+            if (insertionBuffer.initialized()) {
+                insertionBuffer.finish();
+            }
+        } // end of block iteration
+
+        assert interval == Interval.EndMarker : "missed an interval";
+    }
+
+    private static void checkIntervals(Interval interval) {
+        Interval prev = null;
+        Interval temp = interval;
+        while (temp != Interval.EndMarker) {
+            assert temp.spillDefinitionPos() > 0 : "invalid spill definition pos";
+            if (prev != null) {
+                assert temp.from() >= prev.from() : "intervals not sorted";
+                assert temp.spillDefinitionPos() >= prev.spillDefinitionPos() : "when intervals are sorted by from :  then they must also be sorted by spillDefinitionPos";
+            }
+
+            assert temp.spillSlot() != null : "interval has no spill slot assigned";
+            assert temp.spillDefinitionPos() >= temp.from() : "invalid order";
+            assert temp.spillDefinitionPos() <= temp.from() + 2 : "only intervals defined once at their start-pos can be optimized";
+
+            if (GraalOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("interval %d (from %d to %d) must be stored at %d", temp.operandNumber, temp.from(), temp.to(), temp.spillDefinitionPos());
+            }
+
+            prev = temp;
+            temp = temp.next;
+        }
+    }
+
+    /**
+     * Numbers all instructions in all blocks. The numbering follows the {@linkplain ComputeLinearScanOrder linear scan order}.
+     */
+    void numberInstructions() {
+        ValueProcedure setVariableProc = new ValueProcedure() {
+            @Override
+            public CiValue doValue(CiValue value) {
+                if (isVariable(value)) {
+                    int variableIdx = asVariable(value).index;
+                    while (variables.size() <= variableIdx) {
+                        variables.add(null);
+                    }
+                    variables.set(variableIdx, asVariable(value));
+                }
+                return value;
+            }
+        };
+
+        // Assign IDs to LIR nodes and build a mapping, lirOps, from ID to LIRInstruction node.
+        int numBlocks = blockCount();
+        int numInstructions = 0;
+        for (int i = 0; i < numBlocks; i++) {
+            numInstructions += blockAt(i).lir.size();
+        }
+
+        // initialize with correct length
+        opIdToInstructionMap = new LIRInstruction[numInstructions];
+        opIdToBlockMap = new Block[numInstructions];
+
+        int opId = 0;
+        int index = 0;
+
+        for (int i = 0; i < numBlocks; i++) {
+            Block block = blockAt(i);
+            blockData.put(block, new BlockData());
+
+            List<LIRInstruction> instructions = block.lir;
+
+            int numInst = instructions.size();
+            for (int j = 0; j < numInst; j++) {
+                LIRInstruction op = instructions.get(j);
+                op.setId(opId);
+
+                opIdToInstructionMap[index] = op;
+                opIdToBlockMap[index] = block;
+                assert instructionForId(opId) == op : "must match";
+
+                op.forEachTemp(setVariableProc);
+                op.forEachOutput(setVariableProc);
+
+                index++;
+                opId += 2; // numbering of lirOps by two
+            }
+        }
+        assert index == numInstructions : "must match";
+        assert (index << 1) == opId : "must match: " + (index << 1);
+
+        if (GraalOptions.DetailedAsserts) {
+            for (int i = 0; i < variables.size(); i++) {
+                assert variables.get(i) != null && variables.get(i).index == i;
+            }
+            assert variables.size() == ir.numVariables();
+        }
+    }
+
+    /**
+     * Computes local live sets (i.e. {@link Block#liveGen} and {@link Block#liveKill}) separately for each block.
+     */
+    void computeLocalLiveSets() {
+        int numBlocks = blockCount();
+        int liveSize = liveSetSize();
+
+        intervalInLoop = new BitMap2D(operandSize(), numLoops());
+
+        // iterate all blocks
+        for (int i = 0; i < numBlocks; i++) {
+            final Block block = blockAt(i);
+            final BitMap liveGen = new BitMap(liveSize);
+            final BitMap liveKill = new BitMap(liveSize);
+
+            List<LIRInstruction> instructions = block.lir;
+            int numInst = instructions.size();
+
+            // iterate all instructions of the block. skip the first because it is always a label
+            assert !instructions.get(0).hasOperands() : "first operation must always be a label";
+            for (int j = 1; j < numInst; j++) {
+                final LIRInstruction op = instructions.get(j);
+
+                ValueProcedure useProc = new ValueProcedure() {
+                    @Override
+                    protected CiValue doValue(CiValue operand) {
+                        if (isVariable(operand)) {
+                            int operandNum = operandNumber(operand);
+                            if (!liveKill.get(operandNum)) {
+                                liveGen.set(operandNum);
+                                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                                    TTY.println("  Setting liveGen for operand %d at instruction %d", operandNum, op.id());
+                                }
+                            }
+                            if (block.getLoop() != null) {
+                                intervalInLoop.setBit(operandNum, block.getLoop().index);
+                            }
+                        }
+
+                        if (GraalOptions.DetailedAsserts) {
+                            verifyInput(block, liveKill, operand);
+                        }
+                        return operand;
+                    }
+                };
+                ValueProcedure stateProc = new ValueProcedure() {
+                    @Override
+                    public CiValue doValue(CiValue operand) {
+                        int operandNum = operandNumber(operand);
+                        if (!liveKill.get(operandNum)) {
+                            liveGen.set(operandNum);
+                            if (GraalOptions.TraceLinearScanLevel >= 4) {
+                                TTY.println("  Setting liveGen for LIR opId %d, operand %d because of state for %s", op.id(), operandNum, op);
+                            }
+                        }
+                        return operand;
+                    }
+                };
+                ValueProcedure defProc = new ValueProcedure() {
+                    @Override
+                    public CiValue doValue(CiValue operand) {
+                        if (isVariable(operand)) {
+                            int varNum = operandNumber(operand);
+                            liveKill.set(varNum);
+                            if (block.getLoop() != null) {
+                                intervalInLoop.setBit(varNum, block.getLoop().index);
+                            }
+                        }
+
+                        if (GraalOptions.DetailedAsserts) {
+                            // fixed intervals are never live at block boundaries, so
+                            // they need not be processed in live sets
+                            // process them only in debug mode so that this can be checked
+                            verifyTemp(liveKill, operand);
+                        }
+                        return operand;
+                    }
+                };
+
+                op.forEachInput(useProc);
+                op.forEachAlive(useProc);
+                // Add uses of live locals from interpreter's point of view for proper debug information generation
+                op.forEachState(stateProc);
+                op.forEachTemp(defProc);
+                op.forEachOutput(defProc);
+            } // end of instruction iteration
+
+            blockData.get(block).liveGen = liveGen;
+            blockData.get(block).liveKill = liveKill;
+            blockData.get(block).liveIn = new BitMap(liveSize);
+            blockData.get(block).liveOut = new BitMap(liveSize);
+
+            if (GraalOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("liveGen  B%d %s", block.getId(), blockData.get(block).liveGen);
+                TTY.println("liveKill B%d %s", block.getId(), blockData.get(block).liveKill);
+            }
+        } // end of block iteration
+    }
+
+    private void verifyTemp(BitMap liveKill, CiValue operand) {
+        // fixed intervals are never live at block boundaries, so
+        // they need not be processed in live sets
+        // process them only in debug mode so that this can be checked
+        if (isRegister(operand)) {
+            if (isProcessed(operand)) {
+                liveKill.set(operandNumber(operand));
+            }
+        }
+    }
+
+    private void verifyInput(Block block, BitMap liveKill, CiValue operand) {
+        // fixed intervals are never live at block boundaries, so
+        // they need not be processed in live sets.
+        // this is checked by these assertions to be sure about it.
+        // the entry block may have incoming
+        // values in registers, which is ok.
+        if (isRegister(operand) && block != ir.cfg.getStartBlock()) {
+            if (isProcessed(operand)) {
+                assert liveKill.get(operandNumber(operand)) : "using fixed register that is not defined in this block";
+            }
+        }
+    }
+
+    /**
+     * Performs a backward dataflow analysis to compute global live sets (i.e. {@link Block#liveIn} and
+     * {@link Block#liveOut}) for each block.
+     */
+    void computeGlobalLiveSets() {
+        int numBlocks = blockCount();
+        boolean changeOccurred;
+        boolean changeOccurredInBlock;
+        int iterationCount = 0;
+        BitMap liveOut = new BitMap(liveSetSize()); // scratch set for calculations
+
+        // Perform a backward dataflow analysis to compute liveOut and liveIn for each block.
+        // The loop is executed until a fixpoint is reached (no changes in an iteration)
+        do {
+            changeOccurred = false;
+
+            // iterate all blocks in reverse order
+            for (int i = numBlocks - 1; i >= 0; i--) {
+                Block block = blockAt(i);
+
+                changeOccurredInBlock = false;
+
+                // liveOut(block) is the union of liveIn(sux), for successors sux of block
+                int n = block.numberOfSux();
+                if (n > 0) {
+                    // block has successors
+                    if (n > 0) {
+                        liveOut.setFrom(blockData.get(block.suxAt(0)).liveIn);
+                        for (int j = 1; j < n; j++) {
+                            liveOut.setUnion(blockData.get(block.suxAt(j)).liveIn);
+                        }
+                    } else {
+                        liveOut.clearAll();
+                    }
+
+                    if (!blockData.get(block).liveOut.isSame(liveOut)) {
+                        // A change occurred. Swap the old and new live out sets to avoid copying.
+                        BitMap temp = blockData.get(block).liveOut;
+                        blockData.get(block).liveOut = liveOut;
+                        liveOut = temp;
+
+                        changeOccurred = true;
+                        changeOccurredInBlock = true;
+                    }
+                }
+
+                if (iterationCount == 0 || changeOccurredInBlock) {
+                    // liveIn(block) is the union of liveGen(block) with (liveOut(block) & !liveKill(block))
+                    // note: liveIn has to be computed only in first iteration or if liveOut has changed!
+                    BitMap liveIn = blockData.get(block).liveIn;
+                    liveIn.setFrom(blockData.get(block).liveOut);
+                    liveIn.setDifference(blockData.get(block).liveKill);
+                    liveIn.setUnion(blockData.get(block).liveGen);
+                }
+
+                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                    traceLiveness(changeOccurredInBlock, iterationCount, block);
+                }
+            }
+            iterationCount++;
+
+            if (changeOccurred && iterationCount > 50) {
+                throw new CiBailout("too many iterations in computeGlobalLiveSets");
+            }
+        } while (changeOccurred);
+
+        if (GraalOptions.DetailedAsserts) {
+            verifyLiveness(numBlocks);
+        }
+
+        // check that the liveIn set of the first block is empty
+        Block startBlock = ir.cfg.getStartBlock();
+        BitMap liveInArgs = new BitMap(blockData.get(startBlock).liveIn.size());
+        if (!blockData.get(startBlock).liveIn.isSame(liveInArgs)) {
+            if (GraalOptions.DetailedAsserts) {
+                reportFailure(numBlocks);
+            }
+
+            TTY.println("preds=" + startBlock.getPredecessors().size() + ", succs=" + startBlock.getSuccessors().size());
+            TTY.println("startBlock-ID: " + startBlock.getId());
+
+            // bailout of if this occurs in product mode.
+            throw new CiBailout("liveIn set of first block must be empty");
+        }
+    }
+
+    private void reportFailure(int numBlocks) {
+        TTY.println(method.toString());
+        TTY.println("Error: liveIn set of first block must be empty (when this fails, variables are used before they are defined)");
+        TTY.print("affected registers:");
+        TTY.println(blockData.get(ir.cfg.getStartBlock()).liveIn.toString());
+
+        // print some additional information to simplify debugging
+        for (int operandNum = 0; operandNum < blockData.get(ir.cfg.getStartBlock()).liveIn.size(); operandNum++) {
+            if (blockData.get(ir.cfg.getStartBlock()).liveIn.get(operandNum)) {
+                CiValue operand = operandFor(operandNum);
+                TTY.println(" var %d; operand=%s", operandNum, operand.toString());
+
+                for (int j = 0; j < numBlocks; j++) {
+                    Block block = blockAt(j);
+                    if (blockData.get(block).liveGen.get(operandNum)) {
+                        TTY.println("  used in block B%d", block.getId());
+                        for (LIRInstruction ins : block.lir) {
+                            TTY.println(ins.id() + ": " + ins.toString());
+                            LIRDebugInfo info = ins.info;
+                            if (info != null) {
+                                info.forEachState(new ValueProcedure() {
+                                    @Override
+                                    public CiValue doValue(CiValue liveStateOperand) {
+                                        TTY.println("   operand=" + liveStateOperand);
+                                        return liveStateOperand;
+                                    }
+                                });
+                            }
+                        }
+                    }
+                    if (blockData.get(block).liveKill.get(operandNum)) {
+                        TTY.println("  defined in block B%d", block.getId());
+                        for (LIRInstruction ins : block.lir) {
+                            TTY.println(ins.id() + ": " + ins.toString());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void verifyLiveness(int numBlocks) {
+        // check that fixed intervals are not live at block boundaries
+        // (live set must be empty at fixed intervals)
+        for (int i = 0; i < numBlocks; i++) {
+            Block block = blockAt(i);
+            for (int j = 0; j <= maxRegisterNumber(); j++) {
+                assert !blockData.get(block).liveIn.get(j) : "liveIn  set of fixed register must be empty";
+                assert !blockData.get(block).liveOut.get(j) : "liveOut set of fixed register must be empty";
+                assert !blockData.get(block).liveGen.get(j) : "liveGen set of fixed register must be empty";
+            }
+        }
+    }
+
+    private void traceLiveness(boolean changeOccurredInBlock, int iterationCount, Block block) {
+        char c = iterationCount == 0 || changeOccurredInBlock ? '*' : ' ';
+        TTY.print("(%d) liveIn%c  B%d ", iterationCount, c, block.getId());
+        TTY.println(blockData.get(block).liveIn.toString());
+        TTY.print("(%d) liveOut%c B%d ", iterationCount, c, block.getId());
+        TTY.println(blockData.get(block).liveOut.toString());
+    }
+
+    void addUse(CiValue operand, int from, int to, RegisterPriority registerPriority, CiKind kind) {
+        if (!isProcessed(operand)) {
+            return;
+        }
+        if (GraalOptions.TraceLinearScanLevel >= 2 && kind == null) {
+            TTY.println(" use %s from %d to %d (%s)", operand, from, to, registerPriority.name());
+        }
+
+        Interval interval = intervalFor(operand);
+        if (interval == null) {
+            interval = createInterval(operand);
+        }
+
+        if (kind != CiKind.Illegal) {
+            interval.setKind(kind);
+        }
+
+        interval.addRange(from, to);
+
+        // Register use position at even instruction id.
+        interval.addUsePos(to & ~1, registerPriority);
+    }
+
+    void addTemp(CiValue operand, int tempPos, RegisterPriority registerPriority, CiKind kind) {
+        if (!isProcessed(operand)) {
+            return;
+        }
+        if (GraalOptions.TraceLinearScanLevel >= 2) {
+            TTY.println(" temp %s tempPos %d (%s)", operand, tempPos, RegisterPriority.MustHaveRegister.name());
+        }
+        Interval interval = intervalFor(operand);
+        if (interval == null) {
+            interval = createInterval(operand);
+        }
+
+        if (kind != CiKind.Illegal) {
+            interval.setKind(kind);
+        }
+
+        interval.addRange(tempPos, tempPos + 1);
+        interval.addUsePos(tempPos, registerPriority);
+    }
+
+    boolean isProcessed(CiValue operand) {
+        return !isRegister(operand) || attributes(asRegister(operand)).isAllocatable;
+    }
+
+    void addDef(CiValue operand, int defPos, RegisterPriority registerPriority, CiKind kind) {
+        if (!isProcessed(operand)) {
+            return;
+        }
+        if (GraalOptions.TraceLinearScanLevel >= 2) {
+            TTY.println(" def %s defPos %d (%s)", operand, defPos, registerPriority.name());
+        }
+        Interval interval = intervalFor(operand);
+        if (interval != null) {
+
+            if (kind != CiKind.Illegal) {
+                interval.setKind(kind);
+            }
+
+            Range r = interval.first();
+            if (r.from <= defPos) {
+                // Update the starting point (when a range is first created for a use, its
+                // start is the beginning of the current block until a def is encountered.)
+                r.from = defPos;
+                interval.addUsePos(defPos, registerPriority);
+
+            } else {
+                // Dead value - make vacuous interval
+                // also add register priority for dead intervals
+                interval.addRange(defPos, defPos + 1);
+                interval.addUsePos(defPos, registerPriority);
+                if (GraalOptions.TraceLinearScanLevel >= 2) {
+                    TTY.println("Warning: def of operand %s at %d occurs without use", operand, defPos);
+                }
+            }
+
+        } else {
+            // Dead value - make vacuous interval
+            // also add register priority for dead intervals
+            interval = createInterval(operand);
+            if (kind != CiKind.Illegal) {
+                interval.setKind(kind);
+            }
+
+            interval.addRange(defPos, defPos + 1);
+            interval.addUsePos(defPos, registerPriority);
+            if (GraalOptions.TraceLinearScanLevel >= 2) {
+                TTY.println("Warning: dead value %s at %d in live intervals", operand, defPos);
+            }
+        }
+
+        changeSpillDefinitionPos(interval, defPos);
+        if (registerPriority == RegisterPriority.None && interval.spillState().ordinal() <= SpillState.StartInMemory.ordinal()) {
+            // detection of method-parameters and roundfp-results
+            // TODO: move this directly to position where use-kind is computed
+            interval.setSpillState(SpillState.StartInMemory);
+        }
+    }
+
+    /**
+     * Determines the register priority for an instruction's output/result operand.
+     */
+    static RegisterPriority registerPriorityOfOutputOperand(LIRInstruction op) {
+        if (op instanceof MoveOp) {
+            MoveOp move = (MoveOp) op;
+            if (isStackSlot(move.getInput()) && move.getInput().kind != CiKind.Object) {
+                // method argument (condition must be equal to handleMethodArguments)
+                return RegisterPriority.None;
+            }
+        }
+
+        // all other operands require a register
+        return RegisterPriority.MustHaveRegister;
+    }
+
+    /**
+     * Determines the priority which with an instruction's input operand will be allocated a register.
+     */
+    static RegisterPriority registerPriorityOfInputOperand(EnumSet<OperandFlag> flags) {
+        if (flags.contains(OperandFlag.Stack)) {
+            return RegisterPriority.ShouldHaveRegister;
+        }
+        // all other operands require a register
+        return RegisterPriority.MustHaveRegister;
+    }
+
+    /**
+     * Optimizes moves related to incoming stack based arguments.
+     * The interval for the destination of such moves is assigned
+     * the stack slot (which is in the caller's frame) as its
+     * spill slot.
+     */
+    void handleMethodArguments(LIRInstruction op) {
+        if (op instanceof MoveOp) {
+            MoveOp move = (MoveOp) op;
+            if (isStackSlot(move.getInput()) && move.getInput().kind != CiKind.Object) {
+                CiStackSlot slot = (CiStackSlot) move.getInput();
+                if (GraalOptions.DetailedAsserts) {
+                    assert op.id() > 0 : "invalid id";
+                    assert blockForId(op.id()).numberOfPreds() == 0 : "move from stack must be in first block";
+                    assert isVariable(move.getResult()) : "result of move must be a variable";
+
+                    if (GraalOptions.TraceLinearScanLevel >= 4) {
+                        TTY.println("found move from stack slot %s to %s", slot, move.getResult());
+                    }
+                }
+
+                Interval interval = intervalFor(move.getResult());
+                interval.setSpillSlot(slot);
+                interval.assignLocation(slot);
+            }
+        }
+    }
+
+    void addRegisterHint(final LIRInstruction op, final CiValue targetValue, OperandMode mode, EnumSet<OperandFlag> flags) {
+        if (flags.contains(OperandFlag.RegisterHint) && isVariableOrRegister(targetValue)) {
+
+            op.forEachRegisterHint(targetValue, mode, new ValueProcedure() {
+                @Override
+                protected CiValue doValue(CiValue registerHint) {
+                    if (isVariableOrRegister(registerHint)) {
+                        Interval from = intervalFor(registerHint);
+                        Interval to = intervalFor(targetValue);
+                        if (from != null && to != null) {
+                            to.setLocationHint(from);
+                            if (GraalOptions.TraceLinearScanLevel >= 4) {
+                                TTY.println("operation at opId %d: added hint from interval %d to %d", op.id(), from.operandNumber, to.operandNumber);
+                            }
+                            return registerHint;
+                        }
+                    }
+                    return null;
+                }
+            });
+        }
+    }
+
+    void buildIntervals() {
+        intervalsSize = operandSize();
+        intervals = new Interval[intervalsSize + INITIAL_SPLIT_INTERVALS_CAPACITY];
+
+        // create a list with all caller-save registers (cpu, fpu, xmm)
+        CiRegister[] callerSaveRegs = frameMap.registerConfig.getCallerSaveRegisters();
+
+        // iterate all blocks in reverse order
+        for (int i = blockCount() - 1; i >= 0; i--) {
+            Block block = blockAt(i);
+            List<LIRInstruction> instructions = block.lir;
+            final int blockFrom = block.getFirstLirInstructionId();
+            int blockTo = block.getLastLirInstructionId();
+
+            assert blockFrom == instructions.get(0).id();
+            assert blockTo == instructions.get(instructions.size() - 1).id();
+
+            // Update intervals for operands live at the end of this block;
+            BitMap live = blockData.get(block).liveOut;
+            for (int operandNum = live.nextSetBit(0); operandNum >= 0; operandNum = live.nextSetBit(operandNum + 1)) {
+                assert live.get(operandNum) : "should not stop here otherwise";
+                CiValue operand = operandFor(operandNum);
+                if (GraalOptions.TraceLinearScanLevel >= 2) {
+                    TTY.println("live in %s to %d", operand, blockTo + 2);
+                }
+
+                addUse(operand, blockFrom, blockTo + 2, RegisterPriority.None, CiKind.Illegal);
+
+                // add special use positions for loop-end blocks when the
+                // interval is used anywhere inside this loop. It's possible
+                // that the block was part of a non-natural loop, so it might
+                // have an invalid loop index.
+                if (block.isLoopEnd() && block.getLoop() != null && isIntervalInLoop(operandNum, block.getLoop().index)) {
+                    intervalFor(operand).addUsePos(blockTo + 1, RegisterPriority.LiveAtLoopEnd);
+                }
+            }
+
+            // iterate all instructions of the block in reverse order.
+            // skip the first instruction because it is always a label
+            // definitions of intervals are processed before uses
+            assert !instructions.get(0).hasOperands() : "first operation must always be a label";
+            for (int j = instructions.size() - 1; j >= 1; j--) {
+                final LIRInstruction op = instructions.get(j);
+                final int opId = op.id();
+
+                // add a temp range for each register if operation destroys caller-save registers
+                if (op.hasCall()) {
+                    for (CiRegister r : callerSaveRegs) {
+                        if (attributes(r).isAllocatable) {
+                            addTemp(r.asValue(), opId, RegisterPriority.None, CiKind.Illegal);
+                        }
+                    }
+                    if (GraalOptions.TraceLinearScanLevel >= 4) {
+                        TTY.println("operation destroys all caller-save registers");
+                    }
+                }
+
+                op.forEachOutput(new ValueProcedure() {
+                    @Override
+                    public CiValue doValue(CiValue operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                        if (isVariableOrRegister(operand)) {
+                            addDef(operand, opId, registerPriorityOfOutputOperand(op), operand.kind.stackKind());
+                            addRegisterHint(op, operand, mode, flags);
+                        }
+                        return operand;
+                    }
+                });
+                op.forEachTemp(new ValueProcedure() {
+                    @Override
+                    public CiValue doValue(CiValue operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                        if (isVariableOrRegister(operand)) {
+                            addTemp(operand, opId, RegisterPriority.MustHaveRegister, operand.kind.stackKind());
+                            addRegisterHint(op, operand, mode, flags);
+                        }
+                        return operand;
+                    }
+                });
+                op.forEachAlive(new ValueProcedure() {
+                    @Override
+                    public CiValue doValue(CiValue operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                        if (isVariableOrRegister(operand)) {
+                            RegisterPriority p = registerPriorityOfInputOperand(flags);
+                            addUse(operand, blockFrom, opId + 1, p, operand.kind.stackKind());
+                            addRegisterHint(op, operand, mode, flags);
+                        }
+                        return operand;
+                    }
+                });
+                op.forEachInput(new ValueProcedure() {
+                    @Override
+                    public CiValue doValue(CiValue operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                        if (isVariableOrRegister(operand)) {
+                            RegisterPriority p = registerPriorityOfInputOperand(flags);
+                            addUse(operand, blockFrom, opId, p, operand.kind.stackKind());
+                            addRegisterHint(op, operand, mode, flags);
+                        }
+                        return operand;
+                    }
+                });
+
+                // Add uses of live locals from interpreter's point of view for proper
+                // debug information generation
+                // Treat these operands as temp values (if the live range is extended
+                // to a call site, the value would be in a register at the call otherwise)
+                op.forEachState(new ValueProcedure() {
+                    @Override
+                    public CiValue doValue(CiValue operand) {
+                        addUse(operand, blockFrom, opId + 1, RegisterPriority.None, operand.kind.stackKind());
+                        return operand;
+                    }
+                });
+
+                // special steps for some instructions (especially moves)
+                handleMethodArguments(op);
+
+            } // end of instruction iteration
+        } // end of block iteration
+
+        // add the range [0, 1] to all fixed intervals.
+        // the register allocator need not handle unhandled fixed intervals
+        for (Interval interval : intervals) {
+            if (interval != null && isRegister(interval.operand)) {
+                interval.addRange(0, 1);
+            }
+        }
+    }
+
+    // * Phase 5: actual register allocation
+
+    private static boolean isSorted(Interval[] intervals) {
+        int from = -1;
+        for (Interval interval : intervals) {
+            assert interval != null;
+            assert from <= interval.from();
+            from = interval.from();
+        }
+        return true;
+    }
+
+    static Interval addToList(Interval first, Interval prev, Interval interval) {
+        Interval newFirst = first;
+        if (prev != null) {
+            prev.next = interval;
+        } else {
+            newFirst = interval;
+        }
+        return newFirst;
+    }
+
+    Interval.Pair createUnhandledLists(IntervalPredicate isList1, IntervalPredicate isList2) {
+        assert isSorted(sortedIntervals) : "interval list is not sorted";
+
+        Interval list1 = Interval.EndMarker;
+        Interval list2 = Interval.EndMarker;
+
+        Interval list1Prev = null;
+        Interval list2Prev = null;
+        Interval v;
+
+        int n = sortedIntervals.length;
+        for (int i = 0; i < n; i++) {
+            v = sortedIntervals[i];
+            if (v == null) {
+                continue;
+            }
+
+            if (isList1.apply(v)) {
+                list1 = addToList(list1, list1Prev, v);
+                list1Prev = v;
+            } else if (isList2 == null || isList2.apply(v)) {
+                list2 = addToList(list2, list2Prev, v);
+                list2Prev = v;
+            }
+        }
+
+        if (list1Prev != null) {
+            list1Prev.next = Interval.EndMarker;
+        }
+        if (list2Prev != null) {
+            list2Prev.next = Interval.EndMarker;
+        }
+
+        assert list1Prev == null || list1Prev.next == Interval.EndMarker : "linear list ends not with sentinel";
+        assert list2Prev == null || list2Prev.next == Interval.EndMarker : "linear list ends not with sentinel";
+
+        return new Interval.Pair(list1, list2);
+    }
+
+    void sortIntervalsBeforeAllocation() {
+        int sortedLen = 0;
+        for (Interval interval : intervals) {
+            if (interval != null) {
+                sortedLen++;
+            }
+        }
+
+        Interval[] sortedList = new Interval[sortedLen];
+        int sortedIdx = 0;
+        int sortedFromMax = -1;
+
+        // special sorting algorithm: the original interval-list is almost sorted,
+        // only some intervals are swapped. So this is much faster than a complete QuickSort
+        for (Interval interval : intervals) {
+            if (interval != null) {
+                int from = interval.from();
+
+                if (sortedFromMax <= from) {
+                    sortedList[sortedIdx++] = interval;
+                    sortedFromMax = interval.from();
+                } else {
+                    // the assumption that the intervals are already sorted failed,
+                    // so this interval must be sorted in manually
+                    int j;
+                    for (j = sortedIdx - 1; j >= 0 && from < sortedList[j].from(); j--) {
+                        sortedList[j + 1] = sortedList[j];
+                    }
+                    sortedList[j + 1] = interval;
+                    sortedIdx++;
+                }
+            }
+        }
+        sortedIntervals = sortedList;
+    }
+
+    void sortIntervalsAfterAllocation() {
+        if (firstDerivedIntervalIndex == -1) {
+            // no intervals have been added during allocation, so sorted list is already up to date
+            return;
+        }
+
+        Interval[] oldList = sortedIntervals;
+        Interval[] newList = Arrays.copyOfRange(intervals, firstDerivedIntervalIndex, intervalsSize);
+        int oldLen = oldList.length;
+        int newLen = newList.length;
+
+        // conventional sort-algorithm for new intervals
+        Arrays.sort(newList, INTERVAL_COMPARATOR);
+
+        // merge old and new list (both already sorted) into one combined list
+        Interval[] combinedList = new Interval[oldLen + newLen];
+        int oldIdx = 0;
+        int newIdx = 0;
+
+        while (oldIdx + newIdx < combinedList.length) {
+            if (newIdx >= newLen || (oldIdx < oldLen && oldList[oldIdx].from() <= newList[newIdx].from())) {
+                combinedList[oldIdx + newIdx] = oldList[oldIdx];
+                oldIdx++;
+            } else {
+                combinedList[oldIdx + newIdx] = newList[newIdx];
+                newIdx++;
+            }
+        }
+
+        sortedIntervals = combinedList;
+    }
+
+    private static final Comparator<Interval> INTERVAL_COMPARATOR = new Comparator<Interval>() {
+
+        public int compare(Interval a, Interval b) {
+            if (a != null) {
+                if (b != null) {
+                    return a.from() - b.from();
+                } else {
+                    return -1;
+                }
+            } else {
+                if (b != null) {
+                    return 1;
+                } else {
+                    return 0;
+                }
+            }
+        }
+    };
+
+    public void allocateRegisters() {
+        Interval precoloredIntervals;
+        Interval notPrecoloredIntervals;
+
+        Interval.Pair result = createUnhandledLists(IS_PRECOLORED_INTERVAL, IS_VARIABLE_INTERVAL);
+        precoloredIntervals = result.first;
+        notPrecoloredIntervals = result.second;
+
+        // allocate cpu registers
+        LinearScanWalker lsw = new LinearScanWalker(this, precoloredIntervals, notPrecoloredIntervals, !target.arch.isX86());
+        lsw.walk();
+        lsw.finishAllocation();
+    }
+
+    // * Phase 6: resolve data flow
+    // (insert moves at edges between blocks if intervals have been split)
+
+    // wrapper for Interval.splitChildAtOpId that performs a bailout in product mode
+    // instead of returning null
+    Interval splitChildAtOpId(Interval interval, int opId, LIRInstruction.OperandMode mode) {
+        Interval result = interval.getSplitChildAtOpId(opId, mode, this);
+
+        if (result != null) {
+            if (GraalOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("Split child at pos " + opId + " of interval " + interval.toString() + " is " + result.toString());
+            }
+            return result;
+        }
+
+        throw new CiBailout("LinearScan: interval is null");
+    }
+
+    Interval intervalAtBlockBegin(Block block, CiValue operand) {
+        assert isVariable(operand) : "register number out of bounds";
+        assert intervalFor(operand) != null : "no interval found";
+
+        return splitChildAtOpId(intervalFor(operand), block.getFirstLirInstructionId(), LIRInstruction.OperandMode.Output);
+    }
+
+    Interval intervalAtBlockEnd(Block block, CiValue operand) {
+        assert isVariable(operand) : "register number out of bounds";
+        assert intervalFor(operand) != null : "no interval found";
+
+        return splitChildAtOpId(intervalFor(operand), block.getLastLirInstructionId() + 1, LIRInstruction.OperandMode.Output);
+    }
+
+    Interval intervalAtOpId(CiValue operand, int opId) {
+        assert isVariable(operand) : "register number out of bounds";
+        assert intervalFor(operand) != null : "no interval found";
+
+        return splitChildAtOpId(intervalFor(operand), opId, LIRInstruction.OperandMode.Input);
+    }
+
+    void resolveCollectMappings(Block fromBlock, Block toBlock, MoveResolver moveResolver) {
+        assert moveResolver.checkEmpty();
+
+        int numOperands = operandSize();
+        BitMap liveAtEdge = blockData.get(toBlock).liveIn;
+
+        // visit all variables for which the liveAtEdge bit is set
+        for (int operandNum = liveAtEdge.nextSetBit(0); operandNum >= 0; operandNum = liveAtEdge.nextSetBit(operandNum + 1)) {
+            assert operandNum < numOperands : "live information set for not exisiting interval";
+            assert blockData.get(fromBlock).liveOut.get(operandNum) && blockData.get(toBlock).liveIn.get(operandNum) : "interval not live at this edge";
+
+            CiValue liveOperand = operandFor(operandNum);
+            Interval fromInterval = intervalAtBlockEnd(fromBlock, liveOperand);
+            Interval toInterval = intervalAtBlockBegin(toBlock, liveOperand);
+
+            if (fromInterval != toInterval && (fromInterval.location() != toInterval.location())) {
+                // need to insert move instruction
+                moveResolver.addMapping(fromInterval, toInterval);
+            }
+        }
+    }
+
+    static void resolveFindInsertPos(Block fromBlock, Block toBlock, MoveResolver moveResolver) {
+        if (fromBlock.numberOfSux() <= 1) {
+            if (GraalOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("inserting moves at end of fromBlock B%d", fromBlock.getId());
+            }
+
+            List<LIRInstruction> instructions = fromBlock.lir;
+            LIRInstruction instr = instructions.get(instructions.size() - 1);
+            if (instr instanceof StandardOp.JumpOp) {
+                // insert moves before branch
+                moveResolver.setInsertPosition(fromBlock.lir, instructions.size() - 1);
+            } else {
+                moveResolver.setInsertPosition(fromBlock.lir, instructions.size());
+            }
+
+        } else {
+            if (GraalOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("inserting moves at beginning of toBlock B%d", toBlock.getId());
+            }
+
+            if (GraalOptions.DetailedAsserts) {
+                assert fromBlock.lir.get(0) instanceof StandardOp.LabelOp : "block does not start with a label";
+
+                // because the number of predecessor edges matches the number of
+                // successor edges, blocks which are reached by switch statements
+                // may have be more than one predecessor but it will be guaranteed
+                // that all predecessors will be the same.
+                for (int i = 0; i < toBlock.numberOfPreds(); i++) {
+                    assert fromBlock == toBlock.predAt(i) : "all critical edges must be broken";
+                }
+            }
+
+            moveResolver.setInsertPosition(toBlock.lir, 1);
+        }
+    }
+
+    /**
+     * Inserts necessary moves (spilling or reloading) at edges between blocks for intervals that
+     * have been split.
+     */
+    void resolveDataFlow() {
+        int numBlocks = blockCount();
+        MoveResolver moveResolver = new MoveResolver(this);
+        BitMap blockCompleted = new BitMap(numBlocks);
+        BitMap alreadyResolved = new BitMap(numBlocks);
+
+        int i;
+        for (i = 0; i < numBlocks; i++) {
+            Block block = blockAt(i);
+
+            // check if block has only one predecessor and only one successor
+            if (block.numberOfPreds() == 1 && block.numberOfSux() == 1) {
+                List<LIRInstruction> instructions = block.lir;
+                assert instructions.get(0) instanceof StandardOp.LabelOp : "block must start with label";
+                assert instructions.get(instructions.size() - 1) instanceof StandardOp.JumpOp : "block with successor must end with unconditional jump";
+
+                // check if block is empty (only label and branch)
+                if (instructions.size() == 2) {
+                    Block pred = block.predAt(0);
+                    Block sux = block.suxAt(0);
+
+                    // prevent optimization of two consecutive blocks
+                    if (!blockCompleted.get(pred.linearScanNumber) && !blockCompleted.get(sux.linearScanNumber)) {
+                        if (GraalOptions.TraceLinearScanLevel >= 3) {
+                            TTY.println(" optimizing empty block B%d (pred: B%d, sux: B%d)", block.getId(), pred.getId(), sux.getId());
+                        }
+                        blockCompleted.set(block.linearScanNumber);
+
+                        // directly resolve between pred and sux (without looking at the empty block between)
+                        resolveCollectMappings(pred, sux, moveResolver);
+                        if (moveResolver.hasMappings()) {
+                            moveResolver.setInsertPosition(block.lir, 1);
+                            moveResolver.resolveAndAppendMoves();
+                        }
+                    }
+                }
+            }
+        }
+
+        for (i = 0; i < numBlocks; i++) {
+            if (!blockCompleted.get(i)) {
+                Block fromBlock = blockAt(i);
+                alreadyResolved.setFrom(blockCompleted);
+
+                int numSux = fromBlock.numberOfSux();
+                for (int s = 0; s < numSux; s++) {
+                    Block toBlock = fromBlock.suxAt(s);
+
+                    // check for duplicate edges between the same blocks (can happen with switch blocks)
+                    if (!alreadyResolved.get(toBlock.linearScanNumber)) {
+                        if (GraalOptions.TraceLinearScanLevel >= 3) {
+                            TTY.println(" processing edge between B%d and B%d", fromBlock.getId(), toBlock.getId());
+                        }
+                        alreadyResolved.set(toBlock.linearScanNumber);
+
+                        // collect all intervals that have been split between fromBlock and toBlock
+                        resolveCollectMappings(fromBlock, toBlock, moveResolver);
+                        if (moveResolver.hasMappings()) {
+                            resolveFindInsertPos(fromBlock, toBlock, moveResolver);
+                            moveResolver.resolveAndAppendMoves();
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    // * Phase 7: assign register numbers back to LIR
+    // (includes computation of debug information and oop maps)
+
+    boolean verifyAssignedLocation(Interval interval, CiValue location) {
+        CiKind kind = interval.kind();
+
+        assert isRegister(location) || isStackSlot(location);
+
+        if (isRegister(location)) {
+            CiRegister reg = asRegister(location);
+
+            // register
+            switch (kind) {
+                case Byte:
+                case Char:
+                case Short:
+                case Jsr:
+                case Object:
+                case Int: {
+                    assert reg.isCpu() : "not cpu register";
+                    break;
+                }
+
+                case Long: {
+                    assert reg.isCpu() : "not cpu register";
+                    break;
+                }
+
+                case Float: {
+                    assert !target.arch.isX86() || reg.isFpu() : "not xmm register: " + reg;
+                    break;
+                }
+
+                case Double: {
+                    assert !target.arch.isX86() || reg.isFpu() : "not xmm register: " + reg;
+                    break;
+                }
+
+                default: {
+                    throw GraalInternalError.shouldNotReachHere();
+                }
+            }
+        }
+        return true;
+    }
+
+    static CiStackSlot canonicalSpillOpr(Interval interval) {
+        assert interval.spillSlot() != null : "canonical spill slot not set";
+        return interval.spillSlot();
+    }
+
+    /**
+     * Assigns the allocated location for an LIR instruction operand back into the instruction.
+     *
+     * @param operand an LIR instruction operand
+     * @param opId the id of the LIR instruction using {@code operand}
+     * @param mode the usage mode for {@code operand} by the instruction
+     * @return the location assigned for the operand
+     */
+    private CiValue colorLirOperand(Variable operand, int opId, OperandMode mode) {
+        Interval interval = intervalFor(operand);
+        assert interval != null : "interval must exist";
+
+        if (opId != -1) {
+            if (GraalOptions.DetailedAsserts) {
+                Block block = blockForId(opId);
+                if (block.numberOfSux() <= 1 && opId == block.getLastLirInstructionId()) {
+                    // check if spill moves could have been appended at the end of this block, but
+                    // before the branch instruction. So the split child information for this branch would
+                    // be incorrect.
+                    LIRInstruction instr = block.lir.get(block.lir.size() - 1);
+                    if (instr instanceof StandardOp.JumpOp) {
+                        if (blockData.get(block).liveOut.get(operandNumber(operand))) {
+                            assert false : "can't get split child for the last branch of a block because the information would be incorrect (moves are inserted before the branch in resolveDataFlow)";
+                        }
+                    }
+                }
+            }
+
+            // operands are not changed when an interval is split during allocation,
+            // so search the right interval here
+            interval = splitChildAtOpId(interval, opId, mode);
+        }
+
+        return interval.location();
+    }
+
+    IntervalWalker initComputeOopMaps() {
+        // setup lists of potential oops for walking
+        Interval oopIntervals;
+        Interval nonOopIntervals;
+
+        oopIntervals = createUnhandledLists(IS_OOP_INTERVAL, null).first;
+
+        // intervals that have no oops inside need not to be processed.
+        // to ensure a walking until the last instruction id, add a dummy interval
+        // with a high operation id
+        nonOopIntervals = new Interval(CiValue.IllegalValue, -1);
+        nonOopIntervals.addRange(Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 1);
+
+        return new IntervalWalker(this, oopIntervals, nonOopIntervals);
+    }
+
+    void computeOopMap(IntervalWalker iw, LIRInstruction op, CiBitMap registerRefMap, CiBitMap frameRefMap) {
+        if (GraalOptions.TraceLinearScanLevel >= 3) {
+            TTY.println("creating oop map at opId %d", op.id());
+        }
+
+        // walk before the current operation . intervals that start at
+        // the operation (i.e. output operands of the operation) are not
+        // included in the oop map
+        iw.walkBefore(op.id());
+
+        // Iterate through active intervals
+        for (Interval interval = iw.activeLists.get(RegisterBinding.Fixed); interval != Interval.EndMarker; interval = interval.next) {
+            CiValue operand = interval.operand;
+
+            assert interval.currentFrom() <= op.id() && op.id() <= interval.currentTo() : "interval should not be active otherwise";
+            assert isVariable(interval.operand) : "fixed interval found";
+
+            // Check if this range covers the instruction. Intervals that
+            // start or end at the current operation are not included in the
+            // oop map, except in the case of patching moves. For patching
+            // moves, any intervals which end at this instruction are included
+            // in the oop map since we may safepoint while doing the patch
+            // before we've consumed the inputs.
+            if (op.id() < interval.currentTo()) {
+                // caller-save registers must not be included into oop-maps at calls
+                assert !op.hasCall() || !isRegister(operand) || !isCallerSave(operand) : "interval is in a caller-save register at a call . register will be overwritten";
+
+                frameMap.setReference(interval.location(), registerRefMap, frameRefMap);
+
+                // Spill optimization: when the stack value is guaranteed to be always correct,
+                // then it must be added to the oop map even if the interval is currently in a register
+                if (interval.alwaysInMemory() && op.id() > interval.spillDefinitionPos() && !interval.location().equals(interval.spillSlot())) {
+                    assert interval.spillDefinitionPos() > 0 : "position not set correctly";
+                    assert interval.spillSlot() != null : "no spill slot assigned";
+                    assert !isRegister(interval.operand) : "interval is on stack :  so stack slot is registered twice";
+                    frameMap.setReference(interval.spillSlot(), registerRefMap, frameRefMap);
+                }
+            }
+        }
+    }
+
+    private boolean isCallerSave(CiValue operand) {
+        return attributes(asRegister(operand)).isCallerSave;
+    }
+
+
+    private void computeDebugInfo(IntervalWalker iw, LIRInstruction op) {
+        assert iw != null : "interval walker needed for debug information";
+        computeDebugInfo(iw, op, op.info);
+
+        if (op instanceof LIRXirInstruction) {
+            LIRXirInstruction xir = (LIRXirInstruction) op;
+            if (xir.infoAfter != null) {
+                computeDebugInfo(iw, op, xir.infoAfter);
+            }
+        }
+    }
+
+
+    private void computeDebugInfo(IntervalWalker iw, final LIRInstruction op, LIRDebugInfo info) {
+        CiBitMap registerRefMap = op.hasCall() ? null : frameMap.initRegisterRefMap();
+        CiBitMap frameRefMap = frameMap.initFrameRefMap();
+        computeOopMap(iw, op, registerRefMap, frameRefMap);
+
+        info.forEachState(new ValueProcedure() {
+            @Override
+            public CiValue doValue(CiValue operand) {
+                int tempOpId = op.id();
+                OperandMode mode = OperandMode.Input;
+                Block block = blockForId(tempOpId);
+                if (block.numberOfSux() == 1 && tempOpId == block.getLastLirInstructionId()) {
+                    // generating debug information for the last instruction of a block.
+                    // if this instruction is a branch, spill moves are inserted before this branch
+                    // and so the wrong operand would be returned (spill moves at block boundaries are not
+                    // considered in the live ranges of intervals)
+                    // Solution: use the first opId of the branch target block instead.
+                    final LIRInstruction instr = block.lir.get(block.lir.size() - 1);
+                    if (instr instanceof StandardOp.JumpOp) {
+                        if (blockData.get(block).liveOut.get(operandNumber(operand))) {
+                            tempOpId = block.suxAt(0).getFirstLirInstructionId();
+                            mode = OperandMode.Output;
+                        }
+                    }
+                }
+
+                // Get current location of operand
+                // The operand must be live because debug information is considered when building the intervals
+                // if the interval is not live, colorLirOperand will cause an assert on failure
+                CiValue result = colorLirOperand((Variable) operand, tempOpId, mode);
+                assert !hasCall(tempOpId) || isStackSlot(result) || !isCallerSave(result) : "cannot have caller-save register operands at calls";
+                return result;
+            }
+        });
+
+        info.finish(registerRefMap, frameRefMap, frameMap);
+    }
+
+    private void assignLocations(List<LIRInstruction> instructions, IntervalWalker iw) {
+        int numInst = instructions.size();
+        boolean hasDead = false;
+
+        for (int j = 0; j < numInst; j++) {
+            final LIRInstruction op = instructions.get(j);
+            if (op == null) { // this can happen when spill-moves are removed in eliminateSpillMoves
+                hasDead = true;
+                continue;
+            }
+
+            ValueProcedure assignProc = new ValueProcedure() {
+                @Override
+                public CiValue doValue(CiValue operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                    if (isVariable(operand)) {
+                        return colorLirOperand((Variable) operand, op.id(), mode);
+                    }
+                    return operand;
+                }
+            };
+
+            op.forEachInput(assignProc);
+            op.forEachAlive(assignProc);
+            op.forEachTemp(assignProc);
+            op.forEachOutput(assignProc);
+
+            if (op.info != null) {
+                // compute reference map and debug information
+                computeDebugInfo(iw, op);
+            }
+
+            // remove useless moves
+            if (op instanceof MoveOp) {
+                MoveOp move = (MoveOp) op;
+                if (move.getInput() == move.getResult()) {
+                    instructions.set(j, null);
+                    hasDead = true;
+                }
+            }
+        }
+
+        if (hasDead) {
+            // iterate all instructions of the block and remove all null-values.
+            int insertPoint = 0;
+            for (int j = 0; j < numInst; j++) {
+                LIRInstruction op = instructions.get(j);
+                if (op != null) {
+                    if (insertPoint != j) {
+                        instructions.set(insertPoint, op);
+                    }
+                    insertPoint++;
+                }
+            }
+            Util.truncate(instructions, insertPoint);
+        }
+    }
+
+    private void assignLocations() {
+        IntervalWalker iw = initComputeOopMaps();
+        for (Block block : sortedBlocks) {
+            assignLocations(block.lir, iw);
+        }
+    }
+
+    public void allocate() {
+
+        Debug.scope("LifetimeAnalysis", new Runnable() {
+
+            public void run() {
+                numberInstructions();
+                printLir("Before register allocation", true);
+                computeLocalLiveSets();
+                computeGlobalLiveSets();
+                buildIntervals();
+                sortIntervalsBeforeAllocation();
+            }
+        });
+
+        Debug.scope("RegisterAllocation", new Runnable() {
+
+            public void run() {
+                printIntervals("Before register allocation");
+                allocateRegisters();
+            }
+        });
+
+        Debug.scope("ResolveDataFlow", new Runnable() {
+            public void run() {
+                resolveDataFlow();
+            }
+        });
+
+        Debug.scope("DebugInfo", new Runnable() {
+
+            public void run() {
+                frameMap.finish();
+
+                printIntervals("After register allocation");
+                printLir("After register allocation", true);
+
+                sortIntervalsAfterAllocation();
+
+                if (GraalOptions.DetailedAsserts) {
+                    verify();
+                }
+
+                eliminateSpillMoves();
+                assignLocations();
+
+                if (GraalOptions.DetailedAsserts) {
+                    verifyIntervals();
+                }
+            }
+        });
+
+        Debug.scope("ControlFlowOptimizations", new Runnable() {
+
+            public void run() {
+                printLir("After register number assignment", true);
+                EdgeMoveOptimizer.optimize(ir.linearScanOrder());
+                ControlFlowOptimizer.optimize(ir);
+                printLir("After control flow optimization", false);
+            }
+        });
+    }
+
+    void printIntervals(String label) {
+        if (GraalOptions.TraceLinearScanLevel >= 1) {
+            int i;
+            TTY.println();
+            TTY.println(label);
+
+            for (Interval interval : intervals) {
+                if (interval != null) {
+                    TTY.out().println(interval.logString(this));
+                }
+            }
+
+            TTY.println();
+            TTY.println("--- Basic Blocks ---");
+            for (i = 0; i < blockCount(); i++) {
+                Block block = blockAt(i);
+                TTY.print("B%d [%d, %d, %s] ", block.getId(), block.getFirstLirInstructionId(), block.getLastLirInstructionId(), block.getLoop());
+            }
+            TTY.println();
+            TTY.println();
+        }
+
+        Debug.dump(Arrays.copyOf(intervals, intervalsSize), label);
+    }
+
+    void printLir(String label, @SuppressWarnings("unused") boolean hirValid) {
+        Debug.dump(ir, label);
+    }
+
+    boolean verify() {
+        // (check that all intervals have a correct register and that no registers are overwritten)
+        if (GraalOptions.TraceLinearScanLevel >= 2) {
+            TTY.println(" verifying intervals *");
+        }
+        verifyIntervals();
+
+        if (GraalOptions.TraceLinearScanLevel >= 2) {
+            TTY.println(" verifying that no oops are in fixed intervals *");
+        }
+        //verifyNoOopsInFixedIntervals();
+
+        if (GraalOptions.TraceLinearScanLevel >= 2) {
+            TTY.println(" verifying that unpinned constants are not alive across block boundaries");
+        }
+        verifyConstants();
+
+        if (GraalOptions.TraceLinearScanLevel >= 2) {
+            TTY.println(" verifying register allocation *");
+        }
+        verifyRegisters();
+
+        if (GraalOptions.TraceLinearScanLevel >= 2) {
+            TTY.println(" no errors found *");
+        }
+
+        return true;
+    }
+
+    private void verifyRegisters() {
+        RegisterVerifier verifier = new RegisterVerifier(this);
+        verifier.verify(blockAt(0));
+    }
+
+    void verifyIntervals() {
+        int len = intervalsSize;
+
+        for (int i = 0; i < len; i++) {
+            Interval i1 = intervals[i];
+            if (i1 == null) {
+                continue;
+            }
+
+            i1.checkSplitChildren();
+
+            if (i1.operandNumber != i) {
+                TTY.println("Interval %d is on position %d in list", i1.operandNumber, i);
+                TTY.println(i1.logString(this));
+                throw new GraalInternalError("");
+            }
+
+            if (isVariable(i1.operand) && i1.kind()  == CiKind.Illegal) {
+                TTY.println("Interval %d has no type assigned", i1.operandNumber);
+                TTY.println(i1.logString(this));
+                throw new GraalInternalError("");
+            }
+
+            if (i1.location() == null) {
+                TTY.println("Interval %d has no register assigned", i1.operandNumber);
+                TTY.println(i1.logString(this));
+                throw new GraalInternalError("");
+            }
+
+            if (!isProcessed(i1.location())) {
+                TTY.println("Can not have an Interval for an ignored register " + i1.location());
+                TTY.println(i1.logString(this));
+                throw new GraalInternalError("");
+            }
+
+            if (i1.first() == Range.EndMarker) {
+                TTY.println("Interval %d has no Range", i1.operandNumber);
+                TTY.println(i1.logString(this));
+                throw new GraalInternalError("");
+            }
+
+            for (Range r = i1.first(); r != Range.EndMarker; r = r.next) {
+                if (r.from >= r.to) {
+                    TTY.println("Interval %d has zero length range", i1.operandNumber);
+                    TTY.println(i1.logString(this));
+                    throw new GraalInternalError("");
+                }
+            }
+
+            for (int j = i + 1; j < len; j++) {
+                Interval i2 = intervals[j];
+                if (i2 == null) {
+                    continue;
+                }
+
+                // special intervals that are created in MoveResolver
+                // . ignore them because the range information has no meaning there
+                if (i1.from() == 1 && i1.to() == 2) {
+                    continue;
+                }
+                if (i2.from() == 1 && i2.to() == 2) {
+                    continue;
+                }
+                CiValue l1 = i1.location();
+                CiValue l2 = i2.location();
+                if (i1.intersects(i2) && (l1.equals(l2))) {
+                    if (GraalOptions.DetailedAsserts) {
+                        TTY.println("Intervals %d and %d overlap and have the same register assigned", i1.operandNumber, i2.operandNumber);
+                        TTY.println(i1.logString(this));
+                        TTY.println(i2.logString(this));
+                    }
+                    throw new CiBailout("");
+                }
+            }
+        }
+    }
+
+    class CheckProcedure extends ValueProcedure {
+        boolean ok;
+        Interval curInterval;
+
+        @Override
+        protected CiValue doValue(CiValue operand) {
+            if (isRegister(operand)) {
+                if (intervalFor(operand) == curInterval) {
+                    ok = true;
+                }
+            }
+            return operand;
+        }
+    }
+
+    void verifyNoOopsInFixedIntervals() {
+        CheckProcedure checkProc = new CheckProcedure();
+
+        Interval fixedIntervals;
+        Interval otherIntervals;
+        fixedIntervals = createUnhandledLists(IS_PRECOLORED_INTERVAL, null).first;
+        // to ensure a walking until the last instruction id, add a dummy interval
+        // with a high operation id
+        otherIntervals = new Interval(CiValue.IllegalValue, -1);
+        otherIntervals.addRange(Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 1);
+        IntervalWalker iw = new IntervalWalker(this, fixedIntervals, otherIntervals);
+
+        for (int i = 0; i < blockCount(); i++) {
+            Block block = blockAt(i);
+
+            List<LIRInstruction> instructions = block.lir;
+
+            for (int j = 0; j < instructions.size(); j++) {
+                LIRInstruction op = instructions.get(j);
+
+                if (op.info != null) {
+                    iw.walkBefore(op.id());
+                    boolean checkLive = true;
+
+                    // Make sure none of the fixed registers is live across an
+                    // oopmap since we can't handle that correctly.
+                    if (checkLive) {
+                        for (Interval interval = iw.activeLists.get(RegisterBinding.Fixed); interval != Interval.EndMarker; interval = interval.next) {
+                            if (interval.currentTo() > op.id() + 1) {
+                                // This interval is live out of this op so make sure
+                                // that this interval represents some value that's
+                                // referenced by this op either as an input or output.
+                                checkProc.curInterval = interval;
+                                checkProc.ok = false;
+
+                                op.forEachInput(checkProc);
+                                op.forEachAlive(checkProc);
+                                op.forEachTemp(checkProc);
+                                op.forEachOutput(checkProc);
+
+                                assert checkProc.ok : "fixed intervals should never be live across an oopmap point";
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    void verifyConstants() {
+        int numBlocks = blockCount();
+
+        for (int i = 0; i < numBlocks; i++) {
+            Block block = blockAt(i);
+            BitMap liveAtEdge = blockData.get(block).liveIn;
+
+            // visit all operands where the liveAtEdge bit is set
+            for (int operandNum = liveAtEdge.nextSetBit(0); operandNum >= 0; operandNum = liveAtEdge.nextSetBit(operandNum + 1)) {
+                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                    TTY.println("checking interval %d of block B%d", operandNum, block.getId());
+                }
+                CiValue operand = operandFor(operandNum);
+                assert isVariable(operand) : "value must have variable operand";
+                // TKR assert value.asConstant() == null || value.isPinned() :
+                // "only pinned constants can be alive accross block boundaries";
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScanWalker.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,963 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.compiler.alloc;
+
+import static com.oracle.max.cri.ci.CiUtil.*;
+import static com.oracle.max.graal.alloc.util.LocationUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiRegister.RegisterFlag;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.alloc.Interval.RegisterBinding;
+import com.oracle.max.graal.compiler.alloc.Interval.RegisterPriority;
+import com.oracle.max.graal.compiler.alloc.Interval.SpillState;
+import com.oracle.max.graal.compiler.alloc.Interval.State;
+import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.StandardOp.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+/**
+ */
+final class LinearScanWalker extends IntervalWalker {
+
+    private final boolean hasCalleeSavedRegisters;
+
+    private CiRegister[] availableRegs;
+
+    private final int[] usePos;
+    private final int[] blockPos;
+
+    private List<Interval>[] spillIntervals;
+
+    private MoveResolver moveResolver; // for ordering spill moves
+
+
+    // accessors mapped to same functions in class LinearScan
+    int blockCount() {
+        return allocator.blockCount();
+    }
+
+    Block blockAt(int idx) {
+        return allocator.blockAt(idx);
+    }
+
+    Block blockOfOpWithId(int opId) {
+        return allocator.blockForId(opId);
+    }
+
+    LinearScanWalker(LinearScan allocator, Interval unhandledFixedFirst, Interval unhandledAnyFirst, boolean hasCalleeSavedRegisters) {
+        super(allocator, unhandledFixedFirst, unhandledAnyFirst);
+        this.hasCalleeSavedRegisters = hasCalleeSavedRegisters;
+        moveResolver = new MoveResolver(allocator);
+        spillIntervals = Util.uncheckedCast(new List[allocator.registers.length]);
+        for (int i = 0; i < allocator.registers.length; i++) {
+            spillIntervals[i] = new ArrayList<>(2);
+        }
+        usePos = new int[allocator.registers.length];
+        blockPos = new int[allocator.registers.length];
+    }
+
+    void initUseLists(boolean onlyProcessUsePos) {
+        for (CiRegister register : availableRegs) {
+            int i = register.number;
+            usePos[i] = Integer.MAX_VALUE;
+
+            if (!onlyProcessUsePos) {
+                blockPos[i] = Integer.MAX_VALUE;
+                spillIntervals[i].clear();
+            }
+        }
+    }
+
+    void excludeFromUse(Interval i) {
+        CiValue location = i.location();
+        int i1 = asRegister(location).number;
+        if (i1 >= availableRegs[0].number && i1 <= availableRegs[availableRegs.length - 1].number) {
+            usePos[i1] = 0;
+        }
+    }
+
+    void setUsePos(Interval interval, int usePos, boolean onlyProcessUsePos) {
+        if (usePos != -1) {
+            assert usePos != 0 : "must use excludeFromUse to set usePos to 0";
+            int i = asRegister(interval.location()).number;
+            if (i >= availableRegs[0].number && i <= availableRegs[availableRegs.length - 1].number) {
+                if (this.usePos[i] > usePos) {
+                    this.usePos[i] = usePos;
+                }
+                if (!onlyProcessUsePos) {
+                    spillIntervals[i].add(interval);
+                }
+            }
+        }
+    }
+
+    void setBlockPos(Interval i, int blockPos) {
+        if (blockPos != -1) {
+            int reg = asRegister(i.location()).number;
+            if (reg >= availableRegs[0].number && reg <= availableRegs[availableRegs.length - 1].number) {
+                if (this.blockPos[reg] > blockPos) {
+                    this.blockPos[reg] = blockPos;
+                }
+                if (usePos[reg] > blockPos) {
+                    usePos[reg] = blockPos;
+                }
+            }
+        }
+    }
+
+    void freeExcludeActiveFixed() {
+        Interval interval = activeLists.get(RegisterBinding.Fixed);
+        while (interval != Interval.EndMarker) {
+            assert isRegister(interval.location()) : "active interval must have a register assigned";
+            excludeFromUse(interval);
+            interval = interval.next;
+        }
+    }
+
+    void freeExcludeActiveAny() {
+        Interval interval = activeLists.get(RegisterBinding.Any);
+        while (interval != Interval.EndMarker) {
+            assert isRegister(interval.location()) : "active interval must have a register assigned";
+            excludeFromUse(interval);
+            interval = interval.next;
+        }
+    }
+
+    void freeCollectInactiveFixed(Interval current) {
+        Interval interval = inactiveLists.get(RegisterBinding.Fixed);
+        while (interval != Interval.EndMarker) {
+            if (current.to() <= interval.currentFrom()) {
+                assert interval.currentIntersectsAt(current) == -1 : "must not intersect";
+                setUsePos(interval, interval.currentFrom(), true);
+            } else {
+                setUsePos(interval, interval.currentIntersectsAt(current), true);
+            }
+            interval = interval.next;
+        }
+    }
+
+    void freeCollectInactiveAny(Interval current) {
+        Interval interval = inactiveLists.get(RegisterBinding.Any);
+        while (interval != Interval.EndMarker) {
+            setUsePos(interval, interval.currentIntersectsAt(current), true);
+            interval = interval.next;
+        }
+    }
+
+    void freeCollectUnhandled(RegisterBinding kind, Interval current) {
+        Interval interval = unhandledLists.get(kind);
+        while (interval != Interval.EndMarker) {
+            setUsePos(interval, interval.intersectsAt(current), true);
+            if (kind == RegisterBinding.Fixed && current.to() <= interval.from()) {
+                setUsePos(interval, interval.from(), true);
+            }
+            interval = interval.next;
+        }
+    }
+
+    void spillExcludeActiveFixed() {
+        Interval interval = activeLists.get(RegisterBinding.Fixed);
+        while (interval != Interval.EndMarker) {
+            excludeFromUse(interval);
+            interval = interval.next;
+        }
+    }
+
+    void spillBlockUnhandledFixed(Interval current) {
+        Interval interval = unhandledLists.get(RegisterBinding.Fixed);
+        while (interval != Interval.EndMarker) {
+            setBlockPos(interval, interval.intersectsAt(current));
+            interval = interval.next;
+        }
+    }
+
+    void spillBlockInactiveFixed(Interval current) {
+        Interval interval = inactiveLists.get(RegisterBinding.Fixed);
+        while (interval != Interval.EndMarker) {
+            if (current.to() > interval.currentFrom()) {
+                setBlockPos(interval, interval.currentIntersectsAt(current));
+            } else {
+                assert interval.currentIntersectsAt(current) == -1 : "invalid optimization: intervals intersect";
+            }
+
+            interval = interval.next;
+        }
+    }
+
+    void spillCollectActiveAny() {
+        Interval interval = activeLists.get(RegisterBinding.Any);
+        while (interval != Interval.EndMarker) {
+            setUsePos(interval, Math.min(interval.nextUsage(RegisterPriority.LiveAtLoopEnd, currentPosition), interval.to()), false);
+            interval = interval.next;
+        }
+    }
+
+    void spillCollectInactiveAny(Interval current) {
+        Interval interval = inactiveLists.get(RegisterBinding.Any);
+        while (interval != Interval.EndMarker) {
+            if (interval.currentIntersects(current)) {
+                setUsePos(interval, Math.min(interval.nextUsage(RegisterPriority.LiveAtLoopEnd, currentPosition), interval.to()), false);
+            }
+            interval = interval.next;
+        }
+    }
+
+    void insertMove(int operandId, Interval srcIt, Interval dstIt) {
+        // output all moves here. When source and target are equal, the move is
+        // optimized away later in assignRegNums
+
+        int opId = (operandId + 1) & ~1;
+        Block opBlock = allocator.blockForId(opId);
+        assert opId > 0 && allocator.blockForId(opId - 2) == opBlock : "cannot insert move at block boundary";
+
+        // calculate index of instruction inside instruction list of current block
+        // the minimal index (for a block with no spill moves) can be calculated because the
+        // numbering of instructions is known.
+        // When the block already contains spill moves, the index must be increased until the
+        // correct index is reached.
+        List<LIRInstruction> list = opBlock.lir;
+        int index = (opId - list.get(0).id()) >> 1;
+        assert list.get(index).id() <= opId : "error in calculation";
+
+        while (list.get(index).id() != opId) {
+            index++;
+            assert 0 <= index && index < list.size() : "index out of bounds";
+        }
+        assert 1 <= index && index < list.size() : "index out of bounds";
+        assert list.get(index).id() == opId : "error in calculation";
+
+        // insert new instruction before instruction at position index
+        moveResolver.moveInsertPosition(opBlock.lir, index);
+        moveResolver.addMapping(srcIt, dstIt);
+    }
+
+    int findOptimalSplitPos(Block minBlock, Block maxBlock, int maxSplitPos) {
+        int fromBlockNr = minBlock.linearScanNumber;
+        int toBlockNr = maxBlock.linearScanNumber;
+
+        assert 0 <= fromBlockNr && fromBlockNr < blockCount() : "out of range";
+        assert 0 <= toBlockNr && toBlockNr < blockCount() : "out of range";
+        assert fromBlockNr < toBlockNr : "must cross block boundary";
+
+        // Try to split at end of maxBlock. If this would be after
+        // maxSplitPos, then use the begin of maxBlock
+        int optimalSplitPos = maxBlock.getLastLirInstructionId() + 2;
+        if (optimalSplitPos > maxSplitPos) {
+            optimalSplitPos = maxBlock.getFirstLirInstructionId();
+        }
+
+        int minLoopDepth = maxBlock.getLoopDepth();
+        for (int i = toBlockNr - 1; i >= fromBlockNr; i--) {
+            Block cur = blockAt(i);
+
+            if (cur.getLoopDepth() < minLoopDepth) {
+                // block with lower loop-depth found . split at the end of this block
+                minLoopDepth = cur.getLoopDepth();
+                optimalSplitPos = cur.getLastLirInstructionId() + 2;
+            }
+        }
+        assert optimalSplitPos > allocator.maxOpId() || allocator.isBlockBegin(optimalSplitPos) : "algorithm must move split pos to block boundary";
+
+        return optimalSplitPos;
+    }
+
+    int findOptimalSplitPos(Interval interval, int minSplitPos, int maxSplitPos, boolean doLoopOptimization) {
+        int optimalSplitPos = -1;
+        if (minSplitPos == maxSplitPos) {
+            // trivial case, no optimization of split position possible
+            if (GraalOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("      min-pos and max-pos are equal, no optimization possible");
+            }
+            optimalSplitPos = minSplitPos;
+
+        } else {
+            assert minSplitPos < maxSplitPos : "must be true then";
+            assert minSplitPos > 0 : "cannot access minSplitPos - 1 otherwise";
+
+            // reason for using minSplitPos - 1: when the minimal split pos is exactly at the
+            // beginning of a block, then minSplitPos is also a possible split position.
+            // Use the block before as minBlock, because then minBlock.lastLirInstructionId() + 2 == minSplitPos
+            Block minBlock = allocator.blockForId(minSplitPos - 1);
+
+            // reason for using maxSplitPos - 1: otherwise there would be an assert on failure
+            // when an interval ends at the end of the last block of the method
+            // (in this case, maxSplitPos == allocator().maxLirOpId() + 2, and there is no
+            // block at this opId)
+            Block maxBlock = allocator.blockForId(maxSplitPos - 1);
+
+            assert minBlock.linearScanNumber <= maxBlock.linearScanNumber : "invalid order";
+            if (minBlock == maxBlock) {
+                // split position cannot be moved to block boundary : so split as late as possible
+                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                    TTY.println("      cannot move split pos to block boundary because minPos and maxPos are in same block");
+                }
+                optimalSplitPos = maxSplitPos;
+
+            } else {
+                if (interval.hasHoleBetween(maxSplitPos - 1, maxSplitPos) && !allocator.isBlockBegin(maxSplitPos)) {
+                    // Do not move split position if the interval has a hole before maxSplitPos.
+                    // Intervals resulting from Phi-Functions have more than one definition (marked
+                    // as mustHaveRegister) with a hole before each definition. When the register is needed
+                    // for the second definition : an earlier reloading is unnecessary.
+                    if (GraalOptions.TraceLinearScanLevel >= 4) {
+                        TTY.println("      interval has hole just before maxSplitPos, so splitting at maxSplitPos");
+                    }
+                    optimalSplitPos = maxSplitPos;
+
+                } else {
+                    // seach optimal block boundary between minSplitPos and maxSplitPos
+                    if (GraalOptions.TraceLinearScanLevel >= 4) {
+                        TTY.println("      moving split pos to optimal block boundary between block B%d and B%d", minBlock.getId(), maxBlock.getId());
+                    }
+
+                    if (doLoopOptimization) {
+                        // Loop optimization: if a loop-end marker is found between min- and max-position :
+                        // then split before this loop
+                        int loopEndPos = interval.nextUsageExact(RegisterPriority.LiveAtLoopEnd, minBlock.getLastLirInstructionId() + 2);
+                        if (GraalOptions.TraceLinearScanLevel >= 4) {
+                            TTY.println("      loop optimization: loop end found at pos %d", loopEndPos);
+                        }
+
+                        assert loopEndPos > minSplitPos : "invalid order";
+                        if (loopEndPos < maxSplitPos) {
+                            // loop-end marker found between min- and max-position
+                            // if it is not the end marker for the same loop as the min-position : then move
+                            // the max-position to this loop block.
+                            // Desired result: uses tagged as shouldHaveRegister inside a loop cause a reloading
+                            // of the interval (normally, only mustHaveRegister causes a reloading)
+                            Block loopBlock = allocator.blockForId(loopEndPos);
+
+                            if (GraalOptions.TraceLinearScanLevel >= 4) {
+                                TTY.println("      interval is used in loop that ends in block B%d, so trying to move maxBlock back from B%d to B%d", loopBlock.getId(), maxBlock.getId(), loopBlock.getId());
+                            }
+                            assert loopBlock != minBlock : "loopBlock and minBlock must be different because block boundary is needed between";
+
+                            optimalSplitPos = findOptimalSplitPos(minBlock, loopBlock, loopBlock.getLastLirInstructionId() + 2);
+                            if (optimalSplitPos == loopBlock.getLastLirInstructionId() + 2) {
+                                optimalSplitPos = -1;
+                                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                                    TTY.println("      loop optimization not necessary");
+                                }
+                            } else {
+                                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                                    TTY.println("      loop optimization successful");
+                                }
+                            }
+                        }
+                    }
+
+                    if (optimalSplitPos == -1) {
+                        // not calculated by loop optimization
+                        optimalSplitPos = findOptimalSplitPos(minBlock, maxBlock, maxSplitPos);
+                    }
+                }
+            }
+        }
+        if (GraalOptions.TraceLinearScanLevel >= 4) {
+            TTY.println("      optimal split position: %d", optimalSplitPos);
+        }
+
+        return optimalSplitPos;
+    }
+
+    // split an interval at the optimal position between minSplitPos and
+    // maxSplitPos in two parts:
+    // 1) the left part has already a location assigned
+    // 2) the right part is sorted into to the unhandled-list
+    void splitBeforeUsage(Interval interval, int minSplitPos, int maxSplitPos) {
+        if (GraalOptions.TraceLinearScanLevel >= 2) {
+            TTY.println("----- splitting interval: ");
+        }
+        if (GraalOptions.TraceLinearScanLevel >= 4) {
+            TTY.println(interval.logString(allocator));
+        }
+        if (GraalOptions.TraceLinearScanLevel >= 2) {
+            TTY.println("      between %d and %d", minSplitPos, maxSplitPos);
+        }
+
+        assert interval.from() < minSplitPos : "cannot split at start of interval";
+        assert currentPosition < minSplitPos : "cannot split before current position";
+        assert minSplitPos <= maxSplitPos : "invalid order";
+        assert maxSplitPos <= interval.to() : "cannot split after end of interval";
+
+        int optimalSplitPos = findOptimalSplitPos(interval, minSplitPos, maxSplitPos, true);
+
+        assert minSplitPos <= optimalSplitPos && optimalSplitPos <= maxSplitPos : "out of range";
+        assert optimalSplitPos <= interval.to() : "cannot split after end of interval";
+        assert optimalSplitPos > interval.from() : "cannot split at start of interval";
+
+        if (optimalSplitPos == interval.to() && interval.nextUsage(RegisterPriority.MustHaveRegister, minSplitPos) == Integer.MAX_VALUE) {
+            // the split position would be just before the end of the interval
+            // . no split at all necessary
+            if (GraalOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("      no split necessary because optimal split position is at end of interval");
+            }
+            return;
+        }
+
+        // must calculate this before the actual split is performed and before split position is moved to odd opId
+        boolean moveNecessary = !allocator.isBlockBegin(optimalSplitPos) && !interval.hasHoleBetween(optimalSplitPos - 1, optimalSplitPos);
+
+        if (!allocator.isBlockBegin(optimalSplitPos)) {
+            // move position before actual instruction (odd opId)
+            optimalSplitPos = (optimalSplitPos - 1) | 1;
+        }
+
+        if (GraalOptions.TraceLinearScanLevel >= 4) {
+            TTY.println("      splitting at position %d", optimalSplitPos);
+        }
+        assert allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 1) : "split pos must be odd when not on block boundary";
+        assert !allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 0) : "split pos must be even on block boundary";
+
+        Interval splitPart = interval.split(optimalSplitPos, allocator);
+
+        splitPart.setInsertMoveWhenActivated(moveNecessary);
+
+        assert splitPart.from() >= currentInterval.currentFrom() : "cannot append new interval before current walk position";
+        unhandledLists.addToListSortedByStartAndUsePositions(RegisterBinding.Any, splitPart);
+
+        if (GraalOptions.TraceLinearScanLevel >= 2) {
+            TTY.println("      split interval in two parts (insertMoveWhenActivated: %b)", moveNecessary);
+        }
+        if (GraalOptions.TraceLinearScanLevel >= 2) {
+            TTY.print("      ");
+            TTY.println(interval.logString(allocator));
+            TTY.print("      ");
+            TTY.println(splitPart.logString(allocator));
+        }
+    }
+
+// split an interval at the optimal position between minSplitPos and
+// maxSplitPos in two parts:
+// 1) the left part has already a location assigned
+// 2) the right part is always on the stack and therefore ignored in further processing
+
+    void splitForSpilling(Interval interval) {
+        // calculate allowed range of splitting position
+        int maxSplitPos = currentPosition;
+        int minSplitPos = Math.max(interval.previousUsage(RegisterPriority.ShouldHaveRegister, maxSplitPos) + 1, interval.from());
+
+        if (GraalOptions.TraceLinearScanLevel >= 2) {
+            TTY.print("----- splitting and spilling interval: ");
+            TTY.println(interval.logString(allocator));
+            TTY.println("      between %d and %d", minSplitPos, maxSplitPos);
+        }
+
+        assert interval.state == State.Active : "why spill interval that is not active?";
+        assert interval.from() <= minSplitPos : "cannot split before start of interval";
+        assert minSplitPos <= maxSplitPos : "invalid order";
+        assert maxSplitPos < interval.to() : "cannot split at end end of interval";
+        assert currentPosition < interval.to() : "interval must not end before current position";
+
+        if (minSplitPos == interval.from()) {
+            // the whole interval is never used, so spill it entirely to memory
+            if (GraalOptions.TraceLinearScanLevel >= 2) {
+                TTY.println("      spilling entire interval because split pos is at beginning of interval");
+                TTY.println("      use positions: " + interval.usePosList().size());
+            }
+            assert interval.firstUsage(RegisterPriority.ShouldHaveRegister) > currentPosition : "interval must not have use position before currentPosition";
+
+            allocator.assignSpillSlot(interval);
+            allocator.changeSpillState(interval, minSplitPos);
+
+            // Also kick parent intervals out of register to memory when they have no use
+            // position. This avoids short interval in register surrounded by intervals in
+            // memory . avoid useless moves from memory to register and back
+            Interval parent = interval;
+            while (parent != null && parent.isSplitChild()) {
+                parent = parent.getSplitChildBeforeOpId(parent.from());
+
+                if (isRegister(parent.location())) {
+                    if (parent.firstUsage(RegisterPriority.ShouldHaveRegister) == Integer.MAX_VALUE) {
+                        // parent is never used, so kick it out of its assigned register
+                        if (GraalOptions.TraceLinearScanLevel >= 4) {
+                            TTY.println("      kicking out interval %d out of its register because it is never used", parent.operandNumber);
+                        }
+                        allocator.assignSpillSlot(parent);
+                    } else {
+                        // do not go further back because the register is actually used by the interval
+                        parent = null;
+                    }
+                }
+            }
+
+        } else {
+            // search optimal split pos, split interval and spill only the right hand part
+            int optimalSplitPos = findOptimalSplitPos(interval, minSplitPos, maxSplitPos, false);
+
+            assert minSplitPos <= optimalSplitPos && optimalSplitPos <= maxSplitPos : "out of range";
+            assert optimalSplitPos < interval.to() : "cannot split at end of interval";
+            assert optimalSplitPos >= interval.from() : "cannot split before start of interval";
+
+            if (!allocator.isBlockBegin(optimalSplitPos)) {
+                // move position before actual instruction (odd opId)
+                optimalSplitPos = (optimalSplitPos - 1) | 1;
+            }
+
+            if (GraalOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("      splitting at position %d", optimalSplitPos);
+            }
+            assert allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 1) : "split pos must be odd when not on block boundary";
+            assert !allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 0) : "split pos must be even on block boundary";
+
+            Interval spilledPart = interval.split(optimalSplitPos, allocator);
+            allocator.assignSpillSlot(spilledPart);
+            allocator.changeSpillState(spilledPart, optimalSplitPos);
+
+            if (!allocator.isBlockBegin(optimalSplitPos)) {
+                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                    TTY.println("      inserting move from interval %d to %d", interval.operandNumber, spilledPart.operandNumber);
+                }
+                insertMove(optimalSplitPos, interval, spilledPart);
+            }
+
+            // the currentSplitChild is needed later when moves are inserted for reloading
+            assert spilledPart.currentSplitChild() == interval : "overwriting wrong currentSplitChild";
+            spilledPart.makeCurrentSplitChild();
+
+            if (GraalOptions.TraceLinearScanLevel >= 2) {
+                TTY.println("      split interval in two parts");
+                TTY.print("      ");
+                TTY.println(interval.logString(allocator));
+                TTY.print("      ");
+                TTY.println(spilledPart.logString(allocator));
+            }
+        }
+    }
+
+    void splitStackInterval(Interval interval) {
+        int minSplitPos = currentPosition + 1;
+        int maxSplitPos = Math.min(interval.firstUsage(RegisterPriority.ShouldHaveRegister), interval.to());
+
+        splitBeforeUsage(interval, minSplitPos, maxSplitPos);
+    }
+
+    void splitWhenPartialRegisterAvailable(Interval interval, int registerAvailableUntil) {
+        int minSplitPos = Math.max(interval.previousUsage(RegisterPriority.ShouldHaveRegister, registerAvailableUntil), interval.from() + 1);
+        splitBeforeUsage(interval, minSplitPos, registerAvailableUntil);
+    }
+
+    void splitAndSpillInterval(Interval interval) {
+        assert interval.state == State.Active || interval.state == State.Inactive : "other states not allowed";
+
+        int currentPos = currentPosition;
+        if (interval.state == State.Inactive) {
+            // the interval is currently inactive, so no spill slot is needed for now.
+            // when the split part is activated, the interval has a new chance to get a register,
+            // so in the best case no stack slot is necessary
+            assert interval.hasHoleBetween(currentPos - 1, currentPos + 1) : "interval can not be inactive otherwise";
+            splitBeforeUsage(interval, currentPos + 1, currentPos + 1);
+
+        } else {
+            // search the position where the interval must have a register and split
+            // at the optimal position before.
+            // The new created part is added to the unhandled list and will get a register
+            // when it is activated
+            int minSplitPos = currentPos + 1;
+            int maxSplitPos = Math.min(interval.nextUsage(RegisterPriority.MustHaveRegister, minSplitPos), interval.to());
+
+            splitBeforeUsage(interval, minSplitPos, maxSplitPos);
+
+            assert interval.nextUsage(RegisterPriority.MustHaveRegister, currentPos) == Integer.MAX_VALUE : "the remaining part is spilled to stack and therefore has no register";
+            splitForSpilling(interval);
+        }
+    }
+
+    boolean allocFreeRegister(Interval interval) {
+        if (GraalOptions.TraceLinearScanLevel >= 2) {
+            TTY.println("trying to find free register for " + interval.logString(allocator));
+        }
+
+        initUseLists(true);
+        freeExcludeActiveFixed();
+        freeExcludeActiveAny();
+        freeCollectInactiveFixed(interval);
+        freeCollectInactiveAny(interval);
+        // freeCollectUnhandled(fixedKind, cur);
+        assert unhandledLists.get(RegisterBinding.Fixed) == Interval.EndMarker : "must not have unhandled fixed intervals because all fixed intervals have a use at position 0";
+
+        // usePos contains the start of the next interval that has this register assigned
+        // (either as a fixed register or a normal allocated register in the past)
+        // only intervals overlapping with cur are processed, non-overlapping invervals can be ignored safely
+        if (GraalOptions.TraceLinearScanLevel >= 4) {
+            TTY.println("      state of registers:");
+            for (CiRegister register : availableRegs) {
+                int i = register.number;
+                TTY.println("      reg %d: usePos: %d", register.number, usePos[i]);
+            }
+        }
+
+        CiRegister hint = null;
+        Interval locationHint = interval.locationHint(true);
+        if (locationHint != null && locationHint.location() != null && isRegister(locationHint.location())) {
+            hint = asRegister(locationHint.location());
+            if (GraalOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("      hint register %d from interval %s", hint.number, locationHint.logString(allocator));
+            }
+        }
+        assert interval.location() == null : "register already assigned to interval";
+
+        // the register must be free at least until this position
+        int regNeededUntil = interval.from() + 1;
+        int intervalTo = interval.to();
+
+        boolean needSplit = false;
+        int splitPos = -1;
+
+        CiRegister reg = null;
+        CiRegister minFullReg = null;
+        CiRegister maxPartialReg = null;
+
+        for (int i = 0; i < availableRegs.length; ++i) {
+            CiRegister availableReg = availableRegs[i];
+            int number = availableReg.number;
+            if (usePos[number] >= intervalTo) {
+                // this register is free for the full interval
+                if (minFullReg == null || availableReg == hint || (usePos[number] < usePos[minFullReg.number] && minFullReg != hint)) {
+                    minFullReg = availableReg;
+                }
+            } else if (usePos[number] > regNeededUntil) {
+                // this register is at least free until regNeededUntil
+                if (maxPartialReg == null || availableReg == hint || (usePos[number] > usePos[maxPartialReg.number] && maxPartialReg != hint)) {
+                    maxPartialReg = availableReg;
+                }
+            }
+        }
+
+        if (minFullReg != null) {
+            reg = minFullReg;
+        } else if (maxPartialReg != null) {
+            needSplit = true;
+            reg = maxPartialReg;
+        } else {
+            return false;
+        }
+
+        splitPos = usePos[reg.number];
+        interval.assignLocation(reg.asValue(interval.kind()));
+        if (GraalOptions.TraceLinearScanLevel >= 2) {
+            TTY.println("selected register %d", reg.number);
+        }
+
+        assert splitPos > 0 : "invalid splitPos";
+        if (needSplit) {
+            // register not available for full interval, so split it
+            splitWhenPartialRegisterAvailable(interval, splitPos);
+        }
+
+        // only return true if interval is completely assigned
+        return true;
+    }
+
+    CiRegister findLockedRegister(int regNeededUntil, int intervalTo, CiValue ignoreReg, boolean[] needSplit) {
+        int maxReg = -1;
+        CiRegister ignore = isRegister(ignoreReg) ? asRegister(ignoreReg) : null;
+
+        for (CiRegister reg : availableRegs) {
+            int i = reg.number;
+            if (reg == ignore) {
+                // this register must be ignored
+
+            } else if (usePos[i] > regNeededUntil) {
+                if (maxReg == -1 || (usePos[i] > usePos[maxReg])) {
+                    maxReg = i;
+                }
+            }
+        }
+
+        if (maxReg != -1) {
+            if (blockPos[maxReg] <= intervalTo) {
+                needSplit[0] = true;
+            }
+            return availableRegs[maxReg];
+        }
+
+        return null;
+    }
+
+    void splitAndSpillIntersectingIntervals(CiRegister reg) {
+        assert reg != null : "no register assigned";
+
+        for (int i = 0; i < spillIntervals[reg.number].size(); i++) {
+            Interval interval = spillIntervals[reg.number].get(i);
+            removeFromList(interval);
+            splitAndSpillInterval(interval);
+        }
+    }
+
+    // Split an Interval and spill it to memory so that cur can be placed in a register
+    void allocLockedRegister(Interval interval) {
+        if (GraalOptions.TraceLinearScanLevel >= 2) {
+            TTY.println("need to split and spill to get register for " + interval.logString(allocator));
+        }
+
+        // collect current usage of registers
+        initUseLists(false);
+        spillExcludeActiveFixed();
+        //  spillBlockUnhandledFixed(cur);
+        assert unhandledLists.get(RegisterBinding.Fixed) == Interval.EndMarker : "must not have unhandled fixed intervals because all fixed intervals have a use at position 0";
+        spillBlockInactiveFixed(interval);
+        spillCollectActiveAny();
+        spillCollectInactiveAny(interval);
+
+        if (GraalOptions.TraceLinearScanLevel >= 4) {
+            TTY.println("      state of registers:");
+            for (CiRegister reg : availableRegs) {
+                int i = reg.number;
+                TTY.print("      reg %d: usePos: %d, blockPos: %d, intervals: ", i, usePos[i], blockPos[i]);
+                for (int j = 0; j < spillIntervals[i].size(); j++) {
+                    TTY.print("%d ", spillIntervals[i].get(j).operandNumber);
+                }
+                TTY.println();
+            }
+        }
+
+        // the register must be free at least until this position
+        int firstUsage = interval.firstUsage(RegisterPriority.MustHaveRegister);
+        int regNeededUntil = Math.min(firstUsage, interval.from() + 1);
+        int intervalTo = interval.to();
+        assert regNeededUntil > 0 && regNeededUntil < Integer.MAX_VALUE : "interval has no use";
+
+        CiRegister reg = null;
+        CiRegister ignore = interval.location() != null && isRegister(interval.location()) ? asRegister(interval.location()) : null;
+        for (CiRegister availableReg : availableRegs) {
+            int number = availableReg.number;
+            if (availableReg == ignore) {
+                // this register must be ignored
+            } else if (usePos[number] > regNeededUntil) {
+                if (reg == null || (usePos[number] > usePos[reg.number])) {
+                    reg = availableReg;
+                }
+            }
+        }
+
+        if (reg == null || usePos[reg.number] <= firstUsage) {
+            // the first use of cur is later than the spilling position -> spill cur
+            if (GraalOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("able to spill current interval. firstUsage(register): %d, usePos: %d", firstUsage, reg == null ? 0 : usePos[reg.number]);
+            }
+
+            if (firstUsage <= interval.from() + 1) {
+                assert false : "cannot spill interval that is used in first instruction (possible reason: no register found) firstUsage=" + firstUsage + ", interval.from()=" + interval.from();
+                // assign a reasonable register and do a bailout in product mode to avoid errors
+                allocator.assignSpillSlot(interval);
+                throw new CiBailout("LinearScan: no register found");
+            }
+
+            splitAndSpillInterval(interval);
+            return;
+        }
+
+        boolean needSplit = blockPos[reg.number] <= intervalTo;
+
+        int splitPos = blockPos[reg.number];
+
+        if (GraalOptions.TraceLinearScanLevel >= 4) {
+            TTY.println("decided to use register %d", reg.number);
+        }
+        assert splitPos > 0 : "invalid splitPos";
+        assert needSplit || splitPos > interval.from() : "splitting interval at from";
+
+        interval.assignLocation(reg.asValue(interval.kind()));
+        if (needSplit) {
+            // register not available for full interval :  so split it
+            splitWhenPartialRegisterAvailable(interval, splitPos);
+        }
+
+        // perform splitting and spilling for all affected intervals
+        splitAndSpillIntersectingIntervals(reg);
+    }
+
+    boolean noAllocationPossible(Interval interval) {
+
+        if (!hasCalleeSavedRegisters) {
+            // fast calculation of intervals that can never get a register because the
+            // the next instruction is a call that blocks all registers
+            // Note: this does not work if callee-saved registers are available (e.g. on Sparc)
+
+            // check if this interval is the result of a split operation
+            // (an interval got a register until this position)
+            int pos = interval.from();
+            if (isOdd(pos)) {
+                // the current instruction is a call that blocks all registers
+                if (pos < allocator.maxOpId() && allocator.hasCall(pos + 1) && interval.to() > pos + 1) {
+                    if (GraalOptions.TraceLinearScanLevel >= 4) {
+                        TTY.println("      free register cannot be available because all registers blocked by following call");
+                    }
+
+                    // safety check that there is really no register available
+                    assert !allocFreeRegister(interval) : "found a register for this interval";
+                    return true;
+                }
+
+            }
+        }
+        return false;
+    }
+
+    void initVarsForAlloc(Interval interval) {
+        EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = allocator.frameMap.registerConfig.getCategorizedAllocatableRegisters();
+        availableRegs = categorizedRegs.get(asVariable(interval.operand).flag);
+    }
+
+    static boolean isMove(LIRInstruction op, Interval from, Interval to) {
+        if (op instanceof MoveOp) {
+            MoveOp move = (MoveOp) op;
+            return isVariable(move.getInput()) && isVariable(move.getResult()) && move.getInput() == from.operand && move.getResult() == to.operand;
+        }
+        return false;
+    }
+
+    // optimization (especially for phi functions of nested loops):
+    // assign same spill slot to non-intersecting intervals
+    void combineSpilledIntervals(Interval interval) {
+        if (interval.isSplitChild()) {
+            // optimization is only suitable for split parents
+            return;
+        }
+
+        Interval registerHint = interval.locationHint(false);
+        if (registerHint == null) {
+            // cur is not the target of a move : otherwise registerHint would be set
+            return;
+        }
+        assert registerHint.isSplitParent() : "register hint must be split parent";
+
+        if (interval.spillState() != SpillState.NoOptimization || registerHint.spillState() != SpillState.NoOptimization) {
+            // combining the stack slots for intervals where spill move optimization is applied
+            // is not benefitial and would cause problems
+            return;
+        }
+
+        int beginPos = interval.from();
+        int endPos = interval.to();
+        if (endPos > allocator.maxOpId() || isOdd(beginPos) || isOdd(endPos)) {
+            // safety check that lirOpWithId is allowed
+            return;
+        }
+
+        if (!isMove(allocator.instructionForId(beginPos), registerHint, interval) || !isMove(allocator.instructionForId(endPos), interval, registerHint)) {
+            // cur and registerHint are not connected with two moves
+            return;
+        }
+
+        Interval beginHint = registerHint.getSplitChildAtOpId(beginPos, LIRInstruction.OperandMode.Input, allocator);
+        Interval endHint = registerHint.getSplitChildAtOpId(endPos, LIRInstruction.OperandMode.Output, allocator);
+        if (beginHint == endHint || beginHint.to() != beginPos || endHint.from() != endPos) {
+            // registerHint must be split : otherwise the re-writing of use positions does not work
+            return;
+        }
+
+        assert beginHint.location() != null : "must have register assigned";
+        assert endHint.location() == null : "must not have register assigned";
+        assert interval.firstUsage(RegisterPriority.MustHaveRegister) == beginPos : "must have use position at begin of interval because of move";
+        assert endHint.firstUsage(RegisterPriority.MustHaveRegister) == endPos : "must have use position at begin of interval because of move";
+
+        if (isRegister(beginHint.location())) {
+            // registerHint is not spilled at beginPos : so it would not be benefitial to immediately spill cur
+            return;
+        }
+        assert registerHint.spillSlot() != null : "must be set when part of interval was spilled";
+
+        // modify intervals such that cur gets the same stack slot as registerHint
+        // delete use positions to prevent the intervals to get a register at beginning
+        interval.setSpillSlot(registerHint.spillSlot());
+        interval.removeFirstUsePos();
+        endHint.removeFirstUsePos();
+    }
+
+    // allocate a physical register or memory location to an interval
+    @Override
+    boolean activateCurrent() {
+        Interval interval = currentInterval;
+        boolean result = true;
+
+        if (GraalOptions.TraceLinearScanLevel >= 2) {
+            TTY.println("+++++ activating interval " + interval.logString(allocator));
+        }
+
+        if (GraalOptions.TraceLinearScanLevel >= 4) {
+            TTY.println("      splitParent: %s, insertMoveWhenActivated: %b", interval.splitParent().operandNumber, interval.insertMoveWhenActivated());
+        }
+
+        final CiValue operand = interval.operand;
+        if (interval.location() != null && isStackSlot(interval.location())) {
+            // activating an interval that has a stack slot assigned . split it at first use position
+            // used for method parameters
+            if (GraalOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("      interval has spill slot assigned (method parameter) . split it before first use");
+            }
+            splitStackInterval(interval);
+            result = false;
+
+        } else {
+            if (interval.location() == null) {
+                // interval has not assigned register . normal allocation
+                // (this is the normal case for most intervals)
+                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                    TTY.println("      normal allocation of register");
+                }
+
+                // assign same spill slot to non-intersecting intervals
+                combineSpilledIntervals(interval);
+
+                initVarsForAlloc(interval);
+                if (noAllocationPossible(interval) || !allocFreeRegister(interval)) {
+                    // no empty register available.
+                    // split and spill another interval so that this interval gets a register
+                    allocLockedRegister(interval);
+                }
+
+                // spilled intervals need not be move to active-list
+                if (!isRegister(interval.location())) {
+                    result = false;
+                }
+            }
+        }
+
+        // load spilled values that become active from stack slot to register
+        if (interval.insertMoveWhenActivated()) {
+            assert interval.isSplitChild();
+            assert interval.currentSplitChild() != null;
+            assert interval.currentSplitChild().operand != operand : "cannot insert move between same interval";
+            if (GraalOptions.TraceLinearScanLevel >= 4) {
+                TTY.println("Inserting move from interval %d to %d because insertMoveWhenActivated is set", interval.currentSplitChild().operandNumber, interval.operandNumber);
+            }
+
+            insertMove(interval.from(), interval.currentSplitChild(), interval);
+        }
+        interval.makeCurrentSplitChild();
+
+        return result; // true = interval is moved to active list
+    }
+
+    public void finishAllocation() {
+        // must be called when all intervals are allocated
+        moveResolver.resolveAndAppendMoves();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/MoveResolver.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,356 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.compiler.alloc;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.lir.*;
+
+/**
+ */
+final class MoveResolver {
+
+    private final LinearScan allocator;
+
+    private int insertIdx;
+    private LIRInsertionBuffer insertionBuffer; // buffer where moves are inserted
+
+    private final List<Interval> mappingFrom;
+    private final List<CiValue> mappingFromOpr;
+    private final List<Interval> mappingTo;
+    private boolean multipleReadsAllowed;
+    private final int[] registerBlocked;
+
+    private int registerBlocked(int reg) {
+        return registerBlocked[reg];
+    }
+
+    private void setRegisterBlocked(int reg, int direction) {
+        assert direction == 1 || direction == -1 : "out of bounds";
+        registerBlocked[reg] += direction;
+    }
+
+    void setMultipleReadsAllowed() {
+        multipleReadsAllowed = true;
+    }
+
+    boolean hasMappings() {
+        return mappingFrom.size() > 0;
+    }
+
+    MoveResolver(LinearScan allocator) {
+
+        this.allocator = allocator;
+        this.multipleReadsAllowed = false;
+        this.mappingFrom = new ArrayList<>(8);
+        this.mappingFromOpr = new ArrayList<>(8);
+        this.mappingTo = new ArrayList<>(8);
+        this.insertIdx = -1;
+        this.insertionBuffer = new LIRInsertionBuffer();
+        this.registerBlocked = new int[allocator.registers.length];
+        assert checkEmpty();
+    }
+
+    boolean checkEmpty() {
+        assert mappingFrom.size() == 0 && mappingFromOpr.size() == 0 && mappingTo.size() == 0 : "list must be empty before and after processing";
+        for (int i = 0; i < allocator.registers.length; i++) {
+            assert registerBlocked(i) == 0 : "register map must be empty before and after processing";
+        }
+        assert !multipleReadsAllowed : "must have default value";
+        return true;
+    }
+
+    private boolean verifyBeforeResolve() {
+        assert mappingFrom.size() == mappingFromOpr.size() : "length must be equal";
+        assert mappingFrom.size() == mappingTo.size() : "length must be equal";
+        assert insertIdx != -1 : "insert position not set";
+
+        int i;
+        int j;
+        if (!multipleReadsAllowed) {
+            for (i = 0; i < mappingFrom.size(); i++) {
+                for (j = i + 1; j < mappingFrom.size(); j++) {
+                    assert mappingFrom.get(i) == null || mappingFrom.get(i) != mappingFrom.get(j) : "cannot read from same interval twice";
+                }
+            }
+        }
+
+        for (i = 0; i < mappingTo.size(); i++) {
+            for (j = i + 1; j < mappingTo.size(); j++) {
+                assert mappingTo.get(i) != mappingTo.get(j) : "cannot write to same interval twice";
+            }
+        }
+
+        HashSet<CiValue> usedRegs = new HashSet<>();
+        if (!multipleReadsAllowed) {
+            for (i = 0; i < mappingFrom.size(); i++) {
+                Interval interval = mappingFrom.get(i);
+                if (interval != null) {
+                    boolean unique = usedRegs.add(interval.location());
+                    assert unique : "cannot read from same register twice";
+                }
+            }
+        }
+
+        usedRegs.clear();
+        for (i = 0; i < mappingTo.size(); i++) {
+            Interval interval = mappingTo.get(i);
+            boolean unique = usedRegs.add(interval.location());
+            assert unique : "cannot write to same register twice";
+        }
+
+        usedRegs.clear();
+        for (i = 0; i < mappingFrom.size(); i++) {
+            Interval interval = mappingFrom.get(i);
+            if (interval != null && !isRegister(interval.location())) {
+                usedRegs.add(interval.location());
+            }
+        }
+        for (i = 0; i < mappingTo.size(); i++) {
+            Interval interval = mappingTo.get(i);
+            assert !usedRegs.contains(interval.location()) || interval.location() == mappingFrom.get(i).location() : "stack slots used in mappingFrom must be disjoint to mappingTo";
+        }
+
+        return true;
+    }
+
+    // mark assignedReg and assignedRegHi of the interval as blocked
+    private void blockRegisters(Interval interval) {
+        CiValue location = interval.location();
+        if (isRegister(location)) {
+            int reg = asRegister(location).number;
+            assert multipleReadsAllowed || registerBlocked(reg) == 0 : "register already marked as used";
+            setRegisterBlocked(reg, 1);
+        }
+    }
+
+    // mark assignedReg and assignedRegHi of the interval as unblocked
+    private void unblockRegisters(Interval interval) {
+        CiValue location = interval.location();
+        if (isRegister(location)) {
+            int reg = asRegister(location).number;
+            assert registerBlocked(reg) > 0 : "register already marked as unused";
+            setRegisterBlocked(reg, -1);
+        }
+    }
+
+    /**
+     * Checks if the {@linkplain Interval#location() location} of {@code to} is not blocked
+     * or is only blocked by {@code from}.
+     */
+    private boolean safeToProcessMove(Interval from, Interval to) {
+        CiValue fromReg = from != null ? from.location() : null;
+
+        CiValue reg = to.location();
+        if (isRegister(reg)) {
+            if (registerBlocked(asRegister(reg).number) > 1 || (registerBlocked(asRegister(reg).number) == 1 && reg != fromReg)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private void createInsertionBuffer(List<LIRInstruction> list) {
+        assert !insertionBuffer.initialized() : "overwriting existing buffer";
+        insertionBuffer.init(list);
+    }
+
+    private void appendInsertionBuffer() {
+        if (insertionBuffer.initialized()) {
+            insertionBuffer.finish();
+        }
+        assert !insertionBuffer.initialized() : "must be uninitialized now";
+
+        insertIdx = -1;
+    }
+
+    private void insertMove(Interval fromInterval, Interval toInterval) {
+        assert fromInterval.operand != toInterval.operand : "from and to interval equal: " + fromInterval;
+        assert fromInterval.kind() == toInterval.kind() : "move between different types";
+        assert insertIdx != -1 : "must setup insert position first";
+
+        CiValue fromOpr = fromInterval.operand;
+        CiValue toOpr = toInterval.operand;
+
+        insertionBuffer.append(insertIdx, allocator.ir.spillMoveFactory.createMove(toOpr, fromOpr));
+
+        if (GraalOptions.TraceLinearScanLevel >= 4) {
+            TTY.println("MoveResolver: inserted move from %d (%s) to %d (%s)", fromInterval.operandNumber, fromInterval.location(), toInterval.operandNumber, toInterval.location());
+        }
+    }
+
+    private void insertMove(CiValue fromOpr, Interval toInterval) {
+        assert fromOpr.kind == toInterval.kind() : "move between different types";
+        assert insertIdx != -1 : "must setup insert position first";
+
+        CiValue toOpr = toInterval.operand;
+        insertionBuffer.append(insertIdx, allocator.ir.spillMoveFactory.createMove(toOpr, fromOpr));
+
+        if (GraalOptions.TraceLinearScanLevel >= 4) {
+            TTY.print("MoveResolver: inserted move from constant %s to %d (%s)", fromOpr, toInterval.operandNumber, toInterval.location());
+        }
+    }
+
+    private void resolveMappings() {
+        assert verifyBeforeResolve();
+
+        // Block all registers that are used as input operands of a move.
+        // When a register is blocked, no move to this register is emitted.
+        // This is necessary for detecting cycles in moves.
+        int i;
+        for (i = mappingFrom.size() - 1; i >= 0; i--) {
+            Interval fromInterval = mappingFrom.get(i);
+            if (fromInterval != null) {
+                blockRegisters(fromInterval);
+            }
+        }
+
+        int spillCandidate = -1;
+        while (mappingFrom.size() > 0) {
+            boolean processedInterval = false;
+
+            for (i = mappingFrom.size() - 1; i >= 0; i--) {
+                Interval fromInterval = mappingFrom.get(i);
+                Interval toInterval = mappingTo.get(i);
+
+                if (safeToProcessMove(fromInterval, toInterval)) {
+                    // this interval can be processed because target is free
+                    if (fromInterval != null) {
+                        insertMove(fromInterval, toInterval);
+                        unblockRegisters(fromInterval);
+                    } else {
+                        insertMove(mappingFromOpr.get(i), toInterval);
+                    }
+                    mappingFrom.remove(i);
+                    mappingFromOpr.remove(i);
+                    mappingTo.remove(i);
+
+                    processedInterval = true;
+                } else if (fromInterval != null && isRegister(fromInterval.location())) {
+                    // this interval cannot be processed now because target is not free
+                    // it starts in a register, so it is a possible candidate for spilling
+                    spillCandidate = i;
+                }
+            }
+
+            if (!processedInterval) {
+                // no move could be processed because there is a cycle in the move list
+                // (e.g. r1 . r2, r2 . r1), so one interval must be spilled to memory
+                assert spillCandidate != -1 : "no interval in register for spilling found";
+
+                // create a new spill interval and assign a stack slot to it
+                Interval fromInterval = mappingFrom.get(spillCandidate);
+                Interval spillInterval = allocator.createDerivedInterval(fromInterval);
+                spillInterval.setKind(fromInterval.kind());
+
+                // add a dummy range because real position is difficult to calculate
+                // Note: this range is a special case when the integrity of the allocation is checked
+                spillInterval.addRange(1, 2);
+
+                // do not allocate a new spill slot for temporary interval, but
+                // use spill slot assigned to fromInterval. Otherwise moves from
+                // one stack slot to another can happen (not allowed by LIRAssembler
+                CiStackSlot spillSlot = fromInterval.spillSlot();
+                if (spillSlot == null) {
+                    spillSlot = allocator.frameMap.allocateSpillSlot(spillInterval.kind());
+                    fromInterval.setSpillSlot(spillSlot);
+                }
+                spillInterval.assignLocation(spillSlot);
+
+                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                    TTY.println("created new Interval %s for spilling", spillInterval.operand);
+                }
+
+                // insert a move from register to stack and update the mapping
+                insertMove(fromInterval, spillInterval);
+                mappingFrom.set(spillCandidate, spillInterval);
+                unblockRegisters(fromInterval);
+            }
+        }
+
+        // reset to default value
+        multipleReadsAllowed = false;
+
+        // check that all intervals have been processed
+        assert checkEmpty();
+    }
+
+    void setInsertPosition(List<LIRInstruction> insertList, int insertIdx) {
+        assert this.insertIdx == -1 : "use moveInsertPosition instead of setInsertPosition when data already set";
+
+        createInsertionBuffer(insertList);
+        this.insertIdx = insertIdx;
+    }
+
+    void moveInsertPosition(List<LIRInstruction> newInsertList, int newInsertIdx) {
+        if (insertionBuffer.lirList() != null && (insertionBuffer.lirList() != newInsertList || this.insertIdx != newInsertIdx)) {
+            // insert position changed . resolve current mappings
+            resolveMappings();
+        }
+
+        if (insertionBuffer.lirList() != newInsertList) {
+            // block changed . append insertionBuffer because it is
+            // bound to a specific block and create a new insertionBuffer
+            appendInsertionBuffer();
+            createInsertionBuffer(newInsertList);
+        }
+
+        this.insertIdx = newInsertIdx;
+    }
+
+    void addMapping(Interval fromInterval, Interval toInterval) {
+        if (GraalOptions.TraceLinearScanLevel >= 4) {
+            TTY.println("MoveResolver: adding mapping from interval %d (%s) to interval %d (%s)", fromInterval.operandNumber, fromInterval.location(), toInterval.operandNumber, toInterval.location());
+        }
+
+        assert fromInterval.operand != toInterval.operand : "from and to interval equal: " + fromInterval;
+        assert fromInterval.kind() == toInterval.kind();
+        mappingFrom.add(fromInterval);
+        mappingFromOpr.add(CiValue.IllegalValue);
+        mappingTo.add(toInterval);
+    }
+
+    void addMapping(CiValue fromOpr, Interval toInterval) {
+        if (GraalOptions.TraceLinearScanLevel >= 4) {
+            TTY.println("MoveResolver: adding mapping from %s to %d (%s)", fromOpr, toInterval.operandNumber, toInterval.location());
+        }
+        assert isConstant(fromOpr) : "only for constants";
+
+        mappingFrom.add(null);
+        mappingFromOpr.add(fromOpr);
+        mappingTo.add(toInterval);
+    }
+
+    void resolveAndAppendMoves() {
+        if (hasMappings()) {
+            resolveMappings();
+        }
+        appendInsertionBuffer();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/Range.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.compiler.alloc;
+
+
+/**
+ * Represents a range of integers from a start (inclusive) to an end (exclusive.
+ */
+public final class Range {
+
+    public static final Range EndMarker = new Range(Integer.MAX_VALUE, Integer.MAX_VALUE, null);
+
+    /**
+     * The start of the range, inclusive.
+     */
+    public int from;
+
+    /**
+     * The end of the range, exclusive.
+     */
+    public int to;
+
+    /**
+     * A link to allow the range to be put into a singly linked list.
+     */
+    public Range next;
+
+    boolean intersects(Range r) {
+        return intersectsAt(r) != -1;
+    }
+
+
+    /**
+     * Creates a new range.
+     *
+     * @param from the start of the range, inclusive
+     * @param to the end of the range, exclusive
+     * @param next link to the next range in a linked list
+     */
+    Range(int from, int to, Range next) {
+        this.from = from;
+        this.to = to;
+        this.next = next;
+    }
+
+    int intersectsAt(Range other) {
+        Range r1 = this;
+        Range r2 = other;
+
+        assert r2 != null : "null ranges not allowed";
+        assert r1 != EndMarker && r2 != EndMarker : "empty ranges not allowed";
+
+        do {
+            if (r1.from < r2.from) {
+                if (r1.to <= r2.from) {
+                    r1 = r1.next;
+                    if (r1 == EndMarker) {
+                        return -1;
+                    }
+                } else {
+                    return r2.from;
+                }
+            } else {
+                if (r2.from < r1.from) {
+                    if (r2.to <= r1.from) {
+                        r2 = r2.next;
+                        if (r2 == EndMarker) {
+                            return -1;
+                        }
+                    } else {
+                        return r1.from;
+                    }
+                } else { // r1.from() == r2.from()
+                    if (r1.from == r1.to) {
+                        r1 = r1.next;
+                        if (r1 == EndMarker) {
+                            return -1;
+                        }
+                    } else {
+                        if (r2.from == r2.to) {
+                            r2 = r2.next;
+                            if (r2 == EndMarker) {
+                                return -1;
+                            }
+                        } else {
+                            return r1.from;
+                        }
+                    }
+                }
+            }
+        } while (true);
+    }
+
+    @Override
+    public String toString() {
+        return "[" + from + ", " + to + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/RegisterVerifier.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.compiler.alloc;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+/**
+ */
+final class RegisterVerifier {
+
+    LinearScan allocator;
+    List<Block> workList; // all blocks that must be processed
+    ArrayMap<Interval[]> savedStates; // saved information of previous check
+
+    // simplified access to methods of LinearScan
+    Interval intervalAt(CiValue operand) {
+        return allocator.intervalFor(operand);
+    }
+
+    // currently, only registers are processed
+    int stateSize() {
+        return allocator.maxRegisterNumber() + 1;
+    }
+
+    // accessors
+    Interval[] stateForBlock(Block block) {
+        return savedStates.get(block.getId());
+    }
+
+    void setStateForBlock(Block block, Interval[] savedState) {
+        savedStates.put(block.getId(), savedState);
+    }
+
+    void addToWorkList(Block block) {
+        if (!workList.contains(block)) {
+            workList.add(block);
+        }
+    }
+
+    RegisterVerifier(LinearScan allocator) {
+        this.allocator = allocator;
+        workList = new ArrayList<>(16);
+        this.savedStates = new ArrayMap<>();
+
+    }
+
+    void verify(Block start) {
+        // setup input registers (method arguments) for first block
+        Interval[] inputState = new Interval[stateSize()];
+        setStateForBlock(start, inputState);
+        addToWorkList(start);
+
+        // main loop for verification
+        do {
+            Block block = workList.get(0);
+            workList.remove(0);
+
+            processBlock(block);
+        } while (!workList.isEmpty());
+    }
+
+    private void processBlock(Block block) {
+        if (GraalOptions.TraceLinearScanLevel >= 2) {
+            TTY.println();
+            TTY.println("processBlock B%d", block.getId());
+        }
+
+        // must copy state because it is modified
+        Interval[] inputState = copy(stateForBlock(block));
+
+        if (GraalOptions.TraceLinearScanLevel >= 4) {
+            TTY.println("Input-State of intervals:");
+            TTY.print("    ");
+            for (int i = 0; i < stateSize(); i++) {
+                if (inputState[i] != null) {
+                    TTY.print(" %4d", inputState[i].operandNumber);
+                } else {
+                    TTY.print("   __");
+                }
+            }
+            TTY.println();
+            TTY.println();
+        }
+
+        // process all operations of the block
+        processOperations(block.lir, inputState);
+
+        // iterate all successors
+        for (int i = 0; i < block.numberOfSux(); i++) {
+            Block succ = block.suxAt(i);
+            processSuccessor(succ, inputState);
+        }
+    }
+
+    private void processSuccessor(Block block, Interval[] inputState) {
+        Interval[] savedState = stateForBlock(block);
+
+        if (savedState != null) {
+            // this block was already processed before.
+            // check if new inputState is consistent with savedState
+
+            boolean savedStateCorrect = true;
+            for (int i = 0; i < stateSize(); i++) {
+                if (inputState[i] != savedState[i]) {
+                    // current inputState and previous savedState assume a different
+                    // interval in this register . assume that this register is invalid
+                    if (savedState[i] != null) {
+                        // invalidate old calculation only if it assumed that
+                        // register was valid. when the register was already invalid,
+                        // then the old calculation was correct.
+                        savedStateCorrect = false;
+                        savedState[i] = null;
+
+                        if (GraalOptions.TraceLinearScanLevel >= 4) {
+                            TTY.println("processSuccessor B%d: invalidating slot %d", block.getId(), i);
+                        }
+                    }
+                }
+            }
+
+            if (savedStateCorrect) {
+                // already processed block with correct inputState
+                if (GraalOptions.TraceLinearScanLevel >= 2) {
+                    TTY.println("processSuccessor B%d: previous visit already correct", block.getId());
+                }
+            } else {
+                // must re-visit this block
+                if (GraalOptions.TraceLinearScanLevel >= 2) {
+                    TTY.println("processSuccessor B%d: must re-visit because input state changed", block.getId());
+                }
+                addToWorkList(block);
+            }
+
+        } else {
+            // block was not processed before, so set initial inputState
+            if (GraalOptions.TraceLinearScanLevel >= 2) {
+                TTY.println("processSuccessor B%d: initial visit", block.getId());
+            }
+
+            setStateForBlock(block, copy(inputState));
+            addToWorkList(block);
+        }
+    }
+
+    static Interval[] copy(Interval[] inputState) {
+        return inputState.clone();
+    }
+
+    static void statePut(Interval[] inputState, CiValue location, Interval interval) {
+        if (location != null && isRegister(location)) {
+            CiRegister reg = asRegister(location);
+            int regNum = reg.number;
+            if (interval != null) {
+                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                    TTY.println("        %s = %s", reg, interval.operand);
+                }
+            } else if (inputState[regNum] != null) {
+                if (GraalOptions.TraceLinearScanLevel >= 4) {
+                    TTY.println("        %s = null", reg);
+                }
+            }
+
+            inputState[regNum] = interval;
+        }
+    }
+
+    static boolean checkState(Interval[] inputState, CiValue reg, Interval interval) {
+        if (reg != null && isRegister(reg)) {
+            if (inputState[asRegister(reg).number] != interval) {
+                throw new GraalInternalError("!! Error in register allocation: register %s does not contain interval %s but interval %s", reg, interval.operand, inputState[asRegister(reg).number]);
+            }
+        }
+        return true;
+    }
+
+    void processOperations(List<LIRInstruction> ops, final Interval[] inputState) {
+        // visit all instructions of the block
+        for (int i = 0; i < ops.size(); i++) {
+            final LIRInstruction op = ops.get(i);
+
+            if (GraalOptions.TraceLinearScanLevel >= 4) {
+                TTY.println(op.toStringWithIdPrefix());
+            }
+
+            ValueProcedure useProc = new ValueProcedure() {
+                @Override
+                public CiValue doValue(CiValue operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                    if (LinearScan.isVariableOrRegister(operand) && allocator.isProcessed(operand)) {
+                        Interval interval = intervalAt(operand);
+                        if (op.id() != -1) {
+                            interval = interval.getSplitChildAtOpId(op.id(), mode, allocator);
+                        }
+
+                        assert checkState(inputState, interval.location(), interval.splitParent());
+                    }
+                    return operand;
+                }
+            };
+
+            ValueProcedure defProc = new ValueProcedure() {
+                @Override
+                public CiValue doValue(CiValue operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                    if (LinearScan.isVariableOrRegister(operand) && allocator.isProcessed(operand)) {
+                        Interval interval = intervalAt(operand);
+                        if (op.id() != -1) {
+                            interval = interval.getSplitChildAtOpId(op.id(), mode, allocator);
+                        }
+
+                        statePut(inputState, interval.location(), interval.splitParent());
+                    }
+                    return operand;
+                }
+            };
+
+            // check if input operands are correct
+            op.forEachInput(useProc);
+            // invalidate all caller save registers at calls
+            if (op.hasCall()) {
+                for (CiRegister r : allocator.frameMap.registerConfig.getCallerSaveRegisters()) {
+                    statePut(inputState, r.asValue(), null);
+                }
+            }
+            op.forEachAlive(useProc);
+            // set temp operands (some operations use temp operands also as output operands, so can't set them null)
+            op.forEachTemp(defProc);
+            // set output operands
+            op.forEachOutput(defProc);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/package-info.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+/**
+ * A collection of debugging aids for Graal development.
+ */
+package com.oracle.max.graal.compiler.debug;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/DebugInfoBuilder.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.compiler.gen;
+
+import java.util.*;
+import java.util.Map.Entry;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.compiler.gen.LIRGenerator.LockScope;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.virtual.*;
+
+public class DebugInfoBuilder {
+    private final NodeMap<CiValue> nodeOperands;
+
+    public DebugInfoBuilder(NodeMap<CiValue> nodeOperands) {
+        this.nodeOperands = nodeOperands;
+    }
+
+
+    private HashMap<VirtualObjectNode, CiVirtualObject> virtualObjects = new HashMap<>();
+
+    public LIRDebugInfo build(FrameState topState, LockScope locks, List<CiStackSlot> pointerSlots, LabelRef exceptionEdge) {
+        assert virtualObjects.size() == 0;
+        CiFrame frame = computeFrameForState(topState, locks);
+
+        CiVirtualObject[] virtualObjectsArray = null;
+        if (virtualObjects.size() != 0) {
+            // collect all VirtualObjectField instances:
+            IdentityHashMap<VirtualObjectNode, VirtualObjectFieldNode> objectStates = new IdentityHashMap<>();
+            FrameState current = topState;
+            do {
+                for (Node n : current.virtualObjectMappings()) {
+                    VirtualObjectFieldNode field = (VirtualObjectFieldNode) n;
+                    // null states occur for objects with 0 fields
+                    if (field != null && !objectStates.containsKey(field.object())) {
+                        objectStates.put(field.object(), field);
+                    }
+                }
+                current = current.outerFrameState();
+            } while (current != null);
+            // fill in the CiVirtualObject values:
+            // during this process new CiVirtualObjects might be discovered, so repeat until no more changes occur.
+            boolean changed;
+            do {
+                changed = false;
+                IdentityHashMap<VirtualObjectNode, CiVirtualObject> virtualObjectsCopy = new IdentityHashMap<>(virtualObjects);
+                for (Entry<VirtualObjectNode, CiVirtualObject> entry : virtualObjectsCopy.entrySet()) {
+                    if (entry.getValue().values() == null) {
+                        VirtualObjectNode vobj = entry.getKey();
+                        if (vobj instanceof BoxedVirtualObjectNode) {
+                            BoxedVirtualObjectNode boxedVirtualObjectNode = (BoxedVirtualObjectNode) vobj;
+                            entry.getValue().setValues(new CiValue[]{toCiValue(boxedVirtualObjectNode.getUnboxedValue())});
+                        } else {
+                            CiValue[] values = new CiValue[vobj.fieldsCount()];
+                            entry.getValue().setValues(values);
+                            if (values.length > 0) {
+                                changed = true;
+                                ValueNode currentField = objectStates.get(vobj);
+                                assert currentField != null;
+                                do {
+                                    if (currentField instanceof VirtualObjectFieldNode) {
+                                        int index = ((VirtualObjectFieldNode) currentField).index();
+                                        if (values[index] == null) {
+                                            values[index] = toCiValue(((VirtualObjectFieldNode) currentField).input());
+                                        }
+                                        currentField = ((VirtualObjectFieldNode) currentField).lastState();
+                                    } else {
+                                        assert currentField instanceof PhiNode : currentField;
+                                        currentField = ((PhiNode) currentField).valueAt(0);
+                                    }
+                                } while (currentField != null);
+                            }
+                        }
+                    }
+                }
+            } while (changed);
+
+            virtualObjectsArray = virtualObjects.values().toArray(new CiVirtualObject[virtualObjects.size()]);
+            virtualObjects.clear();
+        }
+
+        return new LIRDebugInfo(frame, virtualObjectsArray, pointerSlots, exceptionEdge);
+    }
+
+    private CiFrame computeFrameForState(FrameState state, LockScope locks) {
+        int numLocks = (locks != null && locks.callerState == state.outerFrameState()) ? locks.stateDepth + 1 : 0;
+
+        CiValue[] values = new CiValue[state.valuesSize() + numLocks];
+        int valueIndex = 0;
+
+        for (int i = 0; i < state.valuesSize(); i++) {
+            values[valueIndex++] = toCiValue(state.valueAt(i));
+        }
+
+        LockScope nextLock = locks;
+        for (int i = numLocks - 1; i >= 0; i--) {
+            assert locks != null && nextLock.callerState == state.outerFrameState() && nextLock.stateDepth == i;
+
+            CiValue owner = toCiValue(nextLock.monitor.object());
+            CiValue lockData = nextLock.lockData;
+            boolean eliminated = nextLock.monitor.eliminated();
+            values[state.valuesSize() + nextLock.stateDepth] = new CiMonitorValue(owner, lockData, eliminated);
+
+            nextLock = nextLock.outer;
+        }
+
+        CiFrame caller = null;
+        if (state.outerFrameState() != null) {
+            caller = computeFrameForState(state.outerFrameState(), nextLock);
+        } else {
+            if (nextLock != null) {
+                throw new CiBailout("unbalanced monitors: found monitor for unknown frame");
+            }
+        }
+        assert state.bci >= 0 || state.bci == FrameState.BEFORE_BCI;
+        CiFrame frame = new CiFrame(caller, state.method(), state.bci, state.rethrowException(), state.duringCall(), values, state.localsSize(), state.stackSize(), numLocks);
+        return frame;
+    }
+
+    private CiValue toCiValue(ValueNode value) {
+        if (value instanceof VirtualObjectNode) {
+            VirtualObjectNode obj = (VirtualObjectNode) value;
+            CiVirtualObject ciObj = virtualObjects.get(value);
+            if (ciObj == null) {
+                ciObj = CiVirtualObject.get(obj.type(), null, virtualObjects.size());
+                virtualObjects.put(obj, ciObj);
+            }
+            return ciObj;
+
+        } else if (value instanceof ConstantNode) {
+            return ((ConstantNode) value).value;
+
+        } else if (value != null) {
+            CiValue operand = nodeOperands.get(value);
+            assert operand != null && (operand instanceof Variable || operand instanceof CiConstant);
+            return operand;
+
+        } else {
+            // return a dummy value because real value not needed
+            return CiValue.IllegalValue;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/InstructionPrinter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.compiler.gen;
+
+import static com.oracle.max.graal.compiler.gen.InstructionPrinter.InstructionLineColumn.*;
+
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.nodes.*;
+
+/**
+ * A {@link ValueVisitor} for {@linkplain #printInstruction(ValueNode) printing}
+ * an {@link FixedWithNextNode} as an expression or statement.
+ */
+public class InstructionPrinter {
+
+
+    /**
+     * The columns printed in a tabulated instruction
+     * {@linkplain InstructionPrinter#printInstructionListing(ValueNode) listing}.
+     */
+    public enum InstructionLineColumn {
+        /**
+         * The instruction's bytecode index.
+         */
+        BCI(2, "bci"),
+
+        /**
+         * The instruction's use count.
+         */
+        USE(7, "use"),
+
+        /**
+         * The instruction as a {@linkplain com.oracle.max.graal.compiler.util.Util#valueString(com.oracle.max.graal.compiler.ir.Value) value}.
+         */
+        VALUE(12, "tid"),
+
+        /**
+         * The instruction formatted as an expression or statement.
+         */
+        INSTRUCTION(19, "instr"),
+
+        END(60, "");
+
+        final int position;
+        final String label;
+
+        private InstructionLineColumn(int position, String label) {
+            this.position = position;
+            this.label = label;
+        }
+
+        /**
+         * Prints this column's label to a given stream after padding the stream with '_' characters
+         * until its {@linkplain LogStream#position() position} is equal to this column's position.
+         * @param out the print stream
+         */
+        public void printLabel(LogStream out) {
+            out.fillTo(position + out.indentationLevel(), '_');
+            out.print(label);
+        }
+
+        /**
+         * Prints space characters to a given stream until its {@linkplain LogStream#position() position}
+         * is equal to this column's position.
+         * @param out the print stream
+         */
+        public void advance(LogStream out) {
+            out.fillTo(position + out.indentationLevel(), ' ');
+        }
+    }
+
+    private final LogStream out;
+
+    public InstructionPrinter(LogStream out) {
+        this.out = out;
+    }
+
+    public LogStream out() {
+        return out;
+    }
+
+    /**
+     * Prints a header for the tabulated data printed by {@link #printInstructionListing(ValueNode)}.
+     */
+    public void printInstructionListingHeader() {
+        BCI.printLabel(out);
+        USE.printLabel(out);
+        VALUE.printLabel(out);
+        INSTRUCTION.printLabel(out);
+        END.printLabel(out);
+        out.println();
+    }
+
+    /**
+     * Prints an instruction listing on one line. The instruction listing is composed of the
+     * columns specified by {@link InstructionLineColumn}.
+     *
+     * @param instruction the instruction to print
+     */
+    public void printInstructionListing(ValueNode instruction) {
+        int indentation = out.indentationLevel();
+        out.fillTo(BCI.position + indentation, ' ').
+             print(0).
+             fillTo(USE.position + indentation, ' ').
+             print("0").
+             fillTo(VALUE.position + indentation, ' ').
+             print(ValueUtil.valueString(instruction)).
+             fillTo(INSTRUCTION.position + indentation, ' ');
+        printInstruction(instruction);
+        if (instruction instanceof StateSplit) {
+            out.print("  [state: " + ((StateSplit) instruction).stateAfter() + "]");
+        }
+        out.println();
+    }
+
+    public void printInstruction(ValueNode node) {
+        out.print(node.toString());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1508 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.compiler.gen;
+
+import static com.oracle.max.cri.ci.CiCallingConvention.Type.*;
+import static com.oracle.max.cri.ci.CiValue.*;
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.max.cri.util.MemoryBarriers.*;
+import static com.oracle.max.graal.lir.ValueUtil.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiTargetMethod.Mark;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.cri.ri.RiType.Representation;
+import com.oracle.max.cri.xir.CiXirAssembler.XirConstant;
+import com.oracle.max.cri.xir.CiXirAssembler.XirInstruction;
+import com.oracle.max.cri.xir.CiXirAssembler.XirMark;
+import com.oracle.max.cri.xir.CiXirAssembler.XirOperand;
+import com.oracle.max.cri.xir.CiXirAssembler.XirParameter;
+import com.oracle.max.cri.xir.CiXirAssembler.XirRegister;
+import com.oracle.max.cri.xir.CiXirAssembler.XirTemp;
+import com.oracle.max.cri.xir.*;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.StandardOp.*;
+import com.oracle.max.graal.lir.cfg.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction;
+import com.oracle.max.graal.nodes.PhiNode.PhiType;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.java.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.virtual.*;
+
+/**
+ * This class traverses the HIR instructions and generates LIR instructions from them.
+ */
+public abstract class LIRGenerator extends LIRGeneratorTool {
+    protected final Graph graph;
+    protected final RiRuntime runtime;
+    protected final CiTarget target;
+    protected final RiResolvedMethod method;
+    protected final FrameMap frameMap;
+    public final NodeMap<CiValue> nodeOperands;
+
+    protected final LIR lir;
+    protected final XirSupport xirSupport;
+    protected final RiXirGenerator xir;
+    private final DebugInfoBuilder debugInfoBuilder;
+
+    private Block currentBlock;
+    private ValueNode currentInstruction;
+    private ValueNode lastInstructionPrinted; // Debugging only
+    private FrameState lastState;
+
+    /**
+     * Class used to reconstruct the nesting of locks that is required for debug information.
+     */
+    public static class LockScope {
+        /**
+         * Linked list of locks. {@link LIRGenerator#curLocks} is the head of the list.
+         */
+        public final LockScope outer;
+
+        /**
+         * The frame state of the caller of the method performing the lock, or null if the outermost method
+         * performs the lock. This information is used to compute the {@link CiFrame} that this lock belongs to.
+         * We cannot use the actual frame state of the locking method, because it is not unique for a method. The
+         * caller frame states are unique, i.e., all frame states of inlined methods refer to the same caller frame state.
+         */
+        public final FrameState callerState;
+
+        /**
+         * The number of locks already found for this frame state.
+         */
+        public final int stateDepth;
+
+        /**
+         * The monitor enter node, with information about the object that is locked and the elimination status.
+         */
+        public final MonitorEnterNode monitor;
+
+        /**
+         * Space in the stack frame needed by the VM to perform the locking.
+         */
+        public final CiStackSlot lockData;
+
+        public LockScope(LockScope outer, FrameState callerState, MonitorEnterNode monitor, CiStackSlot lockData) {
+            this.outer = outer;
+            this.callerState = callerState;
+            this.monitor = monitor;
+            this.lockData = lockData;
+            if (outer != null && outer.callerState == callerState) {
+                this.stateDepth = outer.stateDepth + 1;
+            } else {
+                this.stateDepth = 0;
+            }
+        }
+    }
+
+    /**
+     * Mapping from blocks to the lock state at the end of the block, indexed by the id number of the block.
+     */
+    private BlockMap<LockScope> blockLocks;
+
+    private BlockMap<FrameState> blockLastState;
+
+    /**
+     * The list of currently locked monitors.
+     */
+    private LockScope curLocks;
+
+
+    public LIRGenerator(Graph graph, RiRuntime runtime, CiTarget target, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) {
+        this.graph = graph;
+        this.runtime = runtime;
+        this.target = target;
+        this.frameMap = frameMap;
+        this.method = method;
+        this.nodeOperands = graph.createNodeMap();
+        this.lir = lir;
+        this.xir = xir;
+        this.xirSupport = new XirSupport();
+        this.debugInfoBuilder = new DebugInfoBuilder(nodeOperands);
+        this.blockLocks = new BlockMap<>(lir.cfg);
+        this.blockLastState = new BlockMap<>(lir.cfg);
+    }
+
+    @Override
+    public CiTarget target() {
+        return target;
+    }
+
+    /**
+     * Returns the operand that has been previously initialized by {@link #setResult()}
+     * with the result of an instruction.
+     * @param node A node that produces a result value.
+     */
+    @Override
+    public CiValue operand(ValueNode node) {
+        if (nodeOperands == null) {
+            return null;
+        }
+        return nodeOperands.get(node);
+    }
+
+    /**
+     * Creates a new {@linkplain Variable variable}.
+     * @param kind The kind of the new variable.
+     * @return a new variable
+     */
+    @Override
+    public Variable newVariable(CiKind kind) {
+        CiKind stackKind = kind.stackKind();
+        switch (stackKind) {
+            case Jsr:
+            case Int:
+            case Long:
+            case Object:
+                return new Variable(stackKind, lir.nextVariable(), CiRegister.RegisterFlag.CPU);
+            case Float:
+            case Double:
+                return new Variable(stackKind, lir.nextVariable(), CiRegister.RegisterFlag.FPU);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public CiValue setResult(ValueNode x, CiValue operand) {
+        assert (isVariable(operand) && x.kind() == operand.kind) || (isConstant(operand) && x.kind() == operand.kind.stackKind()) : operand.kind + " for node " + x;
+
+        assert operand(x) == null : "operand cannot be set twice";
+        assert operand != null && isLegal(operand) : "operand must be legal";
+        assert operand.kind.stackKind() == x.kind();
+        assert !(x instanceof VirtualObjectNode);
+        nodeOperands.set(x, operand);
+        return operand;
+    }
+
+    @Override
+    public abstract Variable emitMove(CiValue input);
+
+    public Variable load(CiValue value) {
+        if (!isVariable(value)) {
+            return emitMove(value);
+        }
+        return (Variable) value;
+    }
+
+    public CiValue loadNonConst(CiValue value) {
+        if (isConstant(value) && !canInlineConstant((CiConstant) value)) {
+            return emitMove(value);
+        }
+        return value;
+    }
+
+    public CiValue loadForStore(CiValue value, CiKind storeKind) {
+        if (isConstant(value) && canStoreConstant((CiConstant) value)) {
+            return value;
+        }
+        if (storeKind == CiKind.Byte || storeKind == CiKind.Boolean) {
+            Variable tempVar = new Variable(value.kind, lir.nextVariable(), CiRegister.RegisterFlag.Byte);
+            emitMove(value, tempVar);
+            return tempVar;
+        }
+        return load(value);
+    }
+
+    protected LabelRef getLIRBlock(FixedNode b) {
+        Block result = lir.cfg.blockFor(b);
+        int suxIndex = currentBlock.getSuccessors().indexOf(result);
+        assert suxIndex != -1 : "Block not in successor list of current block";
+
+        return LabelRef.forSuccessor(currentBlock, suxIndex);
+    }
+
+    public LIRDebugInfo state() {
+        assert lastState != null : "must have state before instruction";
+        return stateFor(lastState);
+    }
+
+    public LIRDebugInfo stateFor(FrameState state) {
+        return stateFor(state, null, null);
+    }
+
+    public LIRDebugInfo stateFor(FrameState state, List<CiStackSlot> pointerSlots, LabelRef exceptionEdge) {
+        return debugInfoBuilder.build(state, curLocks, pointerSlots, exceptionEdge);
+    }
+
+    /**
+     * Gets the ABI specific operand used to return a value of a given kind from a method.
+     *
+     * @param kind the kind of value being returned
+     * @return the operand representing the ABI defined location used return a value of kind {@code kind}
+     */
+    public CiValue resultOperandFor(CiKind kind) {
+        if (kind == CiKind.Void) {
+            return IllegalValue;
+        }
+        return frameMap.registerConfig.getReturnRegister(kind).asValue(kind);
+    }
+
+
+    public void append(LIRInstruction op) {
+        assert LIRVerifier.verify(op);
+        if (GraalOptions.PrintIRWithLIR && !TTY.isSuppressed()) {
+            if (currentInstruction != null && lastInstructionPrinted != currentInstruction) {
+                lastInstructionPrinted = currentInstruction;
+                InstructionPrinter ip = new InstructionPrinter(TTY.out());
+                ip.printInstructionListing(currentInstruction);
+            }
+            TTY.println(op.toStringWithIdPrefix());
+            TTY.println();
+        }
+        currentBlock.lir.add(op);
+    }
+
+    public void doBlock(Block block) {
+        if (GraalOptions.PrintIRWithLIR) {
+            TTY.print(block.toString());
+        }
+
+        currentBlock = block;
+        // set up the list of LIR instructions
+        assert block.lir == null : "LIR list already computed for this block";
+        block.lir = new ArrayList<>();
+
+        if (GraalOptions.AllocSSA && block.getBeginNode() instanceof MergeNode) {
+            assert phiValues.isEmpty();
+            MergeNode merge = (MergeNode) block.getBeginNode();
+            for (PhiNode phi : merge.phis()) {
+                if (phi.type() == PhiType.Value) {
+                    CiValue phiValue = newVariable(phi.kind());
+                    setResult(phi, phiValue);
+                    phiValues.add(phiValue);
+                }
+            }
+            append(new PhiLabelOp(new Label(), block.align, phiValues.toArray(new CiValue[phiValues.size()])));
+            phiValues.clear();
+        } else {
+            append(new LabelOp(new Label(), block.align));
+        }
+
+        if (GraalOptions.TraceLIRGeneratorLevel >= 1) {
+            TTY.println("BEGIN Generating LIR for block B" + block.getId());
+        }
+
+        curLocks = null;
+        for (Block pred : block.getPredecessors()) {
+            LockScope predLocks = blockLocks.get(pred);
+            if (curLocks == null) {
+                curLocks = predLocks;
+            } else if (curLocks != predLocks && (!pred.isLoopEnd() || predLocks != null)) {
+                throw new CiBailout("unbalanced monitors: predecessor blocks have different monitor states");
+            }
+        }
+
+        if (block == lir.cfg.getStartBlock()) {
+            assert block.getPredecessors().size() == 0;
+            emitPrologue();
+
+        } else {
+            assert block.getPredecessors().size() > 0;
+            FrameState fs = null;
+
+            for (Block pred : block.getPredecessors()) {
+                if (fs == null) {
+                    fs = blockLastState.get(pred);
+                } else if (fs != blockLastState.get(pred)) {
+                    fs = null;
+                    break;
+                }
+            }
+            if (GraalOptions.TraceLIRGeneratorLevel >= 2) {
+                if (fs == null) {
+                    TTY.println("STATE RESET");
+                } else {
+                    TTY.println("STATE CHANGE (singlePred)");
+                    if (GraalOptions.TraceLIRGeneratorLevel >= 3) {
+                        TTY.println(fs.toDetailedString());
+                    }
+                }
+            }
+            lastState = fs;
+        }
+
+        List<Node> nodes = lir.nodesFor(block);
+        for (int i = 0; i < nodes.size(); i++) {
+            Node instr = nodes.get(i);
+
+            if (GraalOptions.OptImplicitNullChecks) {
+                Node nextInstr = null;
+                if (i < nodes.size() - 1) {
+                    nextInstr = nodes.get(i + 1);
+                }
+
+                if (instr instanceof GuardNode) {
+                    GuardNode guardNode = (GuardNode) instr;
+                    if (guardNode.condition() instanceof NullCheckNode) {
+                        NullCheckNode nullCheckNode = (NullCheckNode) guardNode.condition();
+                        if (!nullCheckNode.expectedNull && nextInstr instanceof Access) {
+                            Access access = (Access) nextInstr;
+                            if (nullCheckNode.object() == access.object() && canBeNullCheck(access.location())) {
+                                //TTY.println("implicit null check");
+                                access.setNullCheck(true);
+                                continue;
+                            }
+                        }
+                    }
+                }
+            }
+            if (GraalOptions.TraceLIRGeneratorLevel >= 3) {
+                TTY.println("LIRGen for " + instr);
+            }
+            FrameState stateAfter = null;
+            if (instr instanceof StateSplit) {
+                stateAfter = ((StateSplit) instr).stateAfter();
+            }
+            if (instr instanceof ValueNode) {
+                try {
+                    doRoot((ValueNode) instr);
+                } catch (Throwable e) {
+                    throw new GraalInternalError(e).addContext(instr);
+                }
+            }
+            if (stateAfter != null) {
+                lastState = stateAfter;
+                assert checkStartOperands(instr, lastState);
+                assert checkStateReady(lastState);
+                if (GraalOptions.TraceLIRGeneratorLevel >= 2) {
+                    TTY.println("STATE CHANGE");
+                    if (GraalOptions.TraceLIRGeneratorLevel >= 3) {
+                        TTY.println(stateAfter.toDetailedString());
+                    }
+                }
+            }
+        }
+        if (block.numberOfSux() >= 1 && !endsWithJump(block)) {
+            NodeSuccessorsIterable successors = block.getEndNode().successors();
+            assert successors.isNotEmpty() : "should have at least one successor : " + block.getEndNode();
+
+            emitJump(getLIRBlock((FixedNode) successors.first()), null);
+        }
+
+        if (GraalOptions.TraceLIRGeneratorLevel >= 1) {
+            TTY.println("END Generating LIR for block B" + block.getId());
+        }
+
+        blockLocks.put(currentBlock, curLocks);
+        blockLastState.put(block, lastState);
+        currentBlock = null;
+
+        if (GraalOptions.PrintIRWithLIR) {
+            TTY.println();
+        }
+    }
+
+    private boolean checkStateReady(FrameState state) {
+        FrameState fs = state;
+        while (fs != null) {
+            for (int i = 0; i < fs.valuesSize(); i++) {
+                ValueNode v = fs.valueAt(i);
+                if (v != null && !(v instanceof VirtualObjectNode)) {
+                    assert operand(v) != null : "Value " + v + " in " + fs + " is not ready!";
+                }
+            }
+            fs =  fs.outerFrameState();
+        }
+        return true;
+    }
+
+    private static boolean endsWithJump(Block block) {
+        if (block.lir.size() == 0) {
+            return false;
+        }
+        LIRInstruction lirInstruction = block.lir.get(block.lir.size() - 1);
+        if (lirInstruction instanceof LIRXirInstruction) {
+            LIRXirInstruction lirXirInstruction = (LIRXirInstruction) lirInstruction;
+            return (lirXirInstruction.falseSuccessor != null) && (lirXirInstruction.trueSuccessor != null);
+        }
+        return lirInstruction instanceof StandardOp.JumpOp;
+    }
+
+    private void doRoot(ValueNode instr) {
+        if (GraalOptions.TraceLIRGeneratorLevel >= 2) {
+            TTY.println("Emitting LIR for instruction " + instr);
+        }
+        currentInstruction = instr;
+
+        Debug.log("Visiting %s", instr);
+        emitNode(instr);
+        Debug.log("Operand for %s = %s", instr, operand(instr));
+    }
+
+    protected void emitNode(ValueNode node) {
+        ((LIRLowerable) node).generate(this);
+    }
+
+    private static boolean canBeNullCheck(LocationNode location) {
+        // TODO: Make this part of CiTarget
+        return !(location instanceof IndexedLocationNode) && location.displacement() < 4096;
+    }
+
+    private void emitPrologue() {
+        CiCallingConvention incomingArguments = frameMap.registerConfig.getCallingConvention(JavaCallee, CiUtil.signatureToKinds(method), target, false);
+
+        CiValue[] params = new CiValue[incomingArguments.locations.length];
+        for (int i = 0; i < params.length; i++) {
+            params[i] = toStackKind(incomingArguments.locations[i]);
+        }
+        append(new ParametersOp(params));
+
+        XirSnippet prologue = xir.genPrologue(null, method);
+        if (prologue != null) {
+            emitXir(prologue, null, null, false);
+        }
+
+        for (LocalNode local : graph.getNodes(LocalNode.class)) {
+            CiValue param = params[local.index()];
+            assert param.kind == local.kind().stackKind();
+            setResult(local, emitMove(param));
+        }
+    }
+
+    private boolean checkStartOperands(Node node, FrameState fs) {
+        if (!Modifier.isNative(method.accessFlags())) {
+            if (node == ((StructuredGraph) node.graph()).start()) {
+                CiKind[] arguments = CiUtil.signatureToKinds(method);
+                int slot = 0;
+                for (CiKind kind : arguments) {
+                    ValueNode arg = fs.localAt(slot);
+                    assert arg != null && arg.kind() == kind.stackKind() : "No valid local in framestate for slot #" + slot + " (" + arg + ")";
+                    slot++;
+                    if (slot < fs.localsSize() && fs.localAt(slot) == null) {
+                        slot++;
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
+
+    @Override
+    public void visitArrayLength(ArrayLengthNode x) {
+        XirArgument array = toXirArgument(x.array());
+        XirSnippet snippet = xir.genArrayLength(site(x), array);
+        emitXir(snippet, x, state(), true);
+        operand(x);
+    }
+
+    @Override
+    public void visitCheckCast(CheckCastNode x) {
+        if (x.emitCode()) {
+            XirSnippet snippet = xir.genCheckCast(site(x), toXirArgument(x.object()), toXirArgument(x.targetClassInstruction()), x.targetClass(), x.hints(), x.hintsExact());
+            emitXir(snippet, x, state(), true);
+        }
+        // The result of a checkcast is the unmodified object, so no need to allocate a new variable for it.
+        setResult(x, operand(x.object()));
+    }
+
+    @Override
+    public void visitMonitorEnter(MonitorEnterNode x) {
+        CiStackSlot lockData = frameMap.allocateStackBlock(runtime.sizeOfLockData(), false);
+        if (x.eliminated()) {
+            // No code is emitted for eliminated locks, but for proper debug information generation we need to
+            // register the monitor and its lock data.
+            curLocks = new LockScope(curLocks, x.stateAfter().outerFrameState(), x, lockData);
+            return;
+        }
+
+        XirArgument obj = toXirArgument(x.object());
+        XirArgument lockAddress = lockData == null ? null : toXirArgument(emitLea(lockData));
+
+        LIRDebugInfo stateBefore = state();
+        // The state before the monitor enter is used for null checks, so it must not contain the newly locked object.
+        curLocks = new LockScope(curLocks, x.stateAfter().outerFrameState(), x, lockData);
+        // The state after the monitor enter is used for deoptimization, after the monitor has blocked, so it must contain the newly locked object.
+        LIRDebugInfo stateAfter = stateFor(x.stateAfter());
+
+        XirSnippet snippet = xir.genMonitorEnter(site(x), obj, lockAddress);
+        emitXir(snippet, x, stateBefore, stateAfter, true, null, null);
+    }
+
+    @Override
+    public void visitMonitorExit(MonitorExitNode x) {
+        if (curLocks == null || curLocks.monitor.object() != x.object() || curLocks.monitor.eliminated() != x.eliminated()) {
+            throw new CiBailout("unbalanced monitors: attempting to unlock an object that is not on top of the locking stack");
+        }
+        if (x.eliminated()) {
+            curLocks = curLocks.outer;
+            return;
+        }
+
+        CiStackSlot lockData = curLocks.lockData;
+        XirArgument obj = toXirArgument(x.object());
+        XirArgument lockAddress = lockData == null ? null : toXirArgument(emitLea(lockData));
+
+        LIRDebugInfo stateBefore = state();
+        curLocks = curLocks.outer;
+
+        XirSnippet snippet = xir.genMonitorExit(site(x), obj, lockAddress);
+        emitXir(snippet, x, stateBefore, true);
+    }
+
+    @Override
+    public void visitLoadField(LoadFieldNode x) {
+        RiField field = x.field();
+        LIRDebugInfo info = state();
+        if (x.isVolatile()) {
+            emitMembar(JMM_PRE_VOLATILE_READ);
+        }
+        XirArgument receiver = toXirArgument(x.object());
+        XirSnippet snippet = x.isStatic() ? xir.genGetStatic(site(x), receiver, field) : xir.genGetField(site(x), receiver, field);
+        emitXir(snippet, x, info, true);
+        if (x.isVolatile()) {
+            emitMembar(JMM_POST_VOLATILE_READ);
+        }
+    }
+
+    @Override
+    public void visitStoreField(StoreFieldNode x) {
+        RiField field = x.field();
+        LIRDebugInfo info = state();
+        if (x.isVolatile()) {
+            emitMembar(JMM_PRE_VOLATILE_WRITE);
+        }
+        XirArgument receiver = toXirArgument(x.object());
+        XirArgument value = toXirArgument(x.value());
+        XirSnippet snippet = x.isStatic() ? xir.genPutStatic(site(x), receiver, field, value) : xir.genPutField(site(x), receiver, field, value);
+        emitXir(snippet, x, info, true);
+        if (x.isVolatile()) {
+            emitMembar(JMM_POST_VOLATILE_WRITE);
+        }
+    }
+
+    @Override
+    public void visitLoadIndexed(LoadIndexedNode x) {
+        XirArgument array = toXirArgument(x.array());
+        XirArgument index = toXirArgument(x.index());
+        XirSnippet snippet = xir.genArrayLoad(site(x), array, index, x.elementKind(), null);
+        emitXir(snippet, x, state(), true);
+    }
+
+    @Override
+    public void visitStoreIndexed(StoreIndexedNode x) {
+        XirArgument array = toXirArgument(x.array());
+        XirArgument index = toXirArgument(x.index());
+        XirArgument value = toXirArgument(x.value());
+        XirSnippet snippet = xir.genArrayStore(site(x), array, index, value, x.elementKind(), null);
+        emitXir(snippet, x, state(), true);
+    }
+
+    @Override
+    public void visitNewInstance(NewInstanceNode x) {
+        XirSnippet snippet = xir.genNewInstance(site(x), x.instanceClass());
+        emitXir(snippet, x, state(), true);
+    }
+
+    @Override
+    public void visitNewTypeArray(NewTypeArrayNode x) {
+        XirArgument length = toXirArgument(x.length());
+        XirSnippet snippet = xir.genNewArray(site(x), length, x.elementType().kind(true), null, null);
+        emitXir(snippet, x, state(), true);
+    }
+
+    @Override
+    public void visitNewObjectArray(NewObjectArrayNode x) {
+        XirArgument length = toXirArgument(x.length());
+        XirSnippet snippet = xir.genNewArray(site(x), length, CiKind.Object, x.elementType(), x.exactType());
+        emitXir(snippet, x, state(), true);
+    }
+
+    @Override
+    public void visitNewMultiArray(NewMultiArrayNode x) {
+        XirArgument[] dims = new XirArgument[x.dimensionCount()];
+        for (int i = 0; i < dims.length; i++) {
+            dims[i] = toXirArgument(x.dimension(i));
+        }
+        XirSnippet snippet = xir.genNewMultiArray(site(x), dims, x.type());
+        emitXir(snippet, x, state(), true);
+    }
+
+    @Override
+    public void visitExceptionObject(ExceptionObjectNode x) {
+        XirSnippet snippet = xir.genExceptionObject(site(x));
+        LIRDebugInfo info = state();
+        emitXir(snippet, x, info, true);
+    }
+
+    @Override
+    public void visitReturn(ReturnNode x) {
+        CiValue operand = CiValue.IllegalValue;
+        if (!x.kind().isVoid()) {
+            operand = resultOperandFor(x.kind());
+            emitMove(operand(x.result()), operand);
+        }
+        XirSnippet epilogue = xir.genEpilogue(site(x), method);
+        if (epilogue != null) {
+            emitXir(epilogue, x, null, false);
+            emitReturn(operand);
+        }
+    }
+
+    protected abstract void emitReturn(CiValue input);
+
+    @SuppressWarnings("unused")
+    protected void postGCWriteBarrier(CiValue addr, CiValue newVal) {
+        XirSnippet writeBarrier = xir.genWriteBarrier(toXirArgument(addr));
+        if (writeBarrier != null) {
+            emitXir(writeBarrier, null, null, false);
+        }
+     }
+
+    @SuppressWarnings("unused")
+    protected void preGCWriteBarrier(CiValue addrOpr, boolean patch, LIRDebugInfo info) {
+        // TODO(tw): Implement this.
+    }
+
+
+
+    @Override
+    public void visitMerge(MergeNode x) {
+    }
+
+    @Override
+    public void visitEndNode(EndNode end) {
+        moveToPhi(end.merge(), end);
+    }
+
+    @Override
+    public void visitLoopEnd(LoopEndNode x) {
+        if (GraalOptions.GenLoopSafepoints && x.hasSafepointPolling()) {
+            emitSafepointPoll(x);
+        }
+    }
+
+    private ArrayList<CiValue> phiValues = new ArrayList<>();
+
+    private void moveToPhi(MergeNode merge, EndNode pred) {
+        if (GraalOptions.AllocSSA) {
+            assert phiValues.isEmpty();
+            for (PhiNode phi : merge.phis()) {
+                if (phi.type() == PhiType.Value) {
+                    phiValues.add(operand(phi.valueAt(pred)));
+                }
+            }
+            append(new PhiJumpOp(getLIRBlock(merge), phiValues.toArray(new CiValue[phiValues.size()])));
+            phiValues.clear();
+            return;
+        }
+
+        if (GraalOptions.TraceLIRGeneratorLevel >= 1) {
+            TTY.println("MOVE TO PHI from " + pred + " to " + merge);
+        }
+        PhiResolver resolver = new PhiResolver(this);
+        for (PhiNode phi : merge.phis()) {
+            if (phi.type() == PhiType.Value) {
+                ValueNode curVal = phi.valueAt(pred);
+                resolver.move(operand(curVal), operandForPhi(phi));
+            }
+        }
+        resolver.dispose();
+
+        append(new JumpOp(getLIRBlock(merge), null));
+    }
+
+    private CiValue operandForPhi(PhiNode phi) {
+        assert phi.type() == PhiType.Value : "wrong phi type: " + phi;
+        CiValue result = operand(phi);
+        if (result == null) {
+            // allocate a variable for this phi
+            Variable newOperand = newVariable(phi.kind());
+            setResult(phi, newOperand);
+            return newOperand;
+        } else {
+            return result;
+        }
+    }
+
+
+    public void emitSafepointPoll(FixedNode x) {
+        if (!lastState.method().noSafepointPolls()) {
+            XirSnippet snippet = xir.genSafepointPoll(site(x));
+            emitXir(snippet, x, state(), false);
+        }
+    }
+
+    @Override
+    public void emitIf(IfNode x) {
+        assert x.defaultSuccessor() == x.falseSuccessor() : "wrong destination";
+        emitBranch(x.compare(), getLIRBlock(x.trueSuccessor()),  getLIRBlock(x.falseSuccessor()), null);
+    }
+
+    @Override
+    public void emitGuardCheck(BooleanNode comp) {
+        if (comp instanceof NullCheckNode && !((NullCheckNode) comp).expectedNull) {
+            emitNullCheckGuard((NullCheckNode) comp);
+        } else if (comp instanceof ConstantNode && comp.asConstant().asBoolean()) {
+            // True constant, nothing to emit.
+        } else {
+            // Fall back to a normal branch.
+            LIRDebugInfo info = state();
+            LabelRef stubEntry = createDeoptStub(DeoptAction.InvalidateReprofile, info, comp);
+            emitBranch(comp, null, stubEntry, info);
+        }
+    }
+
+    protected abstract void emitNullCheckGuard(NullCheckNode node);
+
+    public void emitBranch(BooleanNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRDebugInfo info) {
+        if (node instanceof NullCheckNode) {
+            emitNullCheckBranch((NullCheckNode) node, trueSuccessor, falseSuccessor, info);
+        } else if (node instanceof CompareNode) {
+            emitCompareBranch((CompareNode) node, trueSuccessor, falseSuccessor, info);
+        } else if (node instanceof InstanceOfNode) {
+            emitInstanceOfBranch((InstanceOfNode) node, trueSuccessor, falseSuccessor, info);
+        } else if (node instanceof ConstantNode) {
+            emitConstantBranch(((ConstantNode) node).asConstant().asBoolean(), trueSuccessor, falseSuccessor, info);
+        } else if (node instanceof IsTypeNode) {
+            emitTypeBranch((IsTypeNode) node, trueSuccessor, falseSuccessor, info);
+        } else {
+            throw GraalInternalError.unimplemented(node.toString());
+        }
+    }
+
+    private void emitNullCheckBranch(NullCheckNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRDebugInfo info) {
+        Condition cond = node.expectedNull ? Condition.NE : Condition.EQ;
+        emitBranch(operand(node.object()), CiConstant.NULL_OBJECT, cond, false, falseSuccessor, info);
+        if (trueSuccessor != null) {
+            emitJump(trueSuccessor, null);
+        }
+    }
+
+    public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessorBlock, LabelRef falseSuccessorBlock, LIRDebugInfo info) {
+        emitBranch(operand(compare.x()), operand(compare.y()), compare.condition().negate(), !compare.unorderedIsTrue(), falseSuccessorBlock, info);
+        if (trueSuccessorBlock != null) {
+            emitJump(trueSuccessorBlock, null);
+        }
+    }
+
+    private void emitInstanceOfBranch(InstanceOfNode x, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRDebugInfo info) {
+        XirArgument obj = toXirArgument(x.object());
+        XirSnippet snippet = xir.genInstanceOf(site(x), obj, toXirArgument(x.targetClassInstruction()), x.targetClass(), x.hints(), x.hintsExact());
+        emitXir(snippet, x, info, null, false, x.negated() ? falseSuccessor : trueSuccessor, x.negated() ? trueSuccessor : falseSuccessor);
+    }
+
+    public void emitConstantBranch(boolean value, LabelRef trueSuccessorBlock, LabelRef falseSuccessorBlock, LIRDebugInfo info) {
+        LabelRef block = value ? trueSuccessorBlock : falseSuccessorBlock;
+        if (block != null) {
+            emitJump(block, info);
+        }
+    }
+
+    public void emitTypeBranch(IsTypeNode x, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRDebugInfo info) {
+        XirArgument thisClass = toXirArgument(x.objectClass());
+        XirArgument otherClass = toXirArgument(x.type().getEncoding(Representation.ObjectHub));
+        XirSnippet snippet = xir.genTypeBranch(site(x), thisClass, otherClass, x.type());
+        emitXir(snippet, x, info, null, false, trueSuccessor, falseSuccessor);
+        if (trueSuccessor != null) {
+            emitJump(trueSuccessor, null);
+        }
+    }
+
+    @Override
+    public void emitConditional(ConditionalNode conditional) {
+        CiValue tVal = operand(conditional.trueValue());
+        CiValue fVal = operand(conditional.falseValue());
+        setResult(conditional, emitConditional(conditional.condition(), tVal, fVal));
+    }
+
+    public Variable emitConditional(BooleanNode node, CiValue trueValue, CiValue falseValue) {
+        if (node instanceof NullCheckNode) {
+            return emitNullCheckConditional((NullCheckNode) node, trueValue, falseValue);
+        } else if (node instanceof CompareNode) {
+            return emitCompareConditional((CompareNode) node, trueValue, falseValue);
+        } else if (node instanceof InstanceOfNode) {
+            return emitInstanceOfConditional((InstanceOfNode) node, trueValue, falseValue);
+        } else if (node instanceof ConstantNode) {
+            return emitConstantConditional(((ConstantNode) node).asConstant().asBoolean(), trueValue, falseValue);
+        } else {
+            throw GraalInternalError.unimplemented(node.toString());
+        }
+    }
+
+    private Variable emitNullCheckConditional(NullCheckNode node, CiValue trueValue, CiValue falseValue) {
+        Condition cond = node.expectedNull ? Condition.EQ : Condition.NE;
+        return emitCMove(operand(node.object()), CiConstant.NULL_OBJECT, cond, false, trueValue, falseValue);
+    }
+
+    private Variable emitInstanceOfConditional(InstanceOfNode x, CiValue trueValue, CiValue falseValue) {
+        XirArgument obj = toXirArgument(x.object());
+        XirArgument trueArg = toXirArgument(x.negated() ? falseValue : trueValue);
+        XirArgument falseArg = toXirArgument(x.negated() ? trueValue : falseValue);
+        XirSnippet snippet = xir.genMaterializeInstanceOf(site(x), obj, toXirArgument(x.targetClassInstruction()), trueArg, falseArg, x.targetClass(), x.hints(), x.hintsExact());
+        return (Variable) emitXir(snippet, null, null, false);
+    }
+
+    private Variable emitConstantConditional(boolean value, CiValue trueValue, CiValue falseValue) {
+        return emitMove(value ? trueValue : falseValue);
+    }
+
+    private Variable emitCompareConditional(CompareNode compare, CiValue trueValue, CiValue falseValue) {
+        return emitCMove(operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueValue, falseValue);
+    }
+
+
+    public abstract void emitLabel(Label label, boolean align);
+    public abstract void emitJump(LabelRef label, LIRDebugInfo info);
+    public abstract void emitBranch(CiValue left, CiValue right, Condition cond, boolean unorderedIsTrue, LabelRef label, LIRDebugInfo info);
+    public abstract Variable emitCMove(CiValue leftVal, CiValue right, Condition cond, boolean unorderedIsTrue, CiValue trueValue, CiValue falseValue);
+
+    protected FrameState stateBeforeCallWithArguments(FrameState stateAfter, MethodCallTargetNode call, int bci) {
+        return stateAfter.duplicateModified(bci, stateAfter.rethrowException(), call.returnKind(), toJVMArgumentStack(call.targetMethod().signature(), call.isStatic(), call.arguments()));
+    }
+
+    private static ValueNode[] toJVMArgumentStack(RiSignature signature, boolean isStatic, NodeInputList<ValueNode> arguments) {
+        int slotCount = signature.argumentSlots(!isStatic);
+        ValueNode[] stack = new ValueNode[slotCount];
+        int stackIndex = 0;
+        int argumentIndex = 0;
+        for (ValueNode arg : arguments) {
+            stack[stackIndex] = arg;
+
+            if (stackIndex == 0 && !isStatic) {
+                // Current argument is receiver.
+                stackIndex += stackSlots(CiKind.Object);
+            } else {
+                stackIndex += stackSlots(signature.argumentKindAt(argumentIndex, false));
+                argumentIndex++;
+            }
+        }
+        return stack;
+    }
+
+
+    public static int stackSlots(CiKind kind) {
+        return isTwoSlot(kind) ? 2 : 1;
+    }
+
+    public static boolean isTwoSlot(CiKind kind) {
+        assert kind != CiKind.Void && kind != CiKind.Illegal;
+        return kind == CiKind.Long || kind == CiKind.Double;
+    }
+
+    @Override
+    public void emitInvoke(Invoke x) {
+        MethodCallTargetNode callTarget = x.callTarget();
+        RiMethod targetMethod = callTarget.targetMethod();
+
+        XirSnippet snippet = null;
+        XirArgument receiver;
+        switch (callTarget.invokeKind()) {
+            case Static:
+                snippet = xir.genInvokeStatic(site(x.node()), targetMethod);
+                break;
+            case Special:
+                receiver = toXirArgument(callTarget.receiver());
+                snippet = xir.genInvokeSpecial(site(x.node()), receiver, targetMethod);
+                break;
+            case Virtual:
+                assert callTarget.receiver().kind() == CiKind.Object : callTarget + ": " + callTarget.targetMethod().toString();
+                receiver = toXirArgument(callTarget.receiver());
+                snippet = xir.genInvokeVirtual(site(x.node()), receiver, targetMethod);
+                break;
+            case Interface:
+                assert callTarget.receiver().kind() == CiKind.Object : callTarget;
+                receiver = toXirArgument(callTarget.receiver());
+                snippet = xir.genInvokeInterface(site(x.node()), receiver, targetMethod);
+                break;
+        }
+
+        CiValue destinationAddress = null;
+        if (!target().invokeSnippetAfterArguments) {
+            // TODO This is the version currently necessary for Maxine: since the invokeinterface-snippet uses a division, it
+            // destroys rdx, which is also used to pass a parameter.  Therefore, the snippet must be before the parameters are assigned to their locations.
+            LIRDebugInfo addrInfo = stateFor(stateBeforeCallWithArguments(x.stateAfter(), callTarget, x.bci()));
+            destinationAddress = emitXir(snippet, x.node(), addrInfo, false);
+        }
+
+        CiValue resultOperand = resultOperandFor(x.node().kind());
+
+        CiKind[] signature = CiUtil.signatureToKinds(callTarget.targetMethod().signature(), callTarget.isStatic() ? null : callTarget.targetMethod().holder().kind(true));
+        CiCallingConvention cc = frameMap.registerConfig.getCallingConvention(JavaCall, signature, target(), false);
+        frameMap.callsMethod(cc, JavaCall);
+        List<CiValue> argList = visitInvokeArguments(cc, callTarget.arguments());
+
+        if (target().invokeSnippetAfterArguments) {
+            // TODO This is the version currently active for HotSpot.
+            LIRDebugInfo addrInfo = stateFor(stateBeforeCallWithArguments(x.stateAfter(), callTarget, x.bci()), null, null);
+            destinationAddress = emitXir(snippet, x.node(), addrInfo, false);
+        }
+
+        LIRDebugInfo callInfo = stateFor(x.stateDuring(), null, x instanceof InvokeWithExceptionNode ? getLIRBlock(((InvokeWithExceptionNode) x).exceptionEdge()) : null);
+        emitCall(targetMethod, resultOperand, argList, destinationAddress, callInfo, snippet.marks);
+
+        if (isLegal(resultOperand)) {
+            setResult(x.node(), emitMove(resultOperand));
+        }
+    }
+
+    protected abstract void emitCall(Object targetMethod, CiValue result, List<CiValue> arguments, CiValue targetAddress, LIRDebugInfo info, Map<XirMark, Mark> marks);
+
+
+    private static CiValue toStackKind(CiValue value) {
+        if (value.kind.stackKind() != value.kind) {
+            // We only have stack-kinds in the LIR, so convert the operand kind for values from the calling convention.
+            if (isRegister(value)) {
+                return asRegister(value).asValue(value.kind.stackKind());
+            } else if (isStackSlot(value)) {
+                return CiStackSlot.get(value.kind.stackKind(), asStackSlot(value).rawOffset(), asStackSlot(value).rawAddFrameSize());
+            } else {
+                throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+        return value;
+    }
+
+    public List<CiValue> visitInvokeArguments(CiCallingConvention cc, Iterable<ValueNode> arguments) {
+        // for each argument, load it into the correct location
+        List<CiValue> argList = new ArrayList<>();
+        int j = 0;
+        for (ValueNode arg : arguments) {
+            if (arg != null) {
+                CiValue operand = toStackKind(cc.locations[j++]);
+                emitMove(operand(arg), operand);
+                argList.add(operand);
+
+            } else {
+                throw GraalInternalError.shouldNotReachHere("I thought we no longer have null entries for two-slot types...");
+            }
+        }
+        return argList;
+    }
+
+
+    protected abstract LabelRef createDeoptStub(DeoptAction action, LIRDebugInfo info, Object deoptInfo);
+
+    @Override
+    public Variable emitCallToRuntime(CiRuntimeCall runtimeCall, boolean canTrap, CiValue... args) {
+        LIRDebugInfo info = canTrap ? state() : null;
+
+        CiKind result = runtimeCall.resultKind;
+        CiKind[] arguments = runtimeCall.arguments;
+        CiValue physReg = resultOperandFor(result);
+
+        List<CiValue> argumentList;
+        if (arguments.length > 0) {
+            // move the arguments into the correct location
+            CiCallingConvention cc = frameMap.registerConfig.getCallingConvention(RuntimeCall, arguments, target(), false);
+            frameMap.callsMethod(cc, RuntimeCall);
+            assert cc.locations.length == args.length : "argument count mismatch";
+            for (int i = 0; i < args.length; i++) {
+                CiValue arg = args[i];
+                CiValue loc = cc.locations[i];
+                emitMove(arg, loc);
+            }
+            argumentList = Arrays.asList(cc.locations);
+        } else {
+            // no arguments
+            assert args == null || args.length == 0;
+            argumentList = Collections.emptyList();
+        }
+
+        emitCall(runtimeCall, physReg, argumentList, CiConstant.forLong(0), info, null);
+
+        if (isLegal(physReg)) {
+            return emitMove(physReg);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public void emitRuntimeCall(RuntimeCallNode x) {
+        // TODO Merge with emitCallToRuntime() method above.
+
+        CiValue resultOperand = resultOperandFor(x.kind());
+        CiCallingConvention cc = frameMap.registerConfig.getCallingConvention(RuntimeCall, x.call().arguments, target(), false);
+        frameMap.callsMethod(cc, RuntimeCall);
+        List<CiValue> argList = visitInvokeArguments(cc, x.arguments());
+
+        LIRDebugInfo info = null;
+        FrameState stateAfter = x.stateAfter();
+        if (stateAfter != null) {
+            // TODO change back to stateBeforeReturn() when RuntimeCallNode uses a CallTargetNode
+            FrameState stateBeforeReturn = stateAfter.duplicateModified(stateAfter.bci, stateAfter.rethrowException(), x.kind());
+
+            // TODO is it correct here that the pointerSlots are not passed to the oop map generation?
+            info = stateFor(stateBeforeReturn);
+        }
+
+        emitCall(x.call(), resultOperand, argList, CiConstant.forLong(0), info, null);
+
+        if (isLegal(resultOperand)) {
+            setResult(x, emitMove(resultOperand));
+        }
+    }
+
+    @Override
+    public void emitLookupSwitch(LookupSwitchNode x) {
+        Variable tag = load(operand(x.value()));
+        if (x.numberOfCases() == 0 || x.numberOfCases() < GraalOptions.SequentialSwitchLimit) {
+            int len = x.numberOfCases();
+            for (int i = 0; i < len; i++) {
+                emitBranch(tag, CiConstant.forInt(x.keyAt(i)), Condition.EQ, false, getLIRBlock(x.blockSuccessor(i)), null);
+            }
+            emitJump(getLIRBlock(x.defaultSuccessor()), null);
+        } else {
+            visitSwitchRanges(createSwitchRanges(x, null), tag, getLIRBlock(x.defaultSuccessor()));
+        }
+    }
+
+    @Override
+    public void emitTableSwitch(TableSwitchNode x) {
+        Variable value = load(operand(x.value()));
+        // TODO: tune the defaults for the controls used to determine what kind of translation to use
+        if (x.numberOfCases() == 0 || x.numberOfCases() <= GraalOptions.SequentialSwitchLimit) {
+            int loKey = x.lowKey();
+            int len = x.numberOfCases();
+            for (int i = 0; i < len; i++) {
+                emitBranch(value, CiConstant.forInt(i + loKey), Condition.EQ, false, getLIRBlock(x.blockSuccessor(i)), null);
+            }
+            emitJump(getLIRBlock(x.defaultSuccessor()), null);
+        } else {
+            SwitchRange[] switchRanges = createSwitchRanges(null, x);
+            int rangeDensity = x.numberOfCases() / switchRanges.length;
+            if (rangeDensity >= GraalOptions.RangeTestsSwitchDensity) {
+                visitSwitchRanges(switchRanges, value, getLIRBlock(x.defaultSuccessor()));
+            } else {
+                LabelRef[] targets = new LabelRef[x.numberOfCases()];
+                for (int i = 0; i < x.numberOfCases(); ++i) {
+                    targets[i] = getLIRBlock(x.blockSuccessor(i));
+                }
+                emitTableSwitch(x.lowKey(), getLIRBlock(x.defaultSuccessor()), targets, value);
+            }
+        }
+    }
+
+    protected abstract void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, CiValue index);
+
+    // the range of values in a lookupswitch or tableswitch statement
+    private static final class SwitchRange {
+        protected final int lowKey;
+        protected int highKey;
+        protected final LabelRef sux;
+
+        SwitchRange(int lowKey, LabelRef sux) {
+            this.lowKey = lowKey;
+            this.highKey = lowKey;
+            this.sux = sux;
+        }
+    }
+
+    private SwitchRange[] createSwitchRanges(LookupSwitchNode ls, TableSwitchNode ts) {
+        // Only one of the parameters is used, but code is shared because it is mostly the same.
+        SwitchNode x = ls != null ? ls : ts;
+        // we expect the keys to be sorted by increasing value
+        List<SwitchRange> res = new ArrayList<>(x.numberOfCases());
+        int len = x.numberOfCases();
+        if (len > 0) {
+            LabelRef defaultSux = getLIRBlock(x.defaultSuccessor());
+            int key = ls != null ? ls.keyAt(0) : ts.lowKey();
+            LabelRef sux = getLIRBlock(x.blockSuccessor(0));
+            SwitchRange range = new SwitchRange(key, sux);
+            for (int i = 1; i < len; i++) {
+                int newKey = ls != null ? ls.keyAt(i) : key + 1;
+                LabelRef newSux = getLIRBlock(x.blockSuccessor(i));
+                if (key + 1 == newKey && sux == newSux) {
+                    // still in same range
+                    range.highKey = newKey;
+                } else {
+                    // skip tests which explicitly dispatch to the default
+                    if (range.sux != defaultSux) {
+                        res.add(range);
+                    }
+                    range = new SwitchRange(newKey, newSux);
+                }
+                key = newKey;
+                sux = newSux;
+            }
+            if (res.size() == 0 || res.get(res.size() - 1) != range) {
+                res.add(range);
+            }
+        }
+        return res.toArray(new SwitchRange[res.size()]);
+    }
+
+    private void visitSwitchRanges(SwitchRange[] x, Variable value, LabelRef defaultSux) {
+        for (int i = 0; i < x.length; i++) {
+            SwitchRange oneRange = x[i];
+            int lowKey = oneRange.lowKey;
+            int highKey = oneRange.highKey;
+            LabelRef dest = oneRange.sux;
+            if (lowKey == highKey) {
+                emitBranch(value, CiConstant.forInt(lowKey), Condition.EQ, false, dest, null);
+            } else if (highKey - lowKey == 1) {
+                emitBranch(value, CiConstant.forInt(lowKey), Condition.EQ, false, dest, null);
+                emitBranch(value, CiConstant.forInt(highKey), Condition.EQ, false, dest, null);
+            } else {
+                Label l = new Label();
+                emitBranch(value, CiConstant.forInt(lowKey), Condition.LT, false, LabelRef.forLabel(l), null);
+                emitBranch(value, CiConstant.forInt(highKey), Condition.LE, false, dest, null);
+                emitLabel(l, false);
+            }
+        }
+        emitJump(defaultSux, null);
+    }
+
+
+    protected XirArgument toXirArgument(CiValue v) {
+        if (v == null) {
+            return null;
+        }
+        return XirArgument.forInternalObject(v);
+    }
+
+    protected XirArgument toXirArgument(ValueNode i) {
+        if (i == null) {
+            return null;
+        }
+        return XirArgument.forInternalObject(loadNonConst(operand(i)));
+    }
+
+    private CiValue allocateOperand(XirSnippet snippet, XirOperand op) {
+        if (op instanceof XirParameter)  {
+            XirParameter param = (XirParameter) op;
+            return allocateOperand(snippet.arguments[param.parameterIndex], op, param.canBeConstant);
+        } else if (op instanceof XirRegister) {
+            XirRegister reg = (XirRegister) op;
+            return reg.register;
+        } else if (op instanceof XirTemp) {
+            return newVariable(op.kind);
+        } else {
+            GraalInternalError.shouldNotReachHere();
+            return null;
+        }
+    }
+
+    private CiValue allocateOperand(XirArgument arg, XirOperand var, boolean canBeConstant) {
+        if (arg.constant != null) {
+            return arg.constant;
+        }
+
+        CiValue value = (CiValue) arg.object;
+        if (canBeConstant) {
+            return value;
+        }
+        Variable variable = load(value);
+        if (var.kind == CiKind.Byte || var.kind == CiKind.Boolean) {
+            Variable tempVar = new Variable(value.kind, lir.nextVariable(), CiRegister.RegisterFlag.Byte);
+            emitMove(variable, tempVar);
+            variable = tempVar;
+        }
+        return variable;
+    }
+
+    protected CiValue emitXir(XirSnippet snippet, ValueNode x, LIRDebugInfo info, boolean setInstructionResult) {
+        return emitXir(snippet, x, info, null, setInstructionResult, null, null);
+    }
+
+    protected CiValue emitXir(XirSnippet snippet, ValueNode instruction, LIRDebugInfo info, LIRDebugInfo infoAfter, boolean setInstructionResult, LabelRef trueSuccessor, LabelRef falseSuccessor) {
+        if (GraalOptions.PrintXirTemplates) {
+            TTY.println("Emit XIR template " + snippet.template.name);
+        }
+
+        final CiValue[] operandsArray = new CiValue[snippet.template.variableCount];
+
+        frameMap.reserveOutgoing(snippet.template.outgoingStackSize);
+
+        XirOperand resultOperand = snippet.template.resultOperand;
+
+        if (snippet.template.allocateResultOperand) {
+            CiValue outputOperand = IllegalValue;
+            // This snippet has a result that must be separately allocated
+            // Otherwise it is assumed that the result is part of the inputs
+            if (resultOperand.kind != CiKind.Void && resultOperand.kind != CiKind.Illegal) {
+                if (setInstructionResult) {
+                    outputOperand = newVariable(instruction.kind());
+                } else {
+                    outputOperand = newVariable(resultOperand.kind);
+                }
+                assert operandsArray[resultOperand.index] == null;
+            }
+            operandsArray[resultOperand.index] = outputOperand;
+            if (GraalOptions.PrintXirTemplates) {
+                TTY.println("Output operand: " + outputOperand);
+            }
+        }
+
+        for (XirTemp t : snippet.template.temps) {
+            if (t instanceof XirRegister) {
+                XirRegister reg = (XirRegister) t;
+                if (!t.reserve) {
+                    operandsArray[t.index] = reg.register;
+                }
+            }
+        }
+
+        for (XirConstant c : snippet.template.constants) {
+            assert operandsArray[c.index] == null;
+            operandsArray[c.index] = c.value;
+        }
+
+        XirOperand[] inputOperands = snippet.template.inputOperands;
+        XirOperand[] inputTempOperands = snippet.template.inputTempOperands;
+        XirOperand[] tempOperands = snippet.template.tempOperands;
+
+        CiValue[] inputOperandArray = new CiValue[inputOperands.length + inputTempOperands.length];
+        CiValue[] tempOperandArray = new CiValue[tempOperands.length];
+        int[] inputOperandIndicesArray = new int[inputOperands.length + inputTempOperands.length];
+        int[] tempOperandIndicesArray = new int[tempOperands.length];
+        for (int i = 0; i < inputOperands.length; i++) {
+            XirOperand x = inputOperands[i];
+            CiValue op = allocateOperand(snippet, x);
+            operandsArray[x.index] = op;
+            inputOperandArray[i] = op;
+            inputOperandIndicesArray[i] = x.index;
+            if (GraalOptions.PrintXirTemplates) {
+                TTY.println("Input operand: " + x);
+            }
+        }
+
+        assert inputTempOperands.length == 0 : "cwi: I think this code is never used.  If you see this exception being thrown, please tell me...";
+
+        for (int i = 0; i < tempOperands.length; i++) {
+            XirOperand x = tempOperands[i];
+            CiValue op = allocateOperand(snippet, x);
+            operandsArray[x.index] = op;
+            tempOperandArray[i] = op;
+            tempOperandIndicesArray[i] = x.index;
+            if (GraalOptions.PrintXirTemplates) {
+                TTY.println("Temp operand: " + x);
+            }
+        }
+
+        for (CiValue operand : operandsArray) {
+            assert operand != null;
+        }
+
+        CiValue allocatedResultOperand = operandsArray[resultOperand.index];
+        if (!isVariable(allocatedResultOperand) && !isRegister(allocatedResultOperand)) {
+            allocatedResultOperand = IllegalValue;
+        }
+
+        if (setInstructionResult && isLegal(allocatedResultOperand)) {
+            CiValue operand = operand(instruction);
+            if (operand == null) {
+                setResult(instruction, allocatedResultOperand);
+            } else {
+                assert operand == allocatedResultOperand;
+            }
+        }
+
+
+        XirInstruction[] slowPath = snippet.template.slowPath;
+        if (!isConstant(operandsArray[resultOperand.index]) || snippet.template.fastPath.length != 0 || (slowPath != null && slowPath.length > 0)) {
+            // XIR instruction is only needed when the operand is not a constant!
+            emitXir(snippet, operandsArray, allocatedResultOperand,
+                    inputOperandArray, tempOperandArray, inputOperandIndicesArray, tempOperandIndicesArray,
+                    (allocatedResultOperand == IllegalValue) ? -1 : resultOperand.index,
+                    info, infoAfter, trueSuccessor, falseSuccessor);
+            Debug.metric("LIRXIRInstructions").increment();
+        }
+
+        return operandsArray[resultOperand.index];
+    }
+
+    protected abstract void emitXir(XirSnippet snippet, CiValue[] operands, CiValue outputOperand, CiValue[] inputs, CiValue[] temps, int[] inputOperandIndices, int[] tempOperandIndices, int outputOperandIndex,
+                    LIRDebugInfo info, LIRDebugInfo infoAfter, LabelRef trueSuccessor, LabelRef falseSuccessor);
+
+    protected final CiValue callRuntime(CiRuntimeCall runtimeCall, LIRDebugInfo info, CiValue... args) {
+        // get a result register
+        CiKind result = runtimeCall.resultKind;
+        CiKind[] arguments = runtimeCall.arguments;
+
+        CiValue physReg = result.isVoid() ? IllegalValue : resultOperandFor(result);
+
+        List<CiValue> argumentList;
+        if (arguments.length > 0) {
+            // move the arguments into the correct location
+            CiCallingConvention cc = frameMap.registerConfig.getCallingConvention(RuntimeCall, arguments, target(), false);
+            frameMap.callsMethod(cc, RuntimeCall);
+            assert cc.locations.length == args.length : "argument count mismatch";
+            for (int i = 0; i < args.length; i++) {
+                CiValue arg = args[i];
+                CiValue loc = cc.locations[i];
+                emitMove(arg, loc);
+            }
+            argumentList = Arrays.asList(cc.locations);
+        } else {
+            // no arguments
+            assert args == null || args.length == 0;
+            argumentList = Util.uncheckedCast(Collections.emptyList());
+        }
+
+        emitCall(runtimeCall, physReg, argumentList, CiConstant.forLong(0), info, null);
+
+        return physReg;
+    }
+
+    protected final Variable callRuntimeWithResult(CiRuntimeCall runtimeCall, LIRDebugInfo info, CiValue... args) {
+        CiValue location = callRuntime(runtimeCall, info, args);
+        return emitMove(location);
+    }
+
+    SwitchRange[] createLookupRanges(LookupSwitchNode x) {
+        // we expect the keys to be sorted by increasing value
+        List<SwitchRange> res = new ArrayList<>(x.numberOfCases());
+        int len = x.numberOfCases();
+        if (len > 0) {
+            LabelRef defaultSux = getLIRBlock(x.defaultSuccessor());
+            int key = x.keyAt(0);
+            LabelRef sux = getLIRBlock(x.blockSuccessor(0));
+            SwitchRange range = new SwitchRange(key, sux);
+            for (int i = 1; i < len; i++) {
+                int newKey = x.keyAt(i);
+                LabelRef newSux = getLIRBlock(x.blockSuccessor(i));
+                if (key + 1 == newKey && sux == newSux) {
+                    // still in same range
+                    range.highKey = newKey;
+                } else {
+                    // skip tests which explicitly dispatch to the default
+                    if (range.sux != defaultSux) {
+                        res.add(range);
+                    }
+                    range = new SwitchRange(newKey, newSux);
+                }
+                key = newKey;
+                sux = newSux;
+            }
+            if (res.size() == 0 || res.get(res.size() - 1) != range) {
+                res.add(range);
+            }
+        }
+        return res.toArray(new SwitchRange[res.size()]);
+    }
+
+    SwitchRange[] createLookupRanges(TableSwitchNode x) {
+        // TODO: try to merge this with the code for LookupSwitch
+        List<SwitchRange> res = new ArrayList<>(x.numberOfCases());
+        int len = x.numberOfCases();
+        if (len > 0) {
+            LabelRef sux = getLIRBlock(x.blockSuccessor(0));
+            int key = x.lowKey();
+            LabelRef defaultSux = getLIRBlock(x.defaultSuccessor());
+            SwitchRange range = new SwitchRange(key, sux);
+            for (int i = 0; i < len; i++, key++) {
+                LabelRef newSux = getLIRBlock(x.blockSuccessor(i));
+                if (sux == newSux) {
+                    // still in same range
+                    range.highKey = key;
+                } else {
+                    // skip tests which explicitly dispatch to the default
+                    if (sux != defaultSux) {
+                        res.add(range);
+                    }
+                    range = new SwitchRange(key, newSux);
+                }
+                sux = newSux;
+            }
+            if (res.size() == 0 || res.get(res.size() - 1) != range) {
+                res.add(range);
+            }
+        }
+        return res.toArray(new SwitchRange[res.size()]);
+    }
+
+    protected XirSupport site(ValueNode x) {
+        return xirSupport.site(x);
+    }
+
+    /**
+     * Implements site-specific information for the XIR interface.
+     */
+    static class XirSupport implements XirSite {
+        ValueNode current;
+
+        XirSupport() {
+        }
+
+        public CiCodePos getCodePos() {
+            if (current instanceof StateSplit) {
+                FrameState stateAfter = ((StateSplit) current).stateAfter();
+                if (stateAfter != null) {
+                    return stateAfter.toCodePos();
+                }
+            }
+            return null;
+        }
+
+        public boolean isNonNull(XirArgument argument) {
+            return false;
+        }
+
+        public boolean requiresNullCheck() {
+            return current == null || true;
+        }
+
+        public boolean requiresBoundsCheck() {
+            return true;
+        }
+
+        public boolean requiresReadBarrier() {
+            return current == null || true;
+        }
+
+        public boolean requiresWriteBarrier() {
+            return current == null || true;
+        }
+
+        public boolean requiresArrayStoreCheck() {
+            return true;
+        }
+
+        public RiType getApproximateType(XirArgument argument) {
+            return current == null ? null : current.declaredType();
+        }
+
+        public RiType getExactType(XirArgument argument) {
+            return current == null ? null : current.exactType();
+        }
+
+        XirSupport site(ValueNode v) {
+            current = v;
+            return this;
+        }
+
+        @Override
+        public String toString() {
+            return "XirSupport<" + current + ">";
+        }
+    }
+
+    public FrameMap frameMap() {
+        return frameMap;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/PhiResolver.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.compiler.gen;
+
+import static com.oracle.max.cri.ci.CiValue.*;
+import static com.oracle.max.graal.lir.ValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+
+/**
+ * Converts {@link PhiNode} instructions into moves.
+ *
+ * Resolves cycles:
+ * <pre>
+ *
+ *  r1 := r2  becomes  temp := r1
+ *  r2 := r1           r1 := r2
+ *                     r2 := temp
+ * </pre>
+ *
+ * and orders moves:
+ *
+ * <pre>
+ *  r2 := r3  becomes  r1 := r2
+ *  r1 := r2           r2 := r3
+ * </pre>
+ */
+public class PhiResolver {
+
+    /**
+     * Tracks a data flow dependency between a source operand and any number of the destination operands.
+     */
+    static class PhiResolverNode {
+
+        /**
+         * A source operand whose value flows into the {@linkplain #destinations destination} operands.
+         */
+        final CiValue operand;
+
+        /**
+         * The operands whose values are defined by the {@linkplain #operand source} operand.
+         */
+        final ArrayList<PhiResolverNode> destinations;
+
+        /**
+         * Denotes if a move instruction has already been emitted to initialize the value of {@link #operand}.
+         */
+        boolean assigned;
+
+        /**
+         * Specifies if this operand been visited for the purpose of emitting a move instruction.
+         */
+        boolean visited;
+
+        /**
+         * Specifies if this is the initial definition in data flow path for a given value.
+         */
+        boolean startNode;
+
+        PhiResolverNode(CiValue operand) {
+            this.operand = operand;
+            destinations = new ArrayList<>(4);
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder buf = new StringBuilder(operand.toString());
+            if (!destinations.isEmpty()) {
+                buf.append(" ->");
+                for (PhiResolverNode node : destinations) {
+                    buf.append(' ').append(node.operand);
+                }
+            }
+            return buf.toString();
+        }
+    }
+
+    private final LIRGenerator gen;
+
+    /**
+     * The operand loop header phi for the operand currently being process in {@link #dispose()}.
+     */
+    private PhiResolverNode loop;
+
+    private CiValue temp;
+
+    private final ArrayList<PhiResolverNode> variableOperands = new ArrayList<>(3);
+    private final ArrayList<PhiResolverNode> otherOperands = new ArrayList<>(3);
+
+    /**
+     * Maps operands to nodes.
+     */
+    private final HashMap<CiValue, PhiResolverNode> operandToNodeMap = new HashMap<>();
+
+    public PhiResolver(LIRGenerator gen) {
+        this.gen = gen;
+        temp = IllegalValue;
+    }
+
+    public void dispose() {
+        // resolve any cycles in moves from and to variables
+        for (int i = variableOperands.size() - 1; i >= 0; i--) {
+            PhiResolverNode node = variableOperands.get(i);
+            if (!node.visited) {
+                loop = null;
+                move(null, node);
+                node.startNode = true;
+                assert isIllegal(temp) : "moveTempTo() call missing";
+            }
+        }
+
+        // generate move for move from non variable to arbitrary destination
+        for (int i = otherOperands.size() - 1; i >= 0; i--) {
+            PhiResolverNode node = otherOperands.get(i);
+            for (int j = node.destinations.size() - 1; j >= 0; j--) {
+                emitMove(node.operand, node.destinations.get(j).operand);
+            }
+        }
+    }
+
+    public void move(CiValue src, CiValue dest) {
+        assert isVariable(dest) : "destination must be virtual";
+        // tty.print("move "); src.print(); tty.print(" to "); dest.print(); tty.cr();
+        assert isLegal(src) : "source for phi move is illegal";
+        assert isLegal(dest) : "destination for phi move is illegal";
+        PhiResolverNode srcNode = sourceNode(src);
+        PhiResolverNode destNode = destinationNode(dest);
+        srcNode.destinations.add(destNode);
+      }
+
+    private PhiResolverNode createNode(CiValue operand, boolean source) {
+        PhiResolverNode node;
+        if (isVariable(operand)) {
+            node = operandToNodeMap.get(operand);
+            assert node == null || node.operand.equals(operand);
+            if (node == null) {
+                node = new PhiResolverNode(operand);
+                operandToNodeMap.put(operand, node);
+            }
+            // Make sure that all variables show up in the list when
+            // they are used as the source of a move.
+            if (source) {
+                if (!variableOperands.contains(node)) {
+                    variableOperands.add(node);
+                }
+            }
+        } else {
+            assert source;
+            node = new PhiResolverNode(operand);
+            otherOperands.add(node);
+        }
+        return node;
+    }
+
+    private PhiResolverNode destinationNode(CiValue opr) {
+        return createNode(opr, false);
+    }
+
+    private void emitMove(CiValue src, CiValue dest) {
+        assert isLegal(src);
+        assert isLegal(dest);
+        gen.emitMove(src, dest);
+    }
+
+    // Traverse assignment graph in depth first order and generate moves in post order
+    // ie. two assignments: b := c, a := b start with node c:
+    // Call graph: move(NULL, c) -> move(c, b) -> move(b, a)
+    // Generates moves in this order: move b to a and move c to b
+    // ie. cycle a := b, b := a start with node a
+    // Call graph: move(NULL, a) -> move(a, b) -> move(b, a)
+    // Generates moves in this order: move b to temp, move a to b, move temp to a
+    private void move(PhiResolverNode src, PhiResolverNode dest) {
+        if (!dest.visited) {
+            dest.visited = true;
+            for (int i = dest.destinations.size() - 1; i >= 0; i--) {
+                move(dest, dest.destinations.get(i));
+            }
+        } else if (!dest.startNode) {
+            // cycle in graph detected
+            assert loop == null : "only one loop valid!";
+            loop = dest;
+            moveToTemp(src.operand);
+            return;
+        } // else dest is a start node
+
+        if (!dest.assigned) {
+            if (loop == dest) {
+                moveTempTo(dest.operand);
+                dest.assigned = true;
+            } else if (src != null) {
+                emitMove(src.operand, dest.operand);
+                dest.assigned = true;
+            }
+        }
+    }
+
+    private void moveTempTo(CiValue dest) {
+        assert isLegal(temp);
+        emitMove(temp, dest);
+        temp = IllegalValue;
+    }
+
+    private void moveToTemp(CiValue src) {
+        assert isIllegal(temp);
+        temp = gen.newVariable(src.kind);
+        emitMove(src, temp);
+    }
+
+    private PhiResolverNode sourceNode(CiValue opr) {
+        return createNode(opr, true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/package-info.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2009, 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.
+ */
+/**
+ * This package contains the port of the LIRGenerator which translates
+ * HIR instructions to LIR instructions for the backend.
+ */
+package com.oracle.max.graal.compiler.gen;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/MergeableState.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.compiler.graph;
+
+import java.util.*;
+
+import com.oracle.max.graal.nodes.*;
+
+public interface MergeableState <T> {
+    T clone();
+    boolean merge(MergeNode merge, Collection<T> withStates);
+    void loopBegin(LoopBeginNode loopBegin);
+    void loopEnds(LoopBeginNode loopBegin, Collection<T> loopEndStates);
+    void afterSplit(FixedNode node);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/PostOrderNodeIterator.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.compiler.graph;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+
+public abstract class PostOrderNodeIterator<T extends MergeableState<T>> {
+
+    private final NodeBitMap visitedEnds;
+    private final Deque<FixedNode> nodeQueue;
+    private final IdentityHashMap<FixedNode, T> nodeStates;
+    private final FixedNode start;
+
+    protected T state;
+
+    public PostOrderNodeIterator(FixedNode start, T initialState) {
+        visitedEnds = start.graph().createNodeBitMap();
+        nodeQueue = new ArrayDeque<>();
+        nodeStates = new IdentityHashMap<>();
+        this.start = start;
+        this.state = initialState;
+    }
+
+    public void apply() {
+        FixedNode current = start;
+
+        do {
+            if (current instanceof InvokeWithExceptionNode) {
+                invoke((Invoke) current);
+                queueSuccessors(current, null);
+                current = nextQueuedNode();
+            } else if (current instanceof LoopBeginNode) {
+                state.loopBegin((LoopBeginNode) current);
+                nodeStates.put(current, state);
+                state = state.clone();
+                loopBegin((LoopBeginNode) current);
+                current = ((LoopBeginNode) current).next();
+                assert current != null;
+            } else if (current instanceof LoopEndNode) {
+                loopEnd((LoopEndNode) current);
+                finishLoopEnds((LoopEndNode) current);
+                current = nextQueuedNode();
+            } else if (current instanceof MergeNode) {
+                merge((MergeNode) current);
+                current = ((MergeNode) current).next();
+                assert current != null;
+            } else if (current instanceof FixedWithNextNode) {
+                FixedNode next = ((FixedWithNextNode) current).next();
+                assert next != null : current;
+                node(current);
+                current = next;
+            } else if (current instanceof EndNode) {
+                end((EndNode) current);
+                queueMerge((EndNode) current);
+                current = nextQueuedNode();
+            } else if (current instanceof DeoptimizeNode) {
+                deoptimize((DeoptimizeNode) current);
+                current = nextQueuedNode();
+            } else if (current instanceof ReturnNode) {
+                returnNode((ReturnNode) current);
+                current = nextQueuedNode();
+            } else if (current instanceof UnwindNode) {
+                unwind((UnwindNode) current);
+                current = nextQueuedNode();
+            } else if (current instanceof ControlSplitNode) {
+                Set<Node> successors = controlSplit((ControlSplitNode) current);
+                queueSuccessors(current, successors);
+                current = nextQueuedNode();
+            } else {
+                assert false : current;
+            }
+        } while(current != null);
+    }
+
+    private void queueSuccessors(FixedNode x, Set<Node> successors) {
+        nodeStates.put(x, state);
+        if (successors != null) {
+            for (Node node : successors) {
+                if (node != null) {
+                    nodeStates.put((FixedNode) node.predecessor(), state);
+                    nodeQueue.addFirst((FixedNode) node);
+                }
+            }
+        } else {
+            for (Node node : x.successors()) {
+                if (node != null) {
+                    nodeQueue.addFirst((FixedNode) node);
+                }
+            }
+        }
+    }
+
+    private FixedNode nextQueuedNode() {
+        int maxIterations = nodeQueue.size();
+        while (maxIterations-- > 0) {
+            FixedNode node = nodeQueue.removeFirst();
+            if (node instanceof MergeNode) {
+                MergeNode merge = (MergeNode) node;
+                state = nodeStates.get(merge.forwardEndAt(0)).clone();
+                ArrayList<T> states = new ArrayList<>(merge.forwardEndCount() - 1);
+                for (int i = 1; i < merge.forwardEndCount(); i++) {
+                    T other = nodeStates.get(merge.forwardEndAt(i));
+                    assert other != null;
+                    states.add(other);
+                }
+                boolean ready = state.merge(merge, states);
+                if (ready) {
+                    return merge;
+                } else {
+                    nodeQueue.addLast(merge);
+                }
+            } else {
+                assert node.predecessor() != null;
+                state = nodeStates.get(node.predecessor()).clone();
+                state.afterSplit(node);
+                return node;
+            }
+        }
+        return null;
+    }
+
+    private void finishLoopEnds(LoopEndNode end) {
+        assert !visitedEnds.isMarked(end);
+        assert !nodeStates.containsKey(end);
+        nodeStates.put(end, state);
+        visitedEnds.mark(end);
+        LoopBeginNode begin = end.loopBegin();
+        boolean endsVisited = true;
+        for (LoopEndNode le : begin.loopEnds()) {
+            if (!visitedEnds.isMarked(le)) {
+                endsVisited = false;
+                break;
+            }
+        }
+        if (endsVisited) {
+            ArrayList<T> states = new ArrayList<>(begin.loopEnds().count());
+            for (LoopEndNode le : begin.orderedLoopEnds()) {
+                states.add(nodeStates.get(le));
+            }
+            T loopBeginState = nodeStates.get(begin);
+            if (loopBeginState != null) {
+                loopBeginState.loopEnds(begin, states);
+            }
+        }
+    }
+
+    private void queueMerge(EndNode end) {
+        assert !visitedEnds.isMarked(end);
+        assert !nodeStates.containsKey(end);
+        nodeStates.put(end, state);
+        visitedEnds.mark(end);
+        MergeNode merge = end.merge();
+        boolean endsVisited = true;
+        for (int i = 0; i < merge.forwardEndCount(); i++) {
+            if (!visitedEnds.isMarked(merge.forwardEndAt(i))) {
+                endsVisited = false;
+                break;
+            }
+        }
+        if (endsVisited) {
+            nodeQueue.add(merge);
+        }
+    }
+
+    protected abstract void node(FixedNode node);
+
+    protected void end(EndNode endNode) {
+        node(endNode);
+    }
+
+    protected void merge(MergeNode merge) {
+        node(merge);
+    }
+
+    protected void loopBegin(LoopBeginNode loopBegin) {
+        node(loopBegin);
+    }
+
+    protected void loopEnd(LoopEndNode loopEnd) {
+        node(loopEnd);
+    }
+
+    protected void deoptimize(DeoptimizeNode deoptimize) {
+        node(deoptimize);
+    }
+
+    protected Set<Node> controlSplit(ControlSplitNode controlSplit) {
+        node(controlSplit);
+        return null;
+    }
+
+    protected void returnNode(ReturnNode returnNode) {
+        node(returnNode);
+    }
+
+    protected void invoke(Invoke invoke) {
+        node(invoke.node());
+    }
+
+    protected void unwind(UnwindNode unwind) {
+        node(unwind);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/package-info.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2010, 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.max.graal.compiler.graph;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/package-info.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * The top-level package in Graal containing options, metrics, timers and the main compiler class
+ * {@link com.oracle.max.graal.compiler.GraalCompiler}.
+ *
+ * <H2>{@code GraalCompiler} Overview</H2>
+ *
+ * Graal is intended to be used with multiple JVM's so makes no use of or reference to classes for a specific JVM, for
+ * example Maxine.
+ *
+ * The compiler is represented by the class {@code GraalCompiler}. {@code GraalCompiler} binds a specific target
+ * architecture and JVM interface to produce a usable compiler object.
+ * {@code RiMethod} is Graal's representation of a Java method and {@code RiXirGenerator} represents the interface through
+ * which the compiler requests the XIR for a given bytecode from the runtime system.
+ *
+ * <H3>The Graal Compilation Process</H3>
+ *
+ * {@link com.oracle.max.graal.compiler.GraalCompiler#compileMethod} creates a {@link GraalCompilation} instance and then returns the result of calling its
+ * {@link com.oracle.max.graal.compiler.GraalCompilation#compile} method.
+ * <p>
+ * While there is only one {@code GraalCompiler} instance, there may be several compilations proceeding concurrently, each of
+ * which is represented by a unique {@code GraalCompilation} instance. The static method {@link com.oracle.max.graal.compiler.GraalCompilation#currentInterval}} returns the
+ * {@code GraalCompilation} instance associated with the current thread, and is managed using a {@link java.lang.ThreadLocal} variable.
+ * Each {@code GraalCompilation} instance has an associated {@link com.oracle.max.cri.ci.CiStatistics} object that accumulates information about the compilation process.
+ * </p>
+ * <H3>Supported backends</H3>
+ *
+ * <ul>
+ * <li>AMD64/x64 with SSE2</li>
+ * </ul>
+ */
+package com.oracle.max.graal.compiler;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/BoxingEliminationPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,136 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import static com.oracle.max.graal.graph.iterators.NodePredicates.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.graph.iterators.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.PhiNode.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.virtual.*;
+
+public class BoxingEliminationPhase extends Phase {
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        if (graph.getNodes(UnboxNode.class).isNotEmpty()) {
+
+            Map<PhiNode, PhiNode> phiReplacements = new HashMap<>();
+            for (UnboxNode unboxNode : graph.getNodes(UnboxNode.class)) {
+                tryEliminate(graph, unboxNode, phiReplacements);
+            }
+
+            new DeadCodeEliminationPhase().apply(graph);
+
+            for (BoxNode boxNode : graph.getNodes(BoxNode.class)) {
+                tryEliminate(boxNode);
+            }
+        }
+    }
+
+    private void tryEliminate(StructuredGraph graph, UnboxNode unboxNode, Map<PhiNode, PhiNode> phiReplacements) {
+        ValueNode unboxedValue = unboxedValue(unboxNode.source(), unboxNode.destinationKind(), phiReplacements);
+        if (unboxedValue != null) {
+            assert unboxedValue.kind() == unboxNode.kind();
+            unboxNode.replaceAtUsages(unboxedValue);
+            graph.removeFixed(unboxNode);
+        }
+    }
+
+    private PhiNode getReplacementPhi(PhiNode phiNode, CiKind kind, Map<PhiNode, PhiNode> phiReplacements) {
+        if (!phiReplacements.containsKey(phiNode)) {
+            PhiNode result = null;
+            if (phiNode.stamp().nonNull()) {
+                RiResolvedType exactType = phiNode.stamp().exactType();
+                if (exactType != null && exactType.toJava() == kind.toUnboxedJavaClass()) {
+                    StructuredGraph graph = (StructuredGraph) phiNode.graph();
+                    result = graph.add(new PhiNode(kind, phiNode.merge(), PhiType.Value));
+                    phiReplacements.put(phiNode, result);
+                    virtualizeUsages(phiNode, result, exactType);
+                    int i = 0;
+                    for (ValueNode n : phiNode.values()) {
+                        ValueNode unboxedValue = unboxedValue(n, kind, phiReplacements);
+                        if (unboxedValue != null) {
+                            assert unboxedValue.kind() == kind;
+                            result.addInput(unboxedValue);
+                        } else {
+                            UnboxNode unboxNode = graph.add(new UnboxNode(kind, n));
+                            FixedNode pred = phiNode.merge().phiPredecessorAt(i);
+                            graph.addBeforeFixed(pred, unboxNode);
+                            result.addInput(unboxNode);
+                        }
+                        ++i;
+                    }
+                }
+            }
+        }
+        return phiReplacements.get(phiNode);
+    }
+
+    private ValueNode unboxedValue(ValueNode n, CiKind kind, Map<PhiNode, PhiNode> phiReplacements) {
+        if (n instanceof BoxNode) {
+            BoxNode boxNode = (BoxNode) n;
+            return boxNode.source();
+        } else if (n instanceof PhiNode) {
+            PhiNode phiNode = (PhiNode) n;
+            return getReplacementPhi(phiNode, kind, phiReplacements);
+        } else {
+            return null;
+        }
+    }
+
+    private static void tryEliminate(BoxNode boxNode) {
+
+        virtualizeUsages(boxNode, boxNode.source(), boxNode.exactType());
+
+        if (boxNode.usages().filter(isNotA(FrameState.class).nor(VirtualObjectFieldNode.class)).isNotEmpty()) {
+            // Elimination failed, because boxing object escapes.
+            return;
+        }
+
+        // TODO(ls) this seems weird: there might still be references to boxNode, yet it is deleted...
+
+        FrameState stateAfter = boxNode.stateAfter();
+        boxNode.setStateAfter(null);
+        stateAfter.safeDelete();
+
+        ((StructuredGraph) boxNode.graph()).removeFixed(boxNode);
+    }
+
+    private static void virtualizeUsages(ValueNode boxNode, ValueNode replacement, RiResolvedType exactType) {
+        ValueNode virtualValueNode = null;
+        VirtualObjectNode virtualObjectNode = null;
+        for (Node n : boxNode.usages().filter(NodePredicates.isA(FrameState.class).or(VirtualObjectFieldNode.class)).snapshot()) {
+            if (virtualValueNode == null) {
+                virtualObjectNode = n.graph().unique(new BoxedVirtualObjectNode(exactType, replacement));
+            }
+            n.replaceFirstInput(boxNode, virtualObjectNode);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,179 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.util.*;
+
+public class CanonicalizerPhase extends Phase {
+    private static final int MAX_ITERATION_PER_NODE = 10;
+
+    private boolean newNodes;
+    private final CiTarget target;
+    private final CiAssumptions assumptions;
+    private final RiRuntime runtime;
+
+    public CanonicalizerPhase(CiTarget target, RiRuntime runtime, CiAssumptions assumptions) {
+        this(target, runtime, false, assumptions);
+    }
+
+    public CanonicalizerPhase(CiTarget target, RiRuntime runtime, boolean newNodes, CiAssumptions assumptions) {
+        this.newNodes = newNodes;
+        this.target = target;
+        this.assumptions = assumptions;
+        this.runtime = runtime;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        NodeWorkList nodeWorkList = graph.createNodeWorkList(!newNodes, MAX_ITERATION_PER_NODE);
+        if (newNodes) {
+            nodeWorkList.addAll(graph.getNewNodes());
+        }
+
+        canonicalize(graph, nodeWorkList, runtime, target, assumptions);
+    }
+
+    public static void canonicalize(StructuredGraph graph, NodeWorkList nodeWorkList, RiRuntime runtime, CiTarget target, CiAssumptions assumptions) {
+        graph.trackInputChange(nodeWorkList);
+        Tool tool = new Tool(nodeWorkList, runtime, target, assumptions);
+        for (Node node : nodeWorkList) {
+            if (node instanceof Canonicalizable) {
+                Debug.log("Canonicalizer: work on %s", node);
+                graph.mark();
+                ValueNode canonical = ((Canonicalizable) node).canonical(tool);
+//     cases:                                           original node:
+//                                         |Floating|Fixed-unconnected|Fixed-connected|
+//                                         --------------------------------------------
+//                                     null|   1    |        X        |       3       |
+//                                         --------------------------------------------
+//                                 Floating|   2    |        X        |       4       |
+//       canonical node:                   --------------------------------------------
+//                        Fixed-unconnected|   X    |        X        |       5       |
+//                                         --------------------------------------------
+//                          Fixed-connected|   2    |        X        |       6       |
+//                                         --------------------------------------------
+//       X: must not happen (checked with assertions)
+                if (canonical != node) {
+                    if (node instanceof FloatingNode) {
+                        if (canonical == null) {
+                            // case 1
+                            graph.removeFloating((FloatingNode) node);
+                        } else {
+                            // case 2
+                            assert !(canonical instanceof FixedNode) || canonical.predecessor() != null : node + " -> " + canonical +
+                                            " : replacement should be floating or fixed and connected";
+                            graph.replaceFloating((FloatingNode) node, canonical);
+                        }
+                    } else {
+                        assert node instanceof FixedWithNextNode && node.predecessor() != null : node + " -> " + canonical + " : node should be fixed & connected (" + node.predecessor() + ")";
+                        if (canonical == null) {
+                            // case 3
+                            graph.removeFixed((FixedWithNextNode) node);
+                        } else if (canonical instanceof FloatingNode) {
+                            // case 4
+                            graph.replaceFixedWithFloating((FixedWithNextNode) node, (FloatingNode) canonical);
+                        } else {
+                            assert canonical instanceof FixedNode;
+                            if (canonical.predecessor() == null) {
+                                assert !canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " shouldn't have successors";
+                                // case 5
+                                graph.replaceFixedWithFixed((FixedWithNextNode) node, (FixedWithNextNode) canonical);
+                            } else {
+                                assert canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " should have successors";
+                                // case 6
+                                node.replaceAtUsages(canonical);
+                                graph.removeFixed((FixedWithNextNode) node);
+                            }
+                        }
+                    }
+                    nodeWorkList.addAll(graph.getNewNodes());
+                }
+            } else if (node instanceof Simplifiable) {
+                ((Simplifiable) node).simplify(tool);
+            }
+        }
+        graph.stopTrackingInputChange();
+        while (graph.getUsagesDroppedNodesCount() > 0) {
+            for (Node n : graph.getAndCleanUsagesDroppedNodes()) {
+                if (!n.isDeleted() && n.usages().size() == 0 && n instanceof FloatingNode) {
+                    n.clearInputs();
+                    n.safeDelete();
+                }
+            }
+        }
+    }
+
+    private static final class Tool implements SimplifierTool {
+
+        private final NodeWorkList nodeWorkList;
+        private final RiRuntime runtime;
+        private final CiTarget target;
+        private final CiAssumptions assumptions;
+
+        public Tool(NodeWorkList nodeWorkList, RiRuntime runtime, CiTarget target, CiAssumptions assumptions) {
+            this.nodeWorkList = nodeWorkList;
+            this.runtime = runtime;
+            this.target = target;
+            this.assumptions = assumptions;
+        }
+
+        @Override
+        public void deleteBranch(FixedNode branch) {
+            branch.predecessor().replaceFirstSuccessor(branch, null);
+            GraphUtil.killCFG(branch);
+        }
+
+        /**
+         * @return the current target or {@code null} if no target is available in the current context.
+         */
+        @Override
+        public CiTarget target() {
+            return target;
+        }
+
+        /**
+         * @return an object that can be used for recording assumptions or {@code null} if assumptions are not allowed in the current context.
+         */
+        @Override
+        public CiAssumptions assumptions() {
+            return assumptions;
+        }
+
+        @Override
+        public RiRuntime runtime() {
+            return runtime;
+        }
+
+        @Override
+        public void addToWorkList(Node node) {
+            nodeWorkList.add(node);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ComputeProbabilityPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,323 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import java.util.*;
+
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.graph.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+
+public class ComputeProbabilityPhase extends Phase {
+    private static final double EPSILON = 1d / Integer.MAX_VALUE;
+
+    /*
+     * The computation of absolute probabilities works in three steps:
+     *
+     * - The first step, "PropagateProbability", traverses the graph in post order (merges after their ends, ...) and keeps track of the "probability state".
+     *   Whenever it encounters a ControlSplit it uses the split's probability information to divide the probability upon the successors.
+     *   Whenever it encounters an Invoke it assumes that the exception edge is unlikely and propagates the whole probability to the normal successor.
+     *   Whenever it encounters a Merge it sums up the probability of all predecessors.
+     *   It also maintains a set of active loops (whose LoopBegin has been visited) and builds def/use information for the second step.
+     *
+     * - The third step propagates the loop frequencies and multiplies each FixedNode's probability with its loop frequency.
+     *
+     *   TODO: add exception probability information to Invokes
+     */
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        new PropagateProbability(graph.start()).apply();
+        Debug.dump(graph, "After PropagateProbability");
+        computeLoopFactors();
+        Debug.dump(graph, "After computeLoopFactors");
+        new PropagateLoopFrequency(graph.start()).apply();
+    }
+
+    private void computeLoopFactors() {
+        for (LoopInfo info : loopInfos) {
+            double frequency = info.loopFrequency();
+            assert frequency != -1;
+        }
+    }
+
+    private static boolean isRelativeProbability(double prob) {
+        // 1.01 to allow for some rounding errors
+        return prob >= 0 && prob <= 1.01;
+    }
+
+    public static class LoopInfo {
+        public final LoopBeginNode loopBegin;
+
+        public final NodeMap<Set<LoopInfo>> requires;
+
+        private double loopFrequency = -1;
+        public boolean ended = false;
+
+        public LoopInfo(LoopBeginNode loopBegin) {
+            this.loopBegin = loopBegin;
+            this.requires = loopBegin.graph().createNodeMap();
+        }
+
+        public double loopFrequency() {
+            if (loopFrequency == -1 && ended) {
+                double backEdgeProb = 0.0;
+                for (LoopEndNode le : loopBegin.loopEnds()) {
+                    double factor = 1;
+                    Set<LoopInfo> requireds = requires.get(le);
+                    for (LoopInfo required : requireds) {
+                        double t = required.loopFrequency();
+                        if (t == -1) {
+                            return -1;
+                        }
+                        factor *= t;
+                    }
+                    backEdgeProb += le.probability() * factor;
+                }
+                double d = backEdgeProb;
+                if (d < EPSILON) {
+                    d = EPSILON;
+                } else if (d > loopBegin.probability() - EPSILON) {
+                    d = loopBegin.probability() - EPSILON;
+                }
+                loopFrequency = loopBegin.probability() / (loopBegin.probability() - d);
+                loopBegin.setLoopFrequency(loopFrequency);
+            }
+            return loopFrequency;
+        }
+    }
+
+    public Set<LoopInfo> loopInfos = new HashSet<>();
+    public Map<MergeNode, Set<LoopInfo>> mergeLoops = new IdentityHashMap<>();
+
+    private class Probability implements MergeableState<Probability> {
+        public double probability;
+        public HashSet<LoopInfo> loops;
+        public LoopInfo loopInfo;
+
+        public Probability(double probability, HashSet<LoopInfo> loops) {
+            this.probability = probability;
+            this.loops = new HashSet<>(4);
+            if (loops != null) {
+                this.loops.addAll(loops);
+            }
+        }
+
+        @Override
+        public Probability clone() {
+            return new Probability(probability, loops);
+        }
+
+        @Override
+        public boolean merge(MergeNode merge, Collection<Probability> withStates) {
+            if (merge.forwardEndCount() > 1) {
+                HashSet<LoopInfo> intersection = new HashSet<>(loops);
+                for (Probability other : withStates) {
+                    intersection.retainAll(other.loops);
+                }
+                for (LoopInfo info : loops) {
+                    if (!intersection.contains(info)) {
+                        double loopFrequency = info.loopFrequency();
+                        if (loopFrequency == -1) {
+                            return false;
+                        }
+                        probability *= loopFrequency;
+                    }
+                }
+                for (Probability other : withStates) {
+                    double prob = other.probability;
+                    for (LoopInfo info : other.loops) {
+                        if (!intersection.contains(info)) {
+                            double loopFrequency = info.loopFrequency();
+                            if (loopFrequency == -1) {
+                                return false;
+                            }
+                            prob *= loopFrequency;
+                        }
+                    }
+                    probability += prob;
+                }
+                loops = intersection;
+                mergeLoops.put(merge, new HashSet<>(intersection));
+                assert isRelativeProbability(probability) : probability;
+            }
+            return true;
+        }
+
+        @Override
+        public void loopBegin(LoopBeginNode loopBegin) {
+            loopInfo = new LoopInfo(loopBegin);
+            loopInfos.add(loopInfo);
+            loops.add(loopInfo);
+        }
+
+        @Override
+        public void loopEnds(LoopBeginNode loopBegin, Collection<Probability> loopEndStates) {
+            assert loopInfo != null;
+            List<LoopEndNode> loopEnds = loopBegin.orderedLoopEnds();
+            int i = 0;
+            for (Probability proba : loopEndStates) {
+                LoopEndNode loopEnd = loopEnds.get(i++);
+                Set<LoopInfo> requires = loopInfo.requires.get(loopEnd);
+                if (requires == null) {
+                    requires = new HashSet<>();
+                    loopInfo.requires.set(loopEnd, requires);
+                }
+                for (LoopInfo innerLoop : proba.loops) {
+                    if (innerLoop != loopInfo && !this.loops.contains(innerLoop)) {
+                        requires.add(innerLoop);
+                    }
+                }
+            }
+            loopInfo.ended = true;
+        }
+
+        @Override
+        public void afterSplit(FixedNode node) {
+            assert node.predecessor() != null;
+            Node pred = node.predecessor();
+            if (pred instanceof Invoke) {
+                Invoke x = (Invoke) pred;
+                if (x.next() != node) {
+                    probability = 0;
+                }
+            } else {
+                assert pred instanceof ControlSplitNode;
+                ControlSplitNode x = (ControlSplitNode) pred;
+                double sum = 0;
+                for (int i = 0; i < x.blockSuccessorCount(); i++) {
+                    if (x.blockSuccessor(i) == node) {
+                        sum += x.probability(i);
+                    }
+                }
+                probability *= sum;
+            }
+        }
+    }
+
+    private class PropagateProbability extends PostOrderNodeIterator<Probability> {
+
+        public PropagateProbability(FixedNode start) {
+            super(start, new Probability(1d, null));
+        }
+
+        @Override
+        protected void node(FixedNode node) {
+            node.setProbability(state.probability);
+        }
+    }
+
+    private class LoopCount implements MergeableState<LoopCount> {
+        public double count;
+
+        public LoopCount(double count) {
+            this.count = count;
+        }
+
+        @Override
+        public LoopCount clone() {
+            return new LoopCount(count);
+        }
+
+        @Override
+        public boolean merge(MergeNode merge, Collection<LoopCount> withStates) {
+            assert merge.forwardEndCount() == withStates.size() + 1;
+            if (merge.forwardEndCount() > 1) {
+                Set<LoopInfo> loops = mergeLoops.get(merge);
+                assert loops != null;
+                double countProd = 1;
+                for (LoopInfo loop : loops) {
+                    countProd *= loop.loopFrequency();
+                }
+                count = countProd;
+            }
+            return true;
+        }
+
+        @Override
+        public void loopBegin(LoopBeginNode loopBegin) {
+            count *= loopBegin.loopFrequency();
+        }
+
+        @Override
+        public void loopEnds(LoopBeginNode loopBegin, Collection<LoopCount> loopEndStates) {
+            // nothing to do...
+        }
+
+        @Override
+        public void afterSplit(FixedNode node) {
+            // nothing to do...
+        }
+    }
+
+    private class PropagateLoopFrequency extends PostOrderNodeIterator<LoopCount> {
+        private final FrequencyPropagationPolicy policy;
+
+        public PropagateLoopFrequency(FixedNode start) {
+            super(start, new LoopCount(1d));
+            this.policy = createFrequencyPropagationPolicy();
+        }
+
+        @Override
+        protected void node(FixedNode node) {
+            node.setProbability(policy.compute(node.probability(), state.count));
+        }
+
+        private FrequencyPropagationPolicy createFrequencyPropagationPolicy() {
+            switch (GraalOptions.LoopFrequencyPropagationPolicy) {
+                case 0: return new FullFrequencyPropagation();
+                case 1: return new NoFrequencyPropagation();
+                case 2: return new LogarithmicFrequencyPropagation();
+                default: throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
+
+    private interface FrequencyPropagationPolicy {
+        double compute(double probability, double frequency);
+    }
+
+    private static class FullFrequencyPropagation implements FrequencyPropagationPolicy {
+        @Override
+        public double compute(double probability, double frequency) {
+            return probability * frequency;
+        }
+    }
+
+    private static class NoFrequencyPropagation implements FrequencyPropagationPolicy {
+        @Override
+        public double compute(double probability, double frequency) {
+            return probability;
+        }
+    }
+
+    private static class LogarithmicFrequencyPropagation implements FrequencyPropagationPolicy {
+        @Override
+        public double compute(double probability, double frequency) {
+            double result = Math.pow(probability, 1.5) * Math.log(frequency);
+            return Math.max(probability, result);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ConvertDeoptimizeToGuardPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,91 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import java.util.*;
+
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.util.*;
+
+public class ConvertDeoptimizeToGuardPhase extends Phase {
+
+    private static BeginNode findBeginNode(Node startNode) {
+        Node n = startNode;
+        while (true) {
+            if (n instanceof BeginNode) {
+                return (BeginNode) n;
+            } else {
+                n = n.predecessor();
+            }
+        }
+    }
+
+    @Override
+    protected void run(final StructuredGraph graph) {
+        if (graph.getNodes(DeoptimizeNode.class).isEmpty()) {
+            return;
+        }
+
+        for (DeoptimizeNode d : graph.getNodes(DeoptimizeNode.class)) {
+            visitDeoptBranch(findBeginNode(d), d, graph);
+        }
+
+        new DeadCodeEliminationPhase().apply(graph);
+    }
+
+    private void visitDeoptBranch(BeginNode deoptBegin, DeoptimizeNode deopt, StructuredGraph graph) {
+        if (deoptBegin instanceof MergeNode) {
+            MergeNode mergeNode = (MergeNode) deoptBegin;
+            Debug.log("Eliminating %s followed by %s", mergeNode, deopt);
+            List<EndNode> ends = mergeNode.forwardEnds().snapshot();
+            for (EndNode end : ends) {
+                if (!end.isDeleted()) {
+                    BeginNode beginNode = findBeginNode(end);
+                    visitDeoptBranch(beginNode, deopt, graph);
+                }
+            }
+            if (!deopt.isDeleted()) {
+                visitDeoptBranch(findBeginNode(deopt), deopt, graph);
+            }
+        } else if (deoptBegin.predecessor() instanceof IfNode) {
+            IfNode ifNode = (IfNode) deoptBegin.predecessor();
+            BeginNode otherBegin = ifNode.trueSuccessor();
+            BooleanNode conditionNode = ifNode.compare();
+            if (deoptBegin == ifNode.trueSuccessor()) {
+                conditionNode = conditionNode.negate();
+                otherBegin = ifNode.falseSuccessor();
+            }
+            BeginNode ifBlockBegin = findBeginNode(ifNode);
+            Debug.log("Converting %s on %-5s branch of %s to guard for remaining branch %s. IfBegin=%s", deopt, deoptBegin == ifNode.trueSuccessor() ? "true" : "false", ifNode, otherBegin, ifBlockBegin);
+            FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode));
+            otherBegin.replaceAtUsages(ifBlockBegin);
+            FixedNode next = otherBegin.next();
+            otherBegin.setNext(null);
+            guard.setNext(next);
+            ifNode.replaceAtPredecessors(guard);
+            GraphUtil.killCFG(ifNode);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,137 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+
+
+public class DeadCodeEliminationPhase extends Phase {
+
+    private NodeFlood flood;
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        this.flood = graph.createNodeFlood();
+
+        flood.add(graph.start());
+        iterateSuccessors();
+        disconnectCFGNodes(graph);
+        iterateInputs(graph);
+        deleteNodes(graph);
+
+        // remove chained Merges
+        for (MergeNode merge : graph.getNodes(MergeNode.class)) {
+            if (merge.forwardEndCount() == 1 && !(merge instanceof LoopBeginNode)) {
+                replacePhis(merge);
+                EndNode endNode = merge.forwardEndAt(0);
+                FixedNode next = merge.next();
+                merge.safeDelete();
+                endNode.replaceAndDelete(next);
+            }
+        }
+    }
+
+    private void iterateSuccessors() {
+        for (Node current : flood) {
+            if (current instanceof EndNode) {
+                EndNode end = (EndNode) current;
+                flood.add(end.merge());
+            } else {
+                for (Node successor : current.successors()) {
+                    flood.add(successor);
+                }
+            }
+        }
+    }
+
+    private void disconnectCFGNodes(StructuredGraph graph) {
+        for (EndNode node : graph.getNodes(EndNode.class)) {
+            if (!flood.isMarked(node)) {
+                MergeNode merge = node.merge();
+                if (merge != null && flood.isMarked(merge)) {
+                    // We are a dead end node leading to a live merge.
+                    merge.removeEnd(node);
+                }
+            }
+        }
+        for (LoopBeginNode loop : graph.getNodes(LoopBeginNode.class)) {
+            if (flood.isMarked(loop)) {
+                boolean reachable = false;
+                for (LoopEndNode end : loop.loopEnds()) {
+                    if (flood.isMarked(end)) {
+                        reachable = true;
+                        break;
+                    }
+                }
+                if (!reachable) {
+                    Debug.log("Removing loop with unreachable end: %s", loop);
+                    for (LoopEndNode end : loop.loopEnds().snapshot()) {
+                        loop.removeEnd(end);
+                    }
+                    graph.reduceDegenerateLoopBegin(loop);
+                }
+            }
+        }
+    }
+
+    private static void replacePhis(MergeNode merge) {
+        for (PhiNode phi : merge.phis().snapshot()) {
+            ((StructuredGraph) merge.graph()).replaceFloating(phi, phi.valueAt(0));
+        }
+    }
+
+    private void deleteNodes(StructuredGraph graph) {
+        for (Node node : graph.getNodes()) {
+            if (!flood.isMarked(node)) {
+                node.clearInputs();
+                node.clearSuccessors();
+            }
+        }
+        for (Node node : graph.getNodes()) {
+            if (!flood.isMarked(node)) {
+                node.safeDelete();
+            }
+        }
+    }
+
+    private void iterateInputs(StructuredGraph graph) {
+        for (Node node : graph.getNodes()) {
+            if (node instanceof LocalNode) {
+                flood.add(node);
+            }
+            if (flood.isMarked(node)) {
+                for (Node input : node.inputs()) {
+                    flood.add(input);
+                }
+            }
+        }
+        for (Node current : flood) {
+            for (Node input : current.inputs()) {
+                flood.add(input);
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/EscapeAnalysisPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,460 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.graph.*;
+import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.PhiNode.PhiType;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.java.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.virtual.*;
+
+
+public class EscapeAnalysisPhase extends Phase {
+
+    public static class BlockExitState implements MergeableState<BlockExitState> {
+        public final ValueNode[] fieldState;
+        public final VirtualObjectNode virtualObject;
+        public ValueNode virtualObjectField;
+        public final Graph graph;
+
+        public BlockExitState(EscapeField[] fields, VirtualObjectNode virtualObject) {
+            this.fieldState = new ValueNode[fields.length];
+            this.virtualObject = virtualObject;
+            this.virtualObjectField = null;
+            this.graph = virtualObject.graph();
+            for (int i = 0; i < fields.length; i++) {
+                fieldState[i] = ConstantNode.defaultForKind(fields[i].type().kind(true), virtualObject.graph());
+                virtualObjectField = graph.add(new VirtualObjectFieldNode(virtualObject, virtualObjectField, fieldState[i], i));
+            }
+        }
+
+        public BlockExitState(BlockExitState state) {
+            this.fieldState = state.fieldState.clone();
+            this.virtualObject = state.virtualObject;
+            this.virtualObjectField = state.virtualObjectField;
+            this.graph = state.graph;
+        }
+
+        public void updateField(int fieldIndex) {
+            virtualObjectField = graph.add(new VirtualObjectFieldNode(virtualObject, virtualObjectField, fieldState[fieldIndex], fieldIndex));
+        }
+
+        @Override
+        public BlockExitState clone() {
+            return new BlockExitState(this);
+        }
+
+        @Override
+        public boolean merge(MergeNode merge, Collection<BlockExitState> withStates) {
+            PhiNode vobjPhi = null;
+            PhiNode[] valuePhis = new PhiNode[fieldState.length];
+            for (BlockExitState other : withStates) {
+                if (virtualObjectField != other.virtualObjectField && vobjPhi == null) {
+                    vobjPhi = graph.add(new PhiNode(CiKind.Illegal, merge, PhiType.Virtual));
+                    vobjPhi.addInput(virtualObjectField);
+                    virtualObjectField = vobjPhi;
+                }
+                for (int i2 = 0; i2 < fieldState.length; i2++) {
+                    if (fieldState[i2] != other.fieldState[i2] && valuePhis[i2] == null) {
+                        valuePhis[i2] = graph.add(new PhiNode(fieldState[i2].kind(), merge, PhiType.Value));
+                        valuePhis[i2].addInput(fieldState[i2]);
+                        fieldState[i2] = valuePhis[i2];
+                    }
+                }
+            }
+            for (BlockExitState other : withStates) {
+                if (vobjPhi != null) {
+                    vobjPhi.addInput(other.virtualObjectField);
+                }
+                for (int i2 = 0; i2 < fieldState.length; i2++) {
+                    if (valuePhis[i2] != null) {
+                        valuePhis[i2].addInput(other.fieldState[i2]);
+                    }
+                }
+            }
+            assert vobjPhi == null || vobjPhi.valueCount() == withStates.size() + 1;
+            for (int i2 = 0; i2 < fieldState.length; i2++) {
+                if (valuePhis[i2] != null) {
+                    virtualObjectField = graph.add(new VirtualObjectFieldNode(virtualObject, virtualObjectField, valuePhis[i2], i2));
+                    assert valuePhis[i2].valueCount() == withStates.size() + 1;
+                }
+            }
+            return true;
+        }
+
+        @Override
+        public void loopBegin(LoopBeginNode loopBegin) {
+            assert virtualObjectField != null : "unexpected null virtualObjectField";
+            PhiNode vobjPhi = null;
+            vobjPhi = graph.add(new PhiNode(CiKind.Illegal, loopBegin, PhiType.Virtual));
+            vobjPhi.addInput(virtualObjectField);
+            virtualObjectField = vobjPhi;
+            for (int i2 = 0; i2 < fieldState.length; i2++) {
+                PhiNode valuePhi = graph.add(new PhiNode(fieldState[i2].kind(), loopBegin, PhiType.Value));
+                valuePhi.addInput(fieldState[i2]);
+                fieldState[i2] = valuePhi;
+                updateField(i2);
+            }
+        }
+
+        @Override
+        public void loopEnds(LoopBeginNode loopBegin, Collection<BlockExitState> loopEndStates) {
+            while (!(virtualObjectField instanceof PhiNode)) {
+                virtualObjectField = ((VirtualObjectFieldNode) virtualObjectField).lastState();
+            }
+            for (BlockExitState loopEndState : loopEndStates) {
+                ((PhiNode) virtualObjectField).addInput(loopEndState.virtualObjectField);
+                for (int i2 = 0; i2 < fieldState.length; i2++) {
+                    ((PhiNode) fieldState[i2]).addInput(loopEndState.fieldState[i2]);
+                }
+            }
+        }
+
+        @Override
+        public void afterSplit(FixedNode node) {
+            // nothing to do...
+        }
+    }
+
+
+    public static class EscapementFixup {
+
+        private final Map<Object, Integer> fields = new HashMap<>();
+        private final EscapeOp op;
+        private final StructuredGraph graph;
+        private final FixedWithNextNode node;
+        private EscapeField[] escapeFields;
+
+        public EscapementFixup(EscapeOp op, StructuredGraph graph, FixedWithNextNode node) {
+            this.op = op;
+            this.graph = graph;
+            this.node = node;
+        }
+
+        public void apply() {
+            if (node.usages().isEmpty()) {
+                graph.removeFixed(node);
+            } else {
+                process();
+                removeAllocation();
+            }
+        }
+
+        public void removeAllocation() {
+            escapeFields = op.fields(node);
+            for (int i = 0; i < escapeFields.length; i++) {
+                fields.put(escapeFields[i].representation(), i);
+            }
+            final VirtualObjectNode virtual = graph.add(new VirtualObjectNode(((ValueNode) node).exactType(), escapeFields));
+            if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) {
+                TTY.println("new virtual object: " + virtual);
+            }
+            node.replaceAtUsages(virtual);
+            FixedNode next = node.next();
+            graph.removeFixed(node);
+
+            if (virtual.fieldsCount() > 0) {
+                final BlockExitState startState = new BlockExitState(escapeFields, virtual);
+                final PostOrderNodeIterator<?> iterator = new PostOrderNodeIterator<BlockExitState>(next, startState) {
+                    @Override
+                    protected void node(FixedNode curNode) {
+                        int changedField = op.updateState(virtual, curNode, fields, state.fieldState);
+                        if (changedField != -1) {
+                            state.updateField(changedField);
+                        }
+                        if (!curNode.isDeleted() && curNode instanceof StateSplit && ((StateSplit) curNode).stateAfter() != null) {
+                            if (state.virtualObjectField != null) {
+                                ((StateSplit) curNode).stateAfter().addVirtualObjectMapping(state.virtualObjectField);
+                            }
+                        }
+                    }
+                };
+                iterator.apply();
+            }
+        }
+
+        private void process() {
+            for (Node usage : node.usages().snapshot()) {
+                op.beforeUpdate(node, usage);
+            }
+        }
+    }
+
+    private final CiTarget target;
+    private final GraalRuntime runtime;
+    private final CiAssumptions assumptions;
+    private final PhasePlan plan;
+
+    public EscapeAnalysisPhase(CiTarget target, GraalRuntime runtime, CiAssumptions assumptions, PhasePlan plan) {
+        this.runtime = runtime;
+        this.target = target;
+        this.assumptions = assumptions;
+        this.plan = plan;
+    }
+
+    public static class EscapeRecord {
+
+        public final Node node;
+        public final ArrayList<Node> escapesThrough = new ArrayList<>();
+        public final ArrayList<Invoke> invokes = new ArrayList<>();
+        public double localWeight;
+
+        public EscapeRecord(Node node) {
+            this.node = node;
+        }
+
+        public void dump() {
+            TTY.print("node %s (%f) escapes through ", node, localWeight);
+            for (Node escape : escapesThrough) {
+                TTY.print("%s ", escape);
+            }
+            TTY.println();
+        }
+    }
+
+    private static Node escape(EscapeRecord record, Node usage) {
+        final Node node = record.node;
+        if (usage instanceof FrameState) {
+            assert usage.inputs().contains(node);
+            return null;
+        } else {
+            if (usage instanceof FixedNode) {
+                record.localWeight += ((FixedNode) usage).probability();
+            }
+            if (usage instanceof NullCheckNode) {
+                assert ((NullCheckNode) usage).object() == node;
+                return null;
+            } else if (usage instanceof IsTypeNode) {
+                assert ((IsTypeNode) usage).objectClass() == node;
+                return null;
+            } else if (usage instanceof AccessMonitorNode) {
+                assert ((AccessMonitorNode) usage).object() == node;
+                return null;
+            } else if (usage instanceof LoadFieldNode) {
+                assert ((LoadFieldNode) usage).object() == node;
+                return null;
+            } else if (usage instanceof StoreFieldNode) {
+                StoreFieldNode x = (StoreFieldNode) usage;
+                // self-references do not escape
+                return x.value() == node ? x.object() : null;
+            } else if (usage instanceof LoadIndexedNode) {
+                LoadIndexedNode x = (LoadIndexedNode) usage;
+                if (x.index() == node) {
+                    return x.array();
+                } else {
+                    assert x.array() == node;
+                    return EscapeOp.isValidConstantIndex(x) ? null : x.array();
+                }
+            } else if (usage instanceof StoreIndexedNode) {
+                StoreIndexedNode x = (StoreIndexedNode) usage;
+                if (x.index() == node) {
+                    return x.array();
+                } else {
+                    assert x.array() == node || x.value() == node;
+                    // in order to not escape, the access needs to have a valid constant index and either a store into node or be self-referencing
+                    return EscapeOp.isValidConstantIndex(x) && x.value() != node ? null : x.array();
+                }
+            } else if (usage instanceof VirtualObjectFieldNode) {
+                return null;
+            } else if (usage instanceof RegisterFinalizerNode) {
+                assert ((RegisterFinalizerNode) usage).object() == node;
+                return null;
+            } else if (usage instanceof ArrayLengthNode) {
+                assert ((ArrayLengthNode) usage).array() == node;
+                return null;
+            } else {
+                return usage;
+            }
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static void completeAnalysis(StructuredGraph graph) {
+        // TODO(ls): debugging code
+
+        TTY.println("================================================================");
+        for (Node node : graph.getNodes()) {
+            if (node != null && node instanceof FixedWithNextNode && node instanceof EscapeAnalyzable) {
+                EscapeOp op = ((EscapeAnalyzable) node).getEscapeOp();
+                if (op != null && op.canAnalyze(node)) {
+                    EscapeRecord record = new EscapeRecord(node);
+
+                    for (Node usage : node.usages()) {
+                        Node escapesThrough = escape(record, usage);
+                        if (escapesThrough != null && escapesThrough != node) {
+                            record.escapesThrough.add(escapesThrough);
+                        }
+                    }
+                    record.dump();
+                }
+            }
+        }
+    }
+
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (Node node : new GraphOrder(graph)) {
+            if (node != null && node instanceof FixedWithNextNode && node instanceof EscapeAnalyzable) {
+                FixedWithNextNode fixedNode = (FixedWithNextNode) node;
+                EscapeOp op = ((EscapeAnalyzable) node).getEscapeOp();
+                if (op != null && op.canAnalyze(fixedNode)) {
+                    try {
+                        performAnalysis(graph, fixedNode, op);
+                    } catch (GraalInternalError e) {
+                        throw e.addContext("escape analysis of node", node);
+                    }
+                }
+            }
+        }
+    }
+
+    private void performAnalysis(StructuredGraph graph, FixedWithNextNode node, EscapeOp op) {
+        if (!shouldAnalyze(node)) {
+            return;
+        }
+        Set<Node> exits = new HashSet<>();
+        Set<Invoke> invokes = new HashSet<>();
+        int iterations = 0;
+
+        int minimumWeight = getMinimumWeight(node);
+        do {
+            double weight = analyze(op, node, exits, invokes);
+            if (exits.size() != 0) {
+                if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) {
+                    TTY.println("%n####### escaping object: %s (%s)", node, node.exactType());
+                    if (GraalOptions.TraceEscapeAnalysis) {
+                        TTY.print("%d: new value: %s, weight %f, escapes at ", iterations, node, weight);
+                        for (Node n : exits) {
+                            TTY.print("%s, ", n);
+                        }
+                        for (Invoke n : invokes) {
+                            TTY.print("%s, ", n);
+                        }
+                        TTY.println();
+                    }
+                }
+                break;
+            }
+            if (invokes.size() == 0) {
+
+                Debug.dump(graph, "Before escape %s", node);
+                Debug.log("!!!!!!!! non-escaping object: %s (%s)", node, node.exactType());
+                removeAllocation(node, op);
+                Debug.dump(graph, "After escape", graph);
+                break;
+            }
+            if (weight < minimumWeight) {
+                if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) {
+                    TTY.println("%n####### possibly escaping object: %s (insufficient weight for inlining)", node);
+                }
+                break;
+            }
+            if (!GraalOptions.Inline) {
+                break;
+            }
+            if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) {
+                TTY.println("Trying inlining to get a non-escaping object for %s", node);
+            }
+            new InliningPhase(target, runtime, invokes, assumptions, plan).apply(graph);
+            new DeadCodeEliminationPhase().apply(graph);
+            if (node.isDeleted()) {
+                if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) {
+                    TTY.println("%n!!!!!!!! object died while performing escape analysis: %s (%s)", node, node.exactType());
+                }
+                break;
+            }
+            exits.clear();
+            invokes.clear();
+        } while (iterations++ < 3);
+    }
+
+    protected void removeAllocation(FixedWithNextNode node, EscapeOp op) {
+        new EscapementFixup(op, (StructuredGraph) node.graph(), node).apply();
+
+        for (PhiNode phi : node.graph().getNodes(PhiNode.class)) {
+            ValueNode simpleValue = phi;
+            boolean required = false;
+            for (ValueNode value : phi.values()) {
+                if (value != phi && value != simpleValue) {
+                    if (simpleValue != phi) {
+                        required = true;
+                        break;
+                    }
+                    simpleValue = value;
+                }
+            }
+            if (!required) {
+                ((StructuredGraph) node.graph()).replaceFloating(phi, simpleValue);
+            }
+        }
+    }
+
+    protected boolean shouldAnalyze(@SuppressWarnings("unused") FixedWithNextNode node) {
+        return true;
+    }
+
+    protected int getMinimumWeight(@SuppressWarnings("unused") FixedWithNextNode node) {
+        return GraalOptions.ForcedInlineEscapeWeight;
+    }
+
+    private static double analyze(EscapeOp op, Node node, Collection<Node> exits, Collection<Invoke> invokes) {
+        double weight = 0;
+        for (Node usage : node.usages().snapshot()) {
+            boolean escapes = op.escape(node, usage);
+            if (escapes) {
+                if (usage instanceof FrameState) {
+                    // nothing to do...
+                } else if (usage instanceof MethodCallTargetNode) {
+                    if (usage.usages().size() == 0) {
+                        usage.safeDelete();
+                    } else {
+                        invokes.add(((MethodCallTargetNode) usage).invoke());
+                    }
+                } else {
+                    exits.add(usage);
+                    break;
+                }
+            } else {
+                if (GraalOptions.ProbabilityAnalysis && usage instanceof FixedNode) {
+                    weight += ((FixedNode) usage).probability();
+                } else {
+                    weight++;
+                }
+            }
+        }
+        return weight;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ExpandBoxingNodesPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.extended.*;
+
+public class ExpandBoxingNodesPhase extends Phase {
+
+    private final BoxingMethodPool pool;
+
+    public ExpandBoxingNodesPhase(BoxingMethodPool pool) {
+        this.pool = pool;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (BoxNode boxNode : graph.getNodes(BoxNode.class)) {
+            boxNode.expand(pool);
+        }
+
+        for (UnboxNode unboxNode : graph.getNodes(UnboxNode.class)) {
+            unboxNode.expand(pool);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/FloatingReadPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,314 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.cfg.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.PhiNode.PhiType;
+import com.oracle.max.graal.nodes.extended.*;
+
+public class FloatingReadPhase extends Phase {
+
+    private static class MemoryMap {
+        private Block block;
+        private IdentityHashMap<Object, Node> map;
+        private IdentityHashMap<Object, Node> loopEntryMap;
+        private int mergeOperationCount;
+
+        public MemoryMap(Block block) {
+            this.block = block;
+            map = new IdentityHashMap<>();
+        }
+
+        public MemoryMap(Block block, MemoryMap other) {
+            this(block);
+            map.putAll(other.map);
+        }
+
+        public void mergeLoopEntryWith(MemoryMap otherMemoryMap, LoopBeginNode begin) {
+            for (Object keyInOther : otherMemoryMap.map.keySet()) {
+                assert loopEntryMap.containsKey(keyInOther) || map.get(keyInOther) == otherMemoryMap.map.get(keyInOther) : keyInOther + ", " + map.get(keyInOther) + " vs " + otherMemoryMap.map.get(keyInOther) + " " + begin;
+            }
+
+            for (Map.Entry<Object, Node> entry : loopEntryMap.entrySet()) {
+                PhiNode phiNode = (PhiNode) entry.getValue();
+                Object key = entry.getKey();
+                Node other;
+                if (otherMemoryMap.map.containsKey(key)) {
+                    other = otherMemoryMap.map.get(key);
+                } else {
+                    other = otherMemoryMap.map.get(LocationNode.ANY_LOCATION);
+                }
+
+                phiNode.addInput((ValueNode) other);
+            }
+        }
+
+        public void mergeWith(MemoryMap otherMemoryMap, Block b) {
+            Debug.log("Merging block %s into block %s.", otherMemoryMap.block, block);
+            IdentityHashMap<Object, Node> otherMap = otherMemoryMap.map;
+
+            for (Map.Entry<Object, Node> entry : map.entrySet()) {
+                if (otherMap.containsKey(entry.getKey())) {
+                    mergeNodes(entry.getKey(), entry.getValue(), otherMap.get(entry.getKey()), b);
+                } else {
+                    mergeNodes(entry.getKey(), entry.getValue(), otherMap.get(LocationNode.ANY_LOCATION), b);
+                }
+            }
+
+            Node anyLocationNode = map.get(LocationNode.ANY_LOCATION);
+            for (Map.Entry<Object, Node> entry : otherMap.entrySet()) {
+                if (!map.containsKey(entry.getKey())) {
+                    Node current = anyLocationNode;
+                    if (anyLocationNode instanceof PhiNode) {
+                        PhiNode phiNode = (PhiNode) anyLocationNode;
+                        if (phiNode.merge() == block.getBeginNode()) {
+                            PhiNode phiCopy = (PhiNode) phiNode.copyWithInputs();
+                            phiCopy.removeInput(phiCopy.valueCount() - 1);
+                            current = phiCopy;
+                            map.put(entry.getKey(), current);
+                        }
+                    }
+                    mergeNodes(entry.getKey(), current, entry.getValue(), b);
+                }
+            }
+
+            mergeOperationCount++;
+        }
+
+        private void mergeNodes(Object location, Node original, Node newValue, Block mergeBlock) {
+            if (original == newValue) {
+                Debug.log("Nothing to merge both nodes are %s.", original);
+                return;
+            }
+            MergeNode m = (MergeNode) mergeBlock.getBeginNode();
+            if (m.isPhiAtMerge(original)) {
+                PhiNode phi = (PhiNode) original;
+                phi.addInput((ValueNode) newValue);
+                Debug.log("Add new input to %s: %s.", original, newValue);
+                assert phi.valueCount() <= phi.merge().forwardEndCount() : phi.merge();
+            } else {
+                PhiNode phi = m.graph().unique(new PhiNode(CiKind.Illegal, m, PhiType.Memory));
+                for (int i = 0; i < mergeOperationCount + 1; ++i) {
+                    phi.addInput((ValueNode) original);
+                }
+                phi.addInput((ValueNode) newValue);
+                Debug.log("Creating new %s merge=%s newValue=%s location=%s.", phi, phi.merge(), newValue, location);
+                assert phi.valueCount() <= phi.merge().forwardEndCount() + ((phi.merge() instanceof LoopBeginNode) ? 1 : 0) : phi.merge() + "/" + phi.valueCount() + "/" + phi.merge().forwardEndCount() + "/" + mergeOperationCount;
+                assert m.usages().contains(phi);
+                assert phi.merge().usages().contains(phi);
+                for (Node input : phi.inputs()) {
+                    assert input.usages().contains(phi);
+                }
+                map.put(location, phi);
+            }
+        }
+
+        public void processCheckpoint(MemoryCheckpoint checkpoint) {
+            map.clear();
+            map.put(LocationNode.ANY_LOCATION, (Node) checkpoint);
+        }
+
+        public void processWrite(WriteNode writeNode) {
+            map.put(writeNode.location().locationIdentity(), writeNode);
+        }
+
+        public void processRead(ReadNode readNode) {
+            StructuredGraph graph = (StructuredGraph) readNode.graph();
+            assert readNode.getNullCheck() == false;
+
+            Debug.log("Register read to node %s.", readNode);
+            FloatingReadNode floatingRead;
+            if (readNode.location().locationIdentity() == LocationNode.FINAL_LOCATION) {
+                floatingRead = graph.unique(new FloatingReadNode(readNode.kind(), readNode.object(), readNode.guard(), readNode.location()));
+            } else {
+                floatingRead = graph.unique(new FloatingReadNode(readNode.kind(), readNode.object(), readNode.guard(), readNode.location(), getLocationForRead(readNode)));
+            }
+            graph.replaceFixedWithFloating(readNode, floatingRead);
+        }
+
+        private Node getLocationForRead(ReadNode readNode) {
+            Object locationIdentity = readNode.location().locationIdentity();
+            Node result = map.get(locationIdentity);
+            if (result == null) {
+                result = map.get(LocationNode.ANY_LOCATION);
+            }
+            return result;
+        }
+
+        public void createLoopEntryMemoryMap(Set<Object> modifiedLocations, Loop loop) {
+
+            loopEntryMap = new IdentityHashMap<>();
+
+            for (Object modifiedLocation : modifiedLocations) {
+                Node other;
+                if (map.containsKey(modifiedLocation)) {
+                    other = map.get(modifiedLocation);
+                } else {
+                    other = map.get(LocationNode.ANY_LOCATION);
+                }
+                createLoopEntryPhi(modifiedLocation, other, loop);
+            }
+
+            if (modifiedLocations.contains(LocationNode.ANY_LOCATION)) {
+                for (Map.Entry<Object, Node> entry : map.entrySet()) {
+                    if (!modifiedLocations.contains(entry.getKey())) {
+                        createLoopEntryPhi(entry.getKey(), entry.getValue(), loop);
+                    }
+                }
+            }
+        }
+
+        private void createLoopEntryPhi(Object modifiedLocation, Node other, Loop loop) {
+            PhiNode phi = other.graph().unique(new PhiNode(CiKind.Illegal, (MergeNode) loop.header.getBeginNode(), PhiType.Memory));
+            phi.addInput((ValueNode) other);
+            map.put(modifiedLocation, phi);
+            loopEntryMap.put(modifiedLocation, phi);
+        }
+
+
+        public IdentityHashMap<Object, Node> getLoopEntryMap() {
+            return loopEntryMap;
+        }
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+
+        // Add start node write checkpoint.
+        addStartCheckpoint(graph);
+
+        // Identify blocks.
+        ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, false, false);
+        Block[] blocks = cfg.getBlocks();
+
+        HashMap<Loop, Set<Object>> modifiedValues = new HashMap<>();
+        // Initialize modified values to empty hash set.
+        for (Loop loop : cfg.getLoops()) {
+            modifiedValues.put(loop, new HashSet<>());
+        }
+
+        // Get modified values in loops.
+        for (Node n : graph.getNodes()) {
+            Block block = cfg.blockFor(n);
+            if (block != null && block.getLoop() != null) {
+                if (n instanceof WriteNode) {
+                    WriteNode writeNode = (WriteNode) n;
+                    traceWrite(block.getLoop(), writeNode.location().locationIdentity(), modifiedValues);
+                } else if (n instanceof MemoryCheckpoint) {
+                    traceMemoryCheckpoint(block.getLoop(), modifiedValues);
+                }
+            }
+        }
+
+        // Propagate values to parent loops.
+        for (Loop loop : cfg.getLoops()) {
+            if (loop.depth == 1) {
+                propagateFromChildren(loop, modifiedValues);
+            }
+        }
+
+        Debug.log("Modified values: %s.", modifiedValues);
+
+
+        // Process blocks (predecessors first).
+        MemoryMap[] memoryMaps = new MemoryMap[blocks.length];
+        for (final Block b : blocks) {
+            processBlock(b, memoryMaps, cfg.getNodeToBlock(), modifiedValues);
+        }
+    }
+
+    private static void addStartCheckpoint(StructuredGraph graph) {
+        BeginNode entryPoint = graph.start();
+        FixedNode next = entryPoint.next();
+        if (!(next instanceof MemoryCheckpoint)) {
+            graph.addAfterFixed(entryPoint, graph.add(new WriteMemoryCheckpointNode()));
+        }
+    }
+
+    private static void processBlock(Block b, MemoryMap[] memoryMaps, NodeMap<Block> nodeToBlock, HashMap<Loop, Set<Object>> modifiedValues) {
+        // Create initial memory map for the block.
+        MemoryMap map = null;
+        if (b.getPredecessors().size() == 0) {
+            map = new MemoryMap(b);
+        } else {
+            map = new MemoryMap(b, memoryMaps[b.getPredecessors().get(0).getId()]);
+            if (b.isLoopHeader()) {
+                Loop loop = b.getLoop();
+                map.createLoopEntryMemoryMap(modifiedValues.get(loop), loop);
+            }
+            for (int i = 1; i < b.getPredecessors().size(); ++i) {
+                Block block = b.getPredecessors().get(i);
+                if (!block.isLoopEnd()) {
+                    map.mergeWith(memoryMaps[block.getId()], b);
+                }
+            }
+        }
+        memoryMaps[b.getId()] = map;
+
+        // Process instructions of this block.
+        for (Node n : b.getNodes()) {
+            if (n instanceof ReadNode) {
+                ReadNode readNode = (ReadNode) n;
+                map.processRead(readNode);
+            } else if (n instanceof WriteNode) {
+                WriteNode writeNode = (WriteNode) n;
+                map.processWrite(writeNode);
+            } else if (n instanceof MemoryCheckpoint) {
+                MemoryCheckpoint checkpoint = (MemoryCheckpoint) n;
+                map.processCheckpoint(checkpoint);
+            }
+        }
+
+
+        if (b.getEndNode() instanceof LoopEndNode) {
+            LoopEndNode end = (LoopEndNode) b.getEndNode();
+            LoopBeginNode begin = end.loopBegin();
+            Block beginBlock = nodeToBlock.get(begin);
+            MemoryMap memoryMap = memoryMaps[beginBlock.getId()];
+            assert memoryMap != null;
+            assert memoryMap.getLoopEntryMap() != null;
+            memoryMap.mergeLoopEntryWith(map, begin);
+        }
+    }
+
+    private static void traceMemoryCheckpoint(Loop loop, HashMap<Loop, Set<Object>> modifiedValues) {
+        modifiedValues.get(loop).add(LocationNode.ANY_LOCATION);
+    }
+
+    private void propagateFromChildren(Loop loop, HashMap<Loop, Set<Object>> modifiedValues) {
+        for (Loop child : loop.children) {
+            propagateFromChildren(child, modifiedValues);
+            modifiedValues.get(loop).addAll(modifiedValues.get(child));
+        }
+    }
+
+    private static void traceWrite(Loop loop, Object locationIdentity, HashMap<Loop, Set<Object>> modifiedValues) {
+        modifiedValues.get(loop).add(locationIdentity);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GlobalValueNumberingPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+
+public class GlobalValueNumberingPhase extends Phase {
+
+    public static final DebugMetric metricGlobalValueNumberingHits = Debug.metric("GlobalValueNumberingHits");
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        NodeBitMap visited = graph.createNodeBitMap();
+        for (Node n : graph.getNodes()) {
+            apply(n, visited, graph);
+        }
+    }
+
+    private void apply(Node n, NodeBitMap visited, StructuredGraph compilerGraph) {
+        if (!visited.isMarked(n)) {
+            visited.mark(n);
+            for (Node input : n.inputs()) {
+                apply(input, visited, compilerGraph);
+            }
+            if (n.getNodeClass().valueNumberable()) {
+                Node newNode = compilerGraph.findDuplicate(n);
+                if (newNode != null) {
+                    assert !(n instanceof FixedNode || newNode instanceof FixedNode);
+                    n.replaceAtUsages(newNode);
+                    n.safeDelete();
+                    metricGlobalValueNumberingHits.increment();
+                    Debug.log("GVN applied and new node is %1s", newNode);
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/IdentifyBoxingPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import java.lang.reflect.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.java.*;
+
+public class IdentifyBoxingPhase extends Phase {
+
+    private final BoxingMethodPool pool;
+
+    public IdentifyBoxingPhase(BoxingMethodPool pool) {
+        this.pool = pool;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (Invoke invoke : graph.getInvokes()) {
+            tryIntrinsify(invoke);
+        }
+    }
+
+    public void tryIntrinsify(Invoke invoke) {
+        MethodCallTargetNode callTarget = invoke.callTarget();
+        RiResolvedMethod targetMethod = callTarget.targetMethod();
+        if (pool.isSpecialMethod(targetMethod)) {
+            assert callTarget.arguments().size() == 1 : "boxing/unboxing method must have exactly one argument";
+            CiKind returnKind = callTarget.returnKind();
+            ValueNode sourceValue = callTarget.arguments().get(0);
+
+            // Check whether this is a boxing or an unboxing.
+            Node newNode = null;
+            if (returnKind == CiKind.Object) {
+                // We have a boxing method here.
+                assert Modifier.isStatic(targetMethod.accessFlags()) : "boxing method must be static";
+                CiKind sourceKind = targetMethod.signature().argumentKindAt(0, false);
+                newNode = invoke.graph().add(new BoxNode(sourceValue, targetMethod.holder(), sourceKind, invoke.bci()));
+            } else {
+                // We have an unboxing method here.
+                assert !Modifier.isStatic(targetMethod.accessFlags()) : "unboxing method must be an instance method";
+                newNode = invoke.graph().add(new UnboxNode(returnKind, sourceValue));
+            }
+
+            // Intrinsify the invoke to the special node.
+            invoke.intrinsify(newNode);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,401 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.phases.PhasePlan.PhasePosition;
+import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.compiler.util.InliningUtil.InlineInfo;
+import com.oracle.max.graal.compiler.util.InliningUtil.InliningCallback;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+
+
+public class InliningPhase extends Phase implements InliningCallback {
+    /*
+     * - Detect method which only call another method with some parameters set to constants: void foo(a) -> void foo(a, b) -> void foo(a, b, c) ...
+     *   These should not be taken into account when determining inlining depth.
+     * - honor the result of overrideInliningDecision(0, caller, invoke.bci, method, true);
+     */
+
+    private final CiTarget target;
+    private final GraalRuntime runtime;
+
+    private final Collection<? extends Invoke> hints;
+
+    private final PriorityQueue<InlineInfo> inlineCandidates = new PriorityQueue<>();
+    private CiAssumptions assumptions;
+
+    private final PhasePlan plan;
+    private final WeightComputationPolicy weightComputationPolicy;
+    private final InliningPolicy inliningPolicy;
+
+    // Metrics
+    private static final DebugMetric metricInliningPerformed = Debug.metric("InliningPerformed");
+    private static final DebugMetric metricInliningConsidered = Debug.metric("InliningConsidered");
+    private static final DebugMetric metricInliningStoppedByMaxDesiredSize = Debug.metric("InliningStoppedByMaxDesiredSize");
+
+    public InliningPhase(CiTarget target, GraalRuntime runtime, Collection<? extends Invoke> hints, CiAssumptions assumptions, PhasePlan plan) {
+        this.target = target;
+        this.runtime = runtime;
+        this.hints = hints;
+        this.assumptions = assumptions;
+        this.plan = plan;
+        this.weightComputationPolicy = createWeightComputationPolicy();
+        this.inliningPolicy = createInliningPolicy();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected void run(StructuredGraph graph) {
+        graph.createNodeMap();
+
+        if (hints != null) {
+            scanInvokes((Iterable<? extends Node>) Util.uncheckedCast(this.hints), -1, graph);
+        } else {
+            scanInvokes(graph.getNodes(InvokeNode.class), 0, graph);
+            scanInvokes(graph.getNodes(InvokeWithExceptionNode.class), 0, graph);
+        }
+
+        while (!inlineCandidates.isEmpty() && graph.getNodeCount() < GraalOptions.MaximumDesiredSize) {
+            InlineInfo info = inlineCandidates.remove();
+            if (inliningPolicy.isWorthInlining(graph, info)) {
+                Iterable<Node> newNodes = null;
+                if (info.invoke.node().isAlive()) {
+                    try {
+                        info.inline(graph, runtime, this);
+                        Debug.log("inlining %f: %s", info.weight, info);
+                        Debug.dump(graph, "after %s", info);
+                        // get the new nodes here, the canonicalizer phase will reset the mark
+                        newNodes = graph.getNewNodes();
+                        if (GraalOptions.OptCanonicalizer) {
+                            new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph);
+                        }
+                        if (GraalOptions.Intrinsify) {
+                            new IntrinsificationPhase(runtime).apply(graph);
+                        }
+                        metricInliningPerformed.increment();
+                    } catch (CiBailout bailout) {
+                        // TODO determine if we should really bail out of the whole compilation.
+                        throw bailout;
+                    } catch (AssertionError e) {
+                        throw new GraalInternalError(e).addContext(info.toString());
+                    } catch (RuntimeException e) {
+                        throw new GraalInternalError(e).addContext(info.toString());
+                    } catch (GraalInternalError e) {
+                        throw e.addContext(info.toString());
+                    }
+                }
+                if (newNodes != null && info.level < GraalOptions.MaximumInlineLevel) {
+                    scanInvokes(newNodes, info.level + 1, graph);
+                }
+            }
+        }
+
+        if (GraalOptions.Debug && graph.getNodeCount() >= GraalOptions.MaximumDesiredSize) {
+            metricInliningStoppedByMaxDesiredSize.increment();
+        }
+    }
+
+    private void scanInvokes(Iterable<? extends Node> newNodes, int level, StructuredGraph graph) {
+        graph.mark();
+        for (Node node : newNodes) {
+            if (node != null) {
+                if (node instanceof Invoke) {
+                    Invoke invoke = (Invoke) node;
+                    scanInvoke(invoke, level);
+                }
+                for (Node usage : node.usages().filterInterface(Invoke.class).snapshot()) {
+                    scanInvoke((Invoke) usage, level);
+                }
+            }
+        }
+    }
+
+    private void scanInvoke(Invoke invoke, int level) {
+        InlineInfo info = InliningUtil.getInlineInfo(invoke, level >= 0 ? level : computeInliningLevel(invoke), runtime, assumptions, this);
+        if (info != null) {
+            assert level == -1 || computeInliningLevel(invoke) == level : "outer FramesStates must match inlining level";
+            metricInliningConsidered.increment();
+            inlineCandidates.add(info);
+        }
+    }
+
+    public static final Map<RiMethod, Integer> parsedMethods = new HashMap<>();
+
+    @Override
+    public StructuredGraph buildGraph(RiResolvedMethod method) {
+        StructuredGraph newGraph = new StructuredGraph(method);
+
+        if (plan != null) {
+            plan.runPhases(PhasePosition.AFTER_PARSING, newGraph);
+        }
+
+        if (GraalOptions.ProbabilityAnalysis) {
+            new DeadCodeEliminationPhase().apply(newGraph);
+            new ComputeProbabilityPhase().apply(newGraph);
+        }
+        if (GraalOptions.OptCanonicalizer) {
+            new CanonicalizerPhase(target, runtime, assumptions).apply(newGraph);
+        }
+        return newGraph;
+    }
+
+    @Override
+    public double inliningWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke) {
+        boolean preferred = hints != null && hints.contains(invoke);
+        return weightComputationPolicy.computeWeight(caller, method, invoke, preferred);
+    }
+
+    public static int graphComplexity(StructuredGraph graph) {
+        int result = 0;
+        for (Node node : graph.getNodes()) {
+            if (node instanceof ConstantNode || node instanceof LocalNode || node instanceof BeginNode || node instanceof ReturnNode || node instanceof UnwindNode) {
+                result += 0;
+            } else if (node instanceof PhiNode) {
+                result += 5;
+            } else if (node instanceof MergeNode || node instanceof Invoke || node instanceof LoopEndNode || node instanceof EndNode) {
+                result += 0;
+            } else if (node instanceof ControlSplitNode) {
+                result += ((ControlSplitNode) node).blockSuccessorCount();
+            } else {
+                result += 1;
+            }
+        }
+        return Math.max(1, result);
+    }
+
+
+    @Override
+    public void recordConcreteMethodAssumption(RiResolvedMethod method, RiResolvedType context, RiResolvedMethod impl) {
+        assumptions.recordConcreteMethod(method, context, impl);
+    }
+
+    @Override
+    public void recordMethodContentsAssumption(RiResolvedMethod method) {
+        if (assumptions != null) {
+            assumptions.recordMethodContents(method);
+        }
+    }
+
+    private static int computeInliningLevel(Invoke invoke) {
+        int count = 0;
+        FrameState curState = invoke.stateAfter();
+        while (curState != null) {
+            count++;
+            curState = curState.outerFrameState();
+        }
+        return count - 1;
+    }
+
+    private static InliningPolicy createInliningPolicy() {
+        switch(GraalOptions.InliningPolicy) {
+            case 0: return new WeightBasedInliningPolicy();
+            case 1: return new C1StaticSizeBasedInliningPolicy();
+            case 2: return new MinimumCodeSizeBasedInliningPolicy();
+            case 3: return new DynamicSizeBasedInliningPolicy();
+            case 4: return new GreedySizeBasedInliningPolicy();
+            default:
+                GraalInternalError.shouldNotReachHere();
+                return null;
+        }
+    }
+
+    private WeightComputationPolicy createWeightComputationPolicy() {
+        switch(GraalOptions.WeightComputationPolicy) {
+            case 0: return new ExecutionCountBasedWeightComputationPolicy();
+            case 1: return new BytecodeSizeBasedWeightComputationPolicy();
+            case 2: return new ComplexityBasedWeightComputationPolicy();
+            default:
+                GraalInternalError.shouldNotReachHere();
+                return null;
+        }
+    }
+
+    private interface InliningPolicy {
+        boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info);
+    }
+
+    private static class WeightBasedInliningPolicy implements InliningPolicy {
+        @Override
+        public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) {
+            if (GraalOptions.SmallCompiledCodeSize >= 0 && info.compiledCodeSize() > GraalOptions.SmallCompiledCodeSize) {
+                return false;
+            }
+
+            double penalty = Math.pow(GraalOptions.InliningSizePenaltyExp, callerGraph.getNodeCount() / (double) GraalOptions.MaximumDesiredSize) / GraalOptions.InliningSizePenaltyExp;
+            if (info.weight > GraalOptions.MaximumInlineWeight / (1 + penalty * GraalOptions.InliningSizePenalty)) {
+                Debug.log("not inlining (cut off by weight): %e", info.weight);
+                return false;
+            }
+            return true;
+        }
+    }
+
+    private static class C1StaticSizeBasedInliningPolicy implements InliningPolicy {
+        @Override
+        public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) {
+            double maxSize = Math.max(GraalOptions.MaximumTrivialSize, Math.pow(GraalOptions.NestedInliningSizeRatio, info.level) * GraalOptions.MaximumInlineSize);
+            return info.weight <= maxSize;
+        }
+    }
+
+    private static class MinimumCodeSizeBasedInliningPolicy implements InliningPolicy {
+        @Override
+        public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) {
+            assert GraalOptions.ProbabilityAnalysis;
+            if (GraalOptions.SmallCompiledCodeSize >= 0 && info.compiledCodeSize() > GraalOptions.SmallCompiledCodeSize) {
+                return false;
+            }
+
+            double inlineWeight = Math.min(GraalOptions.ProbabilityCapForInlining, info.invoke.probability());
+            double maxSize = Math.pow(GraalOptions.NestedInliningSizeRatio, info.level) * GraalOptions.MaximumInlineSize * inlineWeight;
+            maxSize = Math.max(GraalOptions.MaximumTrivialSize, maxSize);
+            return info.weight <= maxSize;
+        }
+    }
+
+    private static class DynamicSizeBasedInliningPolicy implements InliningPolicy {
+        @Override
+        public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) {
+            assert GraalOptions.ProbabilityAnalysis;
+            if (GraalOptions.SmallCompiledCodeSize >= 0 && info.compiledCodeSize() > GraalOptions.SmallCompiledCodeSize) {
+                return false;
+            }
+
+            double inlineBoost = Math.min(GraalOptions.ProbabilityCapForInlining, info.invoke.probability()) + Math.log10(Math.max(1, info.invoke.probability() - GraalOptions.ProbabilityCapForInlining + 1));
+            double maxSize = Math.pow(GraalOptions.NestedInliningSizeRatio, info.level) * GraalOptions.MaximumInlineSize;
+            maxSize = maxSize + maxSize * inlineBoost;
+            maxSize = Math.min(GraalOptions.MaximumGreedyInlineSize, Math.max(GraalOptions.MaximumTrivialSize, maxSize));
+            return info.weight <= maxSize;
+        }
+    }
+
+    private static class GreedySizeBasedInliningPolicy implements InliningPolicy {
+        @Override
+        public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) {
+            assert GraalOptions.ProbabilityAnalysis;
+            if (GraalOptions.SmallCompiledCodeSize >= 0 && info.compiledCodeSize() > GraalOptions.SmallCompiledCodeSize) {
+                return false;
+            }
+
+            double inlineRatio = Math.min(GraalOptions.ProbabilityCapForInlining, info.invoke.probability());
+            double maxSize = Math.pow(GraalOptions.NestedInliningSizeRatio, info.level) * GraalOptions.MaximumGreedyInlineSize * inlineRatio;
+            maxSize = Math.max(maxSize, GraalOptions.MaximumTrivialSize);
+            return info.weight <= maxSize;
+        }
+    }
+
+    private interface WeightComputationPolicy {
+        double computeWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke, boolean preferredInvoke);
+    }
+
+    private class ExecutionCountBasedWeightComputationPolicy implements WeightComputationPolicy {
+        @Override
+        public double computeWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke, boolean preferredInvoke) {
+            double ratio;
+            if (preferredInvoke) {
+                ratio = 1000000;
+            } else {
+                if (GraalOptions.ProbabilityAnalysis) {
+                    ratio = invoke.node().probability();
+                } else {
+                    RiProfilingInfo profilingInfo = method.profilingInfo();
+                    int executionCount = profilingInfo.getExecutionCount(invoke.bci());
+                    if (executionCount > 0) {
+                        RiResolvedMethod parent = invoke.stateAfter().method();
+                        ratio = executionCount / (float) parent.invocationCount();
+                    } else {
+                        ratio = 1;
+                    }
+                }
+            }
+
+            final double normalSize;
+            // TODO(ls) get rid of this magic, it's here to emulate the old behavior for the time being
+            if (ratio < 0.01) {
+                ratio = 0.01;
+            }
+            if (ratio < 0.5) {
+                normalSize = 10 * ratio / 0.5;
+            } else if (ratio < 2) {
+                normalSize = 10 + (35 - 10) * (ratio - 0.5) / 1.5;
+            } else if (ratio < 20) {
+                normalSize = 35;
+            } else if (ratio < 40) {
+                normalSize = 35 + (350 - 35) * (ratio - 20) / 20;
+            } else {
+                normalSize = 350;
+            }
+
+            int count;
+            if (GraalOptions.ParseBeforeInlining) {
+                if (!parsedMethods.containsKey(method)) {
+                    StructuredGraph newGraph = new StructuredGraph(method);
+                    if (plan != null) {
+                        plan.runPhases(PhasePosition.AFTER_PARSING, newGraph);
+                    }
+                    if (GraalOptions.OptCanonicalizer) {
+                        new CanonicalizerPhase(target, runtime, assumptions).apply(newGraph);
+                    }
+                    count = graphComplexity(newGraph);
+                    parsedMethods.put(method, count);
+                } else {
+                    count = parsedMethods.get(method);
+                }
+            } else {
+                count = method.codeSize();
+            }
+
+            return count / normalSize;
+        }
+    }
+
+    private static class BytecodeSizeBasedWeightComputationPolicy implements WeightComputationPolicy {
+        @Override
+        public double computeWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke, boolean preferredInvoke) {
+            double codeSize = method.codeSize();
+            if (preferredInvoke) {
+                codeSize = codeSize / GraalOptions.BoostInliningForEscapeAnalysis;
+            }
+            return codeSize;
+        }
+    }
+
+    private static class ComplexityBasedWeightComputationPolicy implements WeightComputationPolicy {
+        @Override
+        public double computeWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke, boolean preferredInvoke) {
+            double complexity = method.compilationComplexity();
+            if (preferredInvoke) {
+                complexity = complexity / GraalOptions.BoostInliningForEscapeAnalysis;
+            }
+            return complexity;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InsertStateAfterPlaceholderPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,38 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import com.oracle.max.graal.nodes.*;
+
+public class InsertStateAfterPlaceholderPhase extends Phase {
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (ReturnNode ret : graph.getNodes(ReturnNode.class)) {
+            PlaceholderNode p = graph.add(new PlaceholderNode());
+            p.setStateAfter(graph.add(new FrameState(null, FrameState.AFTER_BCI, 0, 0, false, false)));
+            graph.addBeforeFixed(ret, p);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/IntrinsificationPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,77 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+
+public class IntrinsificationPhase extends Phase {
+
+    private final GraalRuntime runtime;
+
+    public IntrinsificationPhase(GraalRuntime runtime) {
+        this.runtime = runtime;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (InvokeNode invoke : graph.getNodes(InvokeNode.class)) {
+            tryIntrinsify(invoke, runtime);
+        }
+        for (InvokeWithExceptionNode invoke : graph.getNodes(InvokeWithExceptionNode.class)) {
+            tryIntrinsify(invoke, runtime);
+        }
+    }
+
+    public static boolean canIntrinsify(Invoke invoke, RiResolvedMethod target, GraalRuntime runtime) {
+        return getIntrinsicGraph(invoke, target, runtime) != null;
+    }
+
+    private static void tryIntrinsify(Invoke invoke, GraalRuntime runtime) {
+        RiResolvedMethod target = invoke.callTarget().targetMethod();
+        if (target != null) {
+            tryIntrinsify(invoke, target, runtime);
+        }
+    }
+
+    private static void tryIntrinsify(Invoke invoke, RiResolvedMethod target, GraalRuntime runtime) {
+        StructuredGraph intrinsicGraph = getIntrinsicGraph(invoke, target, runtime);
+        if (intrinsicGraph != null) {
+            Debug.log(" > Intrinsify %s", target);
+            InliningUtil.inline(invoke, intrinsicGraph, true);
+        }
+    }
+
+    private static StructuredGraph getIntrinsicGraph(Invoke invoke, RiResolvedMethod target, GraalRuntime runtime) {
+        StructuredGraph intrinsicGraph = (StructuredGraph) target.compilerStorage().get(Graph.class);
+        if (intrinsicGraph == null) {
+            // TODO (ph) remove once all intrinsics are available via RiMethod
+            intrinsicGraph = runtime.intrinsicGraph(invoke.stateAfter().method(), invoke.bci(), target, invoke.callTarget().arguments());
+        }
+        return intrinsicGraph;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,144 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.cfg.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+public class LoweringPhase extends Phase {
+
+    private final GraalRuntime runtime;
+
+    public LoweringPhase(GraalRuntime runtime) {
+        this.runtime = runtime;
+    }
+
+    @Override
+    protected void run(final StructuredGraph graph) {
+        ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, false, true, true);
+
+        NodeBitMap processed = graph.createNodeBitMap();
+        NodeBitMap activeGuards = graph.createNodeBitMap();
+        processBlock(cfg.getStartBlock(), activeGuards, processed, null);
+
+        processed.negate();
+        final CiLoweringTool loweringTool = new CiLoweringTool() {
+
+            @Override
+            public Node getGuardAnchor() {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public GraalRuntime getRuntime() {
+                return runtime;
+            }
+
+            @Override
+            public Node createGuard(Node condition) {
+                // TODO(tw): Explain why this must not be called on floating nodes.
+                throw new UnsupportedOperationException();
+            }
+        };
+        for (Node node : processed) {
+            if (node instanceof Lowerable) {
+                assert !(node instanceof FixedNode) || node.predecessor() == null;
+                ((Lowerable) node).lower(loweringTool);
+            }
+        }
+    }
+
+    private void processBlock(Block block, NodeBitMap activeGuards, NodeBitMap processed, FixedNode parentAnchor) {
+
+        FixedNode anchor = parentAnchor;
+        if (anchor == null) {
+            anchor = block.getBeginNode();
+        }
+        process(block, activeGuards, processed, anchor);
+
+        // Process always reached block first.
+        Block alwaysReachedBlock = block.getPostdominator();
+        if (alwaysReachedBlock != null && alwaysReachedBlock.getDominator() == block) {
+            assert alwaysReachedBlock.getDominator() == block;
+            processBlock(alwaysReachedBlock, activeGuards, processed, anchor);
+        }
+
+        // Now go for the other dominators.
+        for (Block dominated : block.getDominated()) {
+            if (dominated != alwaysReachedBlock) {
+                assert dominated.getDominator() == block;
+                processBlock(dominated, activeGuards, processed, null);
+            }
+        }
+
+        if (parentAnchor == null) {
+            for (GuardNode guard : anchor.usages().filter(GuardNode.class)) {
+                activeGuards.clear(guard);
+            }
+        }
+    }
+
+    private void process(final Block b, final NodeBitMap activeGuards, NodeBitMap processed, final Node anchor) {
+
+        final CiLoweringTool loweringTool = new CiLoweringTool() {
+
+            @Override
+            public Node getGuardAnchor() {
+                return anchor;
+            }
+
+            @Override
+            public GraalRuntime getRuntime() {
+                return runtime;
+            }
+
+            @Override
+            public Node createGuard(Node condition) {
+                FixedNode guardAnchor = (FixedNode) getGuardAnchor();
+                if (GraalOptions.OptEliminateGuards) {
+                    for (Node usage : condition.usages()) {
+                        if (activeGuards.isMarked(usage)) {
+                            return usage;
+                        }
+                    }
+                }
+                GuardNode newGuard = guardAnchor.graph().unique(new GuardNode((BooleanNode) condition, guardAnchor));
+                activeGuards.grow();
+                activeGuards.mark(newGuard);
+                return newGuard;
+            }
+        };
+
+        // Lower the instructions of this block.
+        for (Node node : b.getNodes()) {
+            processed.mark(node);
+            if (node instanceof Lowerable) {
+                ((Lowerable) node).lower(loweringTool);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.nodes.*;
+
+public abstract class Phase {
+
+    private String name;
+
+    protected Phase() {
+        this.name = this.getClass().getSimpleName();
+        if (name.endsWith("Phase")) {
+            name = name.substring(0, name.length() - "Phase".length());
+        }
+    }
+
+    protected Phase(String name) {
+        this.name = name;
+    }
+
+    protected String getDetailedName() {
+        return getName();
+    }
+
+    public final void apply(final StructuredGraph graph) {
+        apply(graph, true);
+    }
+
+    public final void apply(final StructuredGraph graph, final boolean dumpGraph) {
+        Debug.scope(name, this, new Runnable() {
+            public void run() {
+                Phase.this.run(graph);
+                if (dumpGraph) {
+                    Debug.dump(graph, "After phase %s", name);
+                }
+            }
+        });
+    }
+
+    public final String getName() {
+        return name;
+    }
+
+    protected abstract void run(StructuredGraph graph);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/PhasePlan.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,85 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import java.util.*;
+
+import com.oracle.max.graal.nodes.*;
+
+/**
+ * Tells the compiler about additional phases that need to be executed during compilation.
+ */
+public class PhasePlan {
+    /**
+     * The compilation is split into the following sections:
+     * ========================================================================
+     * Period 1: High-level nodes. (Graph building)
+     * ========================================================================
+     * Runtime-specific lowering.
+     * ========================================================================
+     * Period 2: Mid-level nodes. (Memory dependence graph)
+     * ========================================================================
+     * Target-specific lowering, de-SSA.
+     * ========================================================================
+     * Period 3: Low-level nodes. (Register allocation, code generation)
+     * ========================================================================
+     *
+     * A compiler extension phase can chose to run at the end of periods 1-3.
+     */
+    public static enum PhasePosition {
+        AFTER_PARSING,
+        HIGH_LEVEL,
+        MID_LEVEL,
+        LOW_LEVEL
+    }
+
+    public static final PhasePlan DEFAULT = new PhasePlan();
+
+    @SuppressWarnings("unchecked")
+    private final ArrayList<Phase>[] phases = new ArrayList[PhasePosition.values().length];
+
+    private final Set<Class<? extends Phase>> disabledPhases = new HashSet<>();
+
+    public void addPhase(PhasePosition pos, Phase phase) {
+        if (phases[pos.ordinal()] == null) {
+            phases[pos.ordinal()] = new ArrayList<>();
+        }
+        phases[pos.ordinal()].add(phase);
+    }
+
+    public void runPhases(PhasePosition pos, StructuredGraph graph) {
+        if (phases[pos.ordinal()] != null) {
+            for (Phase p : phases[pos.ordinal()]) {
+                p.apply(graph);
+            }
+        }
+    }
+
+    public void disablePhase(Class<? extends Phase> clazz) {
+        disabledPhases.add(clazz);
+    }
+
+    public boolean isPhaseDisabled(Class<? extends Phase> clazz) {
+        return disabledPhases.contains(clazz);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/PhiStampPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,61 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import com.oracle.max.graal.nodes.*;
+
+public class PhiStampPhase extends Phase {
+    @Override
+    protected void run(StructuredGraph graph) {
+        // Infer phis stopping at loop phis.
+        for (PhiNode phi : graph.getNodes(PhiNode.class)) {
+            inferPhi(phi);
+        }
+
+        // Start iterative inference for loop phis.
+        if (graph.hasLoops()) {
+            for (PhiNode phi : graph.getNodes(PhiNode.class)) {
+                if (phi.isLoopPhi()) {
+                    iterativeInferPhi(phi);
+                }
+            }
+        }
+    }
+
+    private void iterativeInferPhi(PhiNode phi) {
+        if (phi.inferStamp()) {
+            for (PhiNode phiUsage : phi.usages().filter(PhiNode.class)) {
+                iterativeInferPhi(phiUsage);
+            }
+        }
+    }
+
+    private void inferPhi(PhiNode phi) {
+        for (PhiNode phiInput : phi.values().filter(PhiNode.class)) {
+            if (!phiInput.isLoopPhi()) {
+                inferPhi(phiInput);
+            }
+        }
+        phi.inferStamp();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ReadEliminationPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,48 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.extended.*;
+
+public class ReadEliminationPhase extends Phase {
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (FloatingReadNode n : graph.getNodes(FloatingReadNode.class)) {
+            if (n.dependencies().size() > 0) {
+                assert n.dependencies().size() == 1;
+                Node memoryInput = n.dependencies().get(0);
+                if (memoryInput instanceof WriteNode) {
+                    WriteNode other = (WriteNode) memoryInput;
+                    if (other.object() == n.object() && other.location() == n.location()) {
+                        Debug.log("Eliminated memory read %1.1s and replaced with node %s", n, other.value());
+                        graph.replaceFloating(n, other.value());
+                    }
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/SafepointPollingEliminationPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import com.oracle.max.graal.graph.iterators.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.util.*;
+
+public class SafepointPollingEliminationPhase extends Phase {
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (LoopEndNode loopEnd : graph.getNodes(LoopEndNode.class)) {
+            NodeIterable<FixedNode> it = NodeIterators.dominators(loopEnd).until(loopEnd.loopBegin());
+            for (FixedNode n : it) {
+                if (n instanceof Invoke) {
+                    loopEnd.setSafepointPolling(false);
+                    break;
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/SnippetIntrinsificationPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,203 @@
+/*
+ * 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.max.graal.compiler.phases;
+
+import java.lang.reflect.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.graph.Node.ConstantNodeParameter;
+import com.oracle.max.graal.graph.Node.NodeIntrinsic;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.java.*;
+import com.oracle.max.graal.nodes.util.*;
+
+public class SnippetIntrinsificationPhase extends Phase {
+
+    private final RiRuntime runtime;
+    private final BoxingMethodPool pool;
+
+    public SnippetIntrinsificationPhase(RiRuntime runtime, BoxingMethodPool pool) {
+        this.runtime = runtime;
+        this.pool = pool;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (Invoke i : graph.getInvokes()) {
+            tryIntrinsify(i);
+        }
+    }
+
+    private void tryIntrinsify(Invoke invoke) {
+        RiResolvedMethod target = invoke.callTarget().targetMethod();
+        NodeIntrinsic intrinsic = target.getAnnotation(Node.NodeIntrinsic.class);
+        if (intrinsic != null) {
+            Class< ? >[] parameterTypes = CiUtil.signatureToTypes(target.signature(), target.holder());
+
+            // Prepare the arguments for the reflective constructor call on the node class.
+            Object[] nodeConstructorArguments = prepareArguments(invoke, parameterTypes, target);
+
+            // Create the new node instance.
+            Class< ? > c = getNodeClass(target, intrinsic);
+            Node newInstance = createNodeInstance(c, parameterTypes, nodeConstructorArguments);
+
+            // Replace the invoke with the new node.
+            invoke.node().graph().add(newInstance);
+            invoke.intrinsify(newInstance);
+
+            // Clean up checkcast instructions inserted by javac if the return type is generic.
+            cleanUpReturnCheckCast(newInstance);
+        }
+    }
+
+    private Object[] prepareArguments(Invoke invoke, Class< ? >[] parameterTypes, RiResolvedMethod target) {
+        NodeInputList<ValueNode> arguments = invoke.callTarget().arguments();
+        Object[] nodeConstructorArguments = new Object[arguments.size()];
+        for (int i = 0; i < nodeConstructorArguments.length; ++i) {
+            int parameterIndex = i;
+            if (!invoke.callTarget().isStatic()) {
+                parameterIndex--;
+            }
+            ValueNode argument = tryBoxingElimination(parameterIndex, target, arguments.get(i));
+            ConstantNodeParameter param = CiUtil.getParameterAnnotation(ConstantNodeParameter.class, parameterIndex, target);
+            if (param != null) {
+                assert argument instanceof ConstantNode : "parameter " + parameterIndex + " must be compile time constant for " + invoke.callTarget().targetMethod();
+                ConstantNode constantNode = (ConstantNode) argument;
+                Object o = constantNode.asConstant().boxedValue();
+                if (o instanceof Class< ? >) {
+                    nodeConstructorArguments[i] = runtime.getType((Class< ? >) o);
+                    parameterTypes[i] = RiResolvedType.class;
+                } else {
+                    nodeConstructorArguments[i] = o;
+                }
+            } else {
+                nodeConstructorArguments[i] = argument;
+                parameterTypes[i] = ValueNode.class;
+            }
+        }
+        return nodeConstructorArguments;
+    }
+
+    private static Class< ? > getNodeClass(RiResolvedMethod target, NodeIntrinsic intrinsic) {
+        Class< ? > result = intrinsic.value();
+        if (result == NodeIntrinsic.class) {
+            result = target.holder().toJava();
+        }
+        assert Node.class.isAssignableFrom(result);
+        return result;
+    }
+
+    private ValueNode tryBoxingElimination(int parameterIndex, RiResolvedMethod target, ValueNode node) {
+        if (parameterIndex >= 0) {
+            Type type = target.getGenericParameterTypes()[parameterIndex];
+            if (type instanceof TypeVariable) {
+                TypeVariable typeVariable = (TypeVariable) type;
+                if (typeVariable.getBounds().length == 1) {
+                    Type boundType = typeVariable.getBounds()[0];
+                    if (boundType instanceof Class && ((Class) boundType).getSuperclass() == null) {
+                        // Unbound generic => try boxing elimination
+                        if (node.usages().size() == 2) {
+                            if (node instanceof Invoke) {
+                                Invoke invokeNode = (Invoke) node;
+                                MethodCallTargetNode callTarget = invokeNode.callTarget();
+                                if (pool.isBoxingMethod(callTarget.targetMethod())) {
+                                    FrameState stateAfter = invokeNode.stateAfter();
+                                    assert stateAfter.usages().size() == 1;
+                                    invokeNode.node().replaceAtUsages(null);
+                                    ValueNode result = callTarget.arguments().get(0);
+                                    StructuredGraph graph = (StructuredGraph) node.graph();
+                                    if (invokeNode instanceof InvokeWithExceptionNode) {
+                                        // Destroy exception edge & clear stateAfter.
+                                        InvokeWithExceptionNode invokeWithExceptionNode = (InvokeWithExceptionNode) invokeNode;
+
+                                        invokeWithExceptionNode.killExceptionEdge();
+                                        graph.removeSplit(invokeWithExceptionNode, InvokeWithExceptionNode.NORMAL_EDGE);
+                                    } else {
+                                        graph.removeFixed((InvokeNode) invokeNode);
+                                    }
+                                    stateAfter.safeDelete();
+                                    GraphUtil.propagateKill(callTarget);
+                                    return result;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return node;
+    }
+
+    private static Node createNodeInstance(Class< ? > nodeClass, Class< ? >[] parameterTypes, Object[] nodeConstructorArguments) {
+
+        Constructor< ? > constructor;
+        try {
+            constructor = nodeClass.getDeclaredConstructor(parameterTypes);
+            constructor.setAccessible(true);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        try {
+            return (ValueNode) constructor.newInstance(nodeConstructorArguments);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void cleanUpReturnCheckCast(Node newInstance) {
+        if (newInstance instanceof ValueNode && ((ValueNode) newInstance).kind() != CiKind.Object) {
+            StructuredGraph graph = (StructuredGraph) newInstance.graph();
+            for (CheckCastNode checkCastNode : newInstance.usages().filter(CheckCastNode.class).snapshot()) {
+                for (Node checkCastUsage : checkCastNode.usages().snapshot()) {
+                    if (checkCastUsage instanceof ValueAnchorNode) {
+                        ValueAnchorNode valueAnchorNode = (ValueAnchorNode) checkCastUsage;
+                        graph.removeFixed(valueAnchorNode);
+                    } else if (checkCastUsage instanceof MethodCallTargetNode) {
+                        MethodCallTargetNode checkCastCallTarget = (MethodCallTargetNode) checkCastUsage;
+                        assert pool.isUnboxingMethod(checkCastCallTarget.targetMethod());
+                        Invoke invokeNode = checkCastCallTarget.invoke();
+                        invokeNode.node().replaceAtUsages(newInstance);
+                        if (invokeNode instanceof InvokeWithExceptionNode) {
+                            // Destroy exception edge & clear stateAfter.
+                            InvokeWithExceptionNode invokeWithExceptionNode = (InvokeWithExceptionNode) invokeNode;
+
+                            invokeWithExceptionNode.killExceptionEdge();
+                            graph.removeSplit(invokeWithExceptionNode, InvokeWithExceptionNode.NORMAL_EDGE);
+                        } else {
+                            graph.removeFixed((InvokeNode) invokeNode);
+                        }
+                        checkCastCallTarget.safeDelete();
+                    } else if (checkCastUsage instanceof FrameState) {
+                        checkCastUsage.replaceFirstInput(checkCastNode, null);
+                    } else {
+                        assert false : "unexpected checkcast usage: " + checkCastUsage;
+                    }
+                }
+                checkCastNode.safeDelete();
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/BlockClosure.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.compiler.schedule;
+
+import com.oracle.max.graal.lir.cfg.*;
+
+/**
+ * The {@code BlockClosure} interface represents a closure for iterating over blocks.
+ */
+public interface BlockClosure {
+    void apply(Block block);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/SchedulePhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.compiler.schedule;
+
+import java.util.*;
+
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.graph.Node.Verbosity;
+import com.oracle.max.graal.lir.cfg.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.virtual.*;
+
+public class SchedulePhase extends Phase {
+    private ControlFlowGraph cfg;
+    private NodeMap<Block> earliestCache;
+
+    private BlockMap<List<Node>> nodesFor;
+
+    public SchedulePhase() {
+        super("Schedule");
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        cfg = ControlFlowGraph.compute(graph, true, true, true, false);
+        earliestCache = graph.createNodeMap();
+        nodesFor = new BlockMap<>(cfg);
+
+        assignBlockToNodes(graph);
+        sortNodesWithinBlocks(graph);
+    }
+
+    public void scheduleGraph() {
+        for (Block block : cfg.getBlocks()) {
+            List<Node> nodeList = nodesFor.get(block);
+            ScheduledNode last = null;
+            for (Node node : nodeList) {
+                if (!(node instanceof FrameState)) {
+                    if (last != null) {
+                        last.setScheduledNext((ScheduledNode) node);
+                    }
+                    last = (ScheduledNode) node;
+                }
+            }
+        }
+    }
+
+    public ControlFlowGraph getCFG() {
+        return cfg;
+    }
+
+    public BlockMap<List<Node>> getNodesFor() {
+        return nodesFor;
+    }
+
+    public List<Node> nodesFor(Block block) {
+        return nodesFor.get(block);
+    }
+
+    private void assignBlockToNodes(StructuredGraph graph) {
+        for (Block block : cfg.getBlocks()) {
+            List<Node> nodes = new ArrayList<>();
+            assert nodesFor.get(block) == null;
+            nodesFor.put(block, nodes);
+            for (Node node : block.getNodes()) {
+                nodes.add(node);
+            }
+        }
+
+        for (Node n : graph.getNodes()) {
+            assignBlockToNode(n);
+        }
+    }
+
+    private void assignBlockToNode(Node n) {
+        if (n == null) {
+            return;
+        }
+
+        assert !n.isDeleted();
+
+        Block prevBlock = cfg.getNodeToBlock().get(n);
+        if (prevBlock != null) {
+            return;
+        }
+        assert !(n instanceof PhiNode) : n;
+        // if in CFG, schedule at the latest position possible in the outermost loop possible
+        Block latestBlock = latestBlock(n);
+        Block block;
+        if (latestBlock == null) {
+            block = earliestBlock(n);
+        } else if (GraalOptions.ScheduleOutOfLoops && !(n instanceof VirtualObjectFieldNode) && !(n instanceof VirtualObjectNode)) {
+            Block earliestBlock = earliestBlock(n);
+            block = scheduleOutOfLoops(n, latestBlock, earliestBlock);
+            assert earliestBlock.dominates(block) : "Graph can not be scheduled : inconsistent for " + n;
+        } else {
+            block = latestBlock;
+        }
+        assert !(n instanceof MergeNode);
+        cfg.getNodeToBlock().set(n, block);
+        nodesFor.get(block).add(n);
+    }
+
+    private Block latestBlock(Node n) {
+        Block block = null;
+        for (Node succ : n.successors()) {
+            if (succ == null) {
+                continue;
+            }
+            assignBlockToNode(succ);
+            block = getCommonDominator(block, cfg.getNodeToBlock().get(succ));
+        }
+        ensureScheduledUsages(n);
+        CommonDominatorBlockClosure cdbc = new CommonDominatorBlockClosure(block);
+        for (Node usage : n.usages()) {
+            blocksForUsage(n, usage, cdbc);
+        }
+        return cdbc.block;
+    }
+
+    private class CommonDominatorBlockClosure implements BlockClosure {
+        public Block block;
+        public CommonDominatorBlockClosure(Block block) {
+            this.block = block;
+        }
+        @Override
+        public void apply(Block newBlock) {
+            this.block = getCommonDominator(this.block, newBlock);
+        }
+    }
+
+    private Block earliestBlock(Node n) {
+        Block earliest = cfg.getNodeToBlock().get(n);
+        if (earliest != null) {
+            return earliest;
+        }
+        earliest = earliestCache.get(n);
+        if (earliest != null) {
+            return earliest;
+        }
+        BitMap bits = new BitMap(cfg.getBlocks().length);
+        ArrayList<Node> before = new ArrayList<>();
+        if (n.predecessor() != null) {
+            before.add(n.predecessor());
+        }
+        for (Node input : n.inputs()) {
+            before.add(input);
+        }
+        for (Node pred : before) {
+            if (pred == null) {
+                continue;
+            }
+            Block b = earliestBlock(pred);
+            if (!bits.get(b.getId())) {
+                earliest = b;
+                do {
+                    bits.set(b.getId());
+                    b = b.getDominator();
+                } while(b != null && !bits.get(b.getId()));
+            }
+        }
+        if (earliest == null) {
+            Block start = cfg.getNodeToBlock().get(((StructuredGraph) n.graph()).start());
+            assert start != null;
+            return start;
+        }
+        earliestCache.set(n, earliest);
+        return earliest;
+    }
+
+
+    private static Block scheduleOutOfLoops(Node n, Block latestBlock, Block earliest) {
+        assert latestBlock != null : "no latest : " + n;
+        Block cur = latestBlock;
+        Block result = latestBlock;
+        while (cur.getLoop() != null && cur != earliest && cur.getDominator() != null) {
+            Block dom = cur.getDominator();
+            if (dom.getLoopDepth() < result.getLoopDepth()) {
+                result = dom;
+            }
+            cur = dom;
+        }
+        return result;
+    }
+
+    private void blocksForUsage(Node node, Node usage, BlockClosure closure) {
+        if (usage instanceof PhiNode) {
+            PhiNode phi = (PhiNode) usage;
+            MergeNode merge = phi.merge();
+            Block mergeBlock = cfg.getNodeToBlock().get(merge);
+            assert mergeBlock != null : "no block for merge " + merge.toString(Verbosity.Id);
+            for (int i = 0; i < phi.valueCount(); ++i) {
+                if (phi.valueAt(i) == node) {
+                    if (mergeBlock.getPredecessors().size() <= i) {
+                        TTY.println(merge.toString());
+                        TTY.println(phi.toString());
+                        TTY.println(merge.cfgPredecessors().toString());
+                        TTY.println(mergeBlock.getPredecessors().toString());
+                        TTY.println(phi.inputs().toString());
+                        TTY.println("value count: " + phi.valueCount());
+                    }
+                    closure.apply(mergeBlock.getPredecessors().get(i));
+                }
+            }
+        } else if (usage instanceof FrameState && ((FrameState) usage).block() != null) {
+            MergeNode merge = ((FrameState) usage).block();
+            Block block = null;
+            for (Node pred : merge.cfgPredecessors()) {
+                block = getCommonDominator(block, cfg.getNodeToBlock().get(pred));
+            }
+            closure.apply(block);
+        } else {
+            assignBlockToNode(usage);
+            closure.apply(cfg.getNodeToBlock().get(usage));
+        }
+    }
+
+    private void ensureScheduledUsages(Node node) {
+        for (Node usage : node.usages().snapshot()) {
+            assignBlockToNode(usage);
+        }
+        // now true usages are ready
+    }
+
+    private static Block getCommonDominator(Block a, Block b) {
+        if (a == null) {
+            return b;
+        }
+        if (b == null) {
+            return a;
+        }
+        return ControlFlowGraph.commonDominator(a, b);
+    }
+
+    private void sortNodesWithinBlocks(StructuredGraph graph) {
+        NodeBitMap map = graph.createNodeBitMap();
+        for (Block b : cfg.getBlocks()) {
+            sortNodesWithinBlocks(b, map);
+        }
+    }
+
+    private void sortNodesWithinBlocks(Block b, NodeBitMap map) {
+        List<Node> instructions = nodesFor.get(b);
+        List<Node> sortedInstructions = new ArrayList<>(instructions.size() + 2);
+
+        assert !map.isMarked(b.getBeginNode()) && cfg.blockFor(b.getBeginNode()) == b;
+        assert !map.isMarked(b.getEndNode()) && cfg.blockFor(b.getEndNode()) == b;
+
+        for (Node i : instructions) {
+            addToSorting(b, i, sortedInstructions, map);
+        }
+
+        // Make sure that last node gets really last (i.e. when a frame state successor hangs off it).
+        Node lastSorted = sortedInstructions.get(sortedInstructions.size() - 1);
+        if (lastSorted != b.getEndNode()) {
+            int idx = sortedInstructions.indexOf(b.getEndNode());
+            boolean canNotMove = false;
+            for (int i = idx + 1; i < sortedInstructions.size(); i++) {
+                if (sortedInstructions.get(i).inputs().contains(b.getEndNode())) {
+                    canNotMove = true;
+                    break;
+                }
+            }
+            if (canNotMove) {
+                // (cwi) this was the assertion commented out below.  However, it is failing frequently when the
+                // scheduler is used for debug printing in early compiler phases. This was annoying during debugging
+                // when an exception breakpoint is set for assertion errors, so I changed it to a bailout.
+                if (b.getEndNode() instanceof ControlSplitNode) {
+                    throw new GraalInternalError("Schedule is not possible : needs to move a node after the last node of the block which can not be move").
+                    addContext(lastSorted).
+                    addContext(b.getEndNode());
+                }
+                //assert !(b.lastNode() instanceof ControlSplitNode);
+
+                //b.setLastNode(lastSorted);
+            } else {
+                sortedInstructions.remove(b.getEndNode());
+                sortedInstructions.add(b.getEndNode());
+            }
+        }
+        nodesFor.put(b, sortedInstructions);
+    }
+
+    private void addToSorting(Block b, Node i, List<Node> sortedInstructions, NodeBitMap map) {
+        if (i == null || map.isMarked(i) || cfg.getNodeToBlock().get(i) != b || i instanceof PhiNode || i instanceof LocalNode) {
+            return;
+        }
+
+        if (i instanceof WriteNode) {
+            // TODO(tw): Make sure every ReadNode that is connected to the same memory state is executed before every write node.
+            // WriteNode wn = (WriteNode) i;
+        }
+
+        FrameState state = null;
+        WriteNode writeNode = null;
+        for (Node input : i.inputs()) {
+            if (input instanceof WriteNode && !map.isMarked(input) && cfg.getNodeToBlock().get(input) == b) {
+                writeNode = (WriteNode) input;
+            } else if (input instanceof FrameState) {
+                state = (FrameState) input;
+            } else {
+                addToSorting(b, input, sortedInstructions, map);
+            }
+        }
+
+        if (i.predecessor() != null) {
+            addToSorting(b, i.predecessor(), sortedInstructions, map);
+        }
+
+        map.mark(i);
+
+        addToSorting(b, state, sortedInstructions, map);
+        assert writeNode == null || !map.isMarked(writeNode);
+        addToSorting(b, writeNode, sortedInstructions, map);
+
+        // Now predecessors and inputs are scheduled => we can add this node.
+        sortedInstructions.add(i);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/UnscheduleNodes.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2012, 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.max.graal.compiler.schedule;
+
+import java.util.*;
+
+import com.oracle.max.graal.compiler.graph.*;
+import com.oracle.max.graal.compiler.types.*;
+import com.oracle.max.graal.nodes.*;
+
+class UnscheduleState implements MergeableState<UnscheduleState> {
+
+    public FixedWithNextNode last;
+
+    @Override
+    public boolean merge(MergeNode merge, Collection<UnscheduleState> withStates) {
+        last = null;
+        return true;
+    }
+
+    @Override
+    public void loopBegin(LoopBeginNode loop) {
+        last = null;
+    }
+
+    @Override
+    public void loopEnds(LoopBeginNode loop, Collection<UnscheduleState> loopEndStates) {
+        last = null;
+    }
+
+    @Override
+    public void afterSplit(FixedNode node) {
+        last = null;
+    }
+
+    @Override
+    public UnscheduleState clone() {
+        return new UnscheduleState();
+    }
+}
+
+public class UnscheduleNodes extends ScheduledNodeIterator<UnscheduleState> {
+
+    public UnscheduleNodes(FixedNode start) {
+        super(start, new UnscheduleState());
+    }
+
+    @Override
+    protected void node(ScheduledNode node) {
+        if (node instanceof FixedNode) {
+            if (state.last != null) {
+                state.last.setNext((FixedNode) node);
+            }
+            if (node instanceof FixedWithNextNode) {
+                state.last = (FixedWithNextNode) node;
+            }
+        } else {
+            node.setScheduledNext(null);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/Backend.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.compiler.target;
+
+import java.lang.reflect.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.cri.xir.*;
+import com.oracle.max.graal.compiler.gen.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+
+/**
+ * The {@code Backend} class represents a compiler backend for Graal.
+ */
+public abstract class Backend {
+    public final RiRuntime runtime;
+    public final CiTarget target;
+
+    protected Backend(RiRuntime runtime, CiTarget target) {
+        this.runtime = runtime;
+        this.target = target;
+    }
+
+    public static Backend create(CiArchitecture arch, RiRuntime runtime, CiTarget target) {
+        String className = arch.getClass().getName().replace("com.oracle.max.asm", "com.oracle.max.graal.compiler") + "Backend";
+        try {
+            Class<?> c = Class.forName(className);
+            Constructor<?> cons = c.getDeclaredConstructor(RiRuntime.class, CiTarget.class);
+            return (Backend) cons.newInstance(runtime, target);
+        } catch (Exception e) {
+            throw new Error("Could not instantiate " + className, e);
+        }
+    }
+
+    public abstract FrameMap newFrameMap(RiRegisterConfig registerConfig);
+    public abstract LIRGenerator newLIRGenerator(Graph graph, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir);
+    public abstract AbstractAssembler newAssembler(RiRegisterConfig registerConfig);
+    public abstract CiXirAssembler newXirAssembler();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Backend.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.compiler.target.amd64;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.cri.xir.*;
+import com.oracle.max.graal.compiler.gen.*;
+import com.oracle.max.graal.compiler.target.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+
+/**
+ * The {@code X86Backend} class represents the backend for the AMD64 architecture.
+ */
+public class AMD64Backend extends Backend {
+
+    public AMD64Backend(RiRuntime runtime, CiTarget target) {
+        super(runtime, target);
+    }
+    /**
+     * Creates a new LIRGenerator for x86.
+     * @param compilation the compilation for which to create the LIR generator
+     * @return an appropriate LIR generator instance
+     */
+    @Override
+    public LIRGenerator newLIRGenerator(Graph graph, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) {
+        return new AMD64LIRGenerator(graph, runtime, target, frameMap, method, lir, xir);
+    }
+
+    @Override
+    public FrameMap newFrameMap(RiRegisterConfig registerConfig) {
+        return new FrameMap(runtime, target, registerConfig);
+    }
+
+    @Override
+    public AbstractAssembler newAssembler(RiRegisterConfig registerConfig) {
+        return new AMD64MacroAssembler(target, registerConfig);
+    }
+
+    @Override
+    public CiXirAssembler newXirAssembler() {
+        return new AMD64XirAssembler(target);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64DeoptimizationStub.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.compiler.target.amd64;
+
+import java.util.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.amd64.*;
+import com.oracle.max.graal.lir.asm.*;
+import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction;
+
+public class AMD64DeoptimizationStub extends AMD64SlowPath {
+    public final Label label = new Label();
+    public final LIRDebugInfo info;
+    public final DeoptAction action;
+    public final Object deoptInfo;
+
+    public AMD64DeoptimizationStub(DeoptAction action, LIRDebugInfo info, Object deoptInfo) {
+        this.action = action;
+        this.info = info;
+        this.deoptInfo = deoptInfo;
+    }
+
+
+    private static ArrayList<Object> keepAlive = new ArrayList<>();
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        // TODO(cwi): we want to get rid of a generally reserved scratch register.
+        CiRegister scratch = tasm.frameMap.registerConfig.getScratchRegister();
+
+        masm.bind(label);
+        if (GraalOptions.CreateDeoptInfo && deoptInfo != null) {
+            masm.nop();
+            keepAlive.add(deoptInfo.toString());
+            AMD64Move.move(tasm, masm, scratch.asValue(), CiConstant.forObject(deoptInfo));
+            // TODO Why use scratch register here? Is it an implicit calling convention that the runtime function reads this register?
+            AMD64Call.directCall(tasm, masm, CiRuntimeCall.SetDeoptInfo, info);
+        }
+        int code;
+        switch(action) {
+            case None:
+                code = 0;
+                break;
+            case Recompile:
+                code = 1;
+                break;
+            case InvalidateReprofile:
+                code = 2;
+                break;
+            case InvalidateRecompile:
+                code = 3;
+                break;
+            case InvalidateStopCompiling:
+                code = 4;
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+        masm.movq(scratch, code);
+        // TODO Why use scratch register here? Is it an implicit calling convention that the runtime function reads this register?
+        AMD64Call.directCall(tasm, masm, CiRuntimeCall.Deoptimize, info);
+        AMD64Call.shouldNotReachHere(tasm, masm);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,601 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.max.graal.compiler.target.amd64;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.max.graal.lir.amd64.AMD64Arithmetic.*;
+import static com.oracle.max.graal.lir.amd64.AMD64Compare.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiTargetMethod.Mark;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.cri.xir.CiXirAssembler.XirMark;
+import com.oracle.max.cri.xir.*;
+import com.oracle.max.graal.compiler.gen.*;
+import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.StandardOp.JumpOp;
+import com.oracle.max.graal.lir.StandardOp.LabelOp;
+import com.oracle.max.graal.lir.amd64.AMD64Arithmetic.DivOp;
+import com.oracle.max.graal.lir.amd64.AMD64Arithmetic.Op1Reg;
+import com.oracle.max.graal.lir.amd64.AMD64Arithmetic.Op1Stack;
+import com.oracle.max.graal.lir.amd64.AMD64Arithmetic.Op2Reg;
+import com.oracle.max.graal.lir.amd64.AMD64Arithmetic.Op2Stack;
+import com.oracle.max.graal.lir.amd64.AMD64Arithmetic.ShiftOp;
+import com.oracle.max.graal.lir.amd64.AMD64Call.DirectCallOp;
+import com.oracle.max.graal.lir.amd64.AMD64Call.IndirectCallOp;
+import com.oracle.max.graal.lir.amd64.AMD64Compare.CompareOp;
+import com.oracle.max.graal.lir.amd64.AMD64ControlFlow.BranchOp;
+import com.oracle.max.graal.lir.amd64.AMD64ControlFlow.CondMoveOp;
+import com.oracle.max.graal.lir.amd64.AMD64ControlFlow.FloatBranchOp;
+import com.oracle.max.graal.lir.amd64.AMD64ControlFlow.FloatCondMoveOp;
+import com.oracle.max.graal.lir.amd64.AMD64ControlFlow.ReturnOp;
+import com.oracle.max.graal.lir.amd64.AMD64ControlFlow.TableSwitchOp;
+import com.oracle.max.graal.lir.amd64.AMD64Move.CompareAndSwapOp;
+import com.oracle.max.graal.lir.amd64.AMD64Move.LeaOp;
+import com.oracle.max.graal.lir.amd64.AMD64Move.LoadOp;
+import com.oracle.max.graal.lir.amd64.AMD64Move.MembarOp;
+import com.oracle.max.graal.lir.amd64.AMD64Move.MoveFromRegOp;
+import com.oracle.max.graal.lir.amd64.AMD64Move.MoveToRegOp;
+import com.oracle.max.graal.lir.amd64.AMD64Move.NullCheckOp;
+import com.oracle.max.graal.lir.amd64.AMD64Move.SpillMoveOp;
+import com.oracle.max.graal.lir.amd64.AMD64Move.StoreOp;
+import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.java.*;
+
+/**
+ * This class implements the X86-specific portion of the LIR generator.
+ */
+public class AMD64LIRGenerator extends LIRGenerator {
+
+    private static final CiRegisterValue RAX_I = AMD64.rax.asValue(CiKind.Int);
+    private static final CiRegisterValue RAX_L = AMD64.rax.asValue(CiKind.Long);
+    private static final CiRegisterValue RDX_I = AMD64.rdx.asValue(CiKind.Int);
+    private static final CiRegisterValue RDX_L = AMD64.rdx.asValue(CiKind.Long);
+    private static final CiRegisterValue RCX_I = AMD64.rcx.asValue(CiKind.Int);
+
+    public static class AMD64SpillMoveFactory implements LIR.SpillMoveFactory {
+        @Override
+        public LIRInstruction createMove(CiValue result, CiValue input) {
+            return new SpillMoveOp(result, input);
+        }
+
+        @Override
+        public LIRInstruction createExchange(CiValue input1, CiValue input2) {
+            // TODO implement XCHG operation for LIR
+            return null;
+        }
+    }
+
+    public AMD64LIRGenerator(Graph graph, RiRuntime runtime, CiTarget target, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) {
+        super(graph, runtime, target, frameMap, method, lir, xir);
+        lir.methodEndMarker = new AMD64MethodEndStub();
+        lir.spillMoveFactory = new AMD64SpillMoveFactory();
+    }
+
+    @Override
+    protected void emitNode(ValueNode node) {
+        if (node instanceof AMD64LIRLowerable) {
+            ((AMD64LIRLowerable) node).generateAmd64(this);
+        } else {
+            super.emitNode(node);
+        }
+    }
+
+    @Override
+    public boolean canStoreConstant(CiConstant c) {
+        // there is no immediate move of 64-bit constants on Intel
+        switch (c.kind) {
+            case Long:   return Util.isInt(c.asLong());
+            case Double: return false;
+            case Object: return c.isNull();
+            default:     return true;
+        }
+    }
+
+    @Override
+    public boolean canInlineConstant(CiConstant c) {
+        switch (c.kind) {
+            case Long:   return NumUtil.isInt(c.asLong());
+            case Object: return c.isNull();
+            default:     return true;
+        }
+    }
+
+    @Override
+    public CiAddress makeAddress(LocationNode location, ValueNode object) {
+        CiValue base = operand(object);
+        CiValue index = CiValue.IllegalValue;
+        int scale = 1;
+        long displacement = location.displacement();
+
+        if (isConstant(base)) {
+            if (!asConstant(base).isNull()) {
+                displacement += asConstant(base).asLong();
+            }
+            base = CiValue.IllegalValue;
+        }
+
+        if (location instanceof IndexedLocationNode) {
+            IndexedLocationNode indexedLoc = (IndexedLocationNode) location;
+
+            index = operand(indexedLoc.index());
+            if (indexedLoc.indexScalingEnabled()) {
+                scale = target().sizeInBytes(location.getValueKind());
+            }
+            if (isConstant(index)) {
+                displacement += asConstant(index).asLong() * scale;
+                index = CiValue.IllegalValue;
+            }
+        }
+
+        if (!NumUtil.isInt(displacement)) {
+            // Currently it's not worth handling this case.
+            throw new CiBailout("integer overflow when computing constant displacement");
+        }
+        return new CiAddress(location.getValueKind(), base, index, CiAddress.Scale.fromInt(scale), (int) displacement);
+    }
+
+    @Override
+    public Variable emitMove(CiValue input) {
+        Variable result = newVariable(input.kind);
+        emitMove(input, result);
+        return result;
+    }
+
+    @Override
+    public void emitMove(CiValue src, CiValue dst) {
+        if (isRegister(src) || isStackSlot(dst)) {
+            append(new MoveFromRegOp(dst, src));
+        } else {
+            append(new MoveToRegOp(dst, src));
+        }
+    }
+
+    @Override
+    public Variable emitLoad(CiValue loadAddress, boolean canTrap) {
+        Variable result = newVariable(loadAddress.kind);
+        append(new LoadOp(result, loadAddress, canTrap ? state() : null));
+        return result;
+    }
+
+    @Override
+    public void emitStore(CiValue storeAddress, CiValue inputVal, boolean canTrap) {
+        CiValue input = loadForStore(inputVal, storeAddress.kind);
+        append(new StoreOp(storeAddress, input, canTrap ? state() : null));
+    }
+
+    @Override
+    public Variable emitLea(CiValue address) {
+        Variable result = newVariable(target().wordKind);
+        append(new LeaOp(result, address));
+        return result;
+    }
+
+    @Override
+    public void emitLabel(Label label, boolean align) {
+        append(new LabelOp(label, align));
+    }
+
+    @Override
+    public void emitJump(LabelRef label, LIRDebugInfo info) {
+        append(new JumpOp(label, info));
+    }
+
+    @Override
+    public void emitBranch(CiValue left, CiValue right, Condition cond, boolean unorderedIsTrue, LabelRef label, LIRDebugInfo info) {
+        emitCompare(left, right);
+        switch (left.kind) {
+            case Boolean:
+            case Int:
+            case Long:
+            case Object: append(new BranchOp(cond, label, info)); break;
+            case Float:
+            case Double: append(new FloatBranchOp(cond, unorderedIsTrue, label, info)); break;
+            default: throw GraalInternalError.shouldNotReachHere("" + left.kind);
+        }
+    }
+
+    @Override
+    public Variable emitCMove(CiValue left, CiValue right, Condition cond, boolean unorderedIsTrue, CiValue trueValue, CiValue falseValue) {
+        emitCompare(left, right);
+
+        Variable result = newVariable(trueValue.kind);
+        switch (left.kind) {
+            case Boolean:
+            case Int:
+            case Long:
+            case Object: append(new CondMoveOp(result, cond, load(trueValue), loadNonConst(falseValue))); break;
+            case Float:
+            case Double: append(new FloatCondMoveOp(result, cond, unorderedIsTrue, load(trueValue), load(falseValue))); break;
+
+        }
+        return result;
+    }
+
+    private void emitCompare(CiValue a, CiValue b) {
+        Variable left = load(a);
+        CiValue right = loadNonConst(b);
+        switch (left.kind) {
+            case Jsr:
+            case Int: append(new CompareOp(ICMP, left, right)); break;
+            case Long: append(new CompareOp(LCMP, left, right)); break;
+            case Object: append(new CompareOp(ACMP, left, right)); break;
+            case Float: append(new CompareOp(FCMP, left, right)); break;
+            case Double: append(new CompareOp(DCMP, left, right)); break;
+            default: throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Variable emitNegate(CiValue input) {
+        Variable result = newVariable(input.kind);
+        switch (input.kind) {
+            case Int:    append(new Op1Stack(INEG, result, input)); break;
+            case Long:   append(new Op1Stack(LNEG, result, input)); break;
+            case Float:  append(new Op2Reg(FXOR, result, input, CiConstant.forFloat(Float.intBitsToFloat(0x80000000)))); break;
+            case Double: append(new Op2Reg(DXOR, result, input, CiConstant.forDouble(Double.longBitsToDouble(0x8000000000000000L)))); break;
+            default: throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitAdd(CiValue a, CiValue b) {
+        Variable result = newVariable(a.kind);
+        switch(a.kind) {
+            case Int:    append(new Op2Stack(IADD, result, a, loadNonConst(b))); break;
+            case Long:   append(new Op2Stack(LADD, result, a, loadNonConst(b))); break;
+            case Float:  append(new Op2Stack(FADD, result, a, loadNonConst(b))); break;
+            case Double: append(new Op2Stack(DADD, result, a, loadNonConst(b))); break;
+            default:     throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitSub(CiValue a, CiValue b) {
+        Variable result = newVariable(a.kind);
+        switch(a.kind) {
+            case Int:    append(new Op2Stack(ISUB, result, a, loadNonConst(b))); break;
+            case Long:   append(new Op2Stack(LSUB, result, a, loadNonConst(b))); break;
+            case Float:  append(new Op2Stack(FSUB, result, a, loadNonConst(b))); break;
+            case Double: append(new Op2Stack(DSUB, result, a, loadNonConst(b))); break;
+            default:     throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitMul(CiValue a, CiValue b) {
+        Variable result = newVariable(a.kind);
+        switch(a.kind) {
+            case Int:    append(new Op2Reg(IMUL, result, a, loadNonConst(b))); break;
+            case Long:   append(new Op2Reg(LMUL, result, a, loadNonConst(b))); break;
+            case Float:  append(new Op2Stack(FMUL, result, a, loadNonConst(b))); break;
+            case Double: append(new Op2Stack(DMUL, result, a, loadNonConst(b))); break;
+            default:     throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitDiv(CiValue a, CiValue b) {
+        switch(a.kind) {
+            case Int:
+                emitMove(a, RAX_I);
+                append(new DivOp(IDIV, RAX_I, RAX_I, load(b), state()));
+                return emitMove(RAX_I);
+            case Long:
+                emitMove(a, RAX_L);
+                append(new DivOp(LDIV, RAX_L, RAX_L, load(b), state()));
+                return emitMove(RAX_L);
+            case Float: {
+                Variable result = newVariable(a.kind);
+                append(new Op2Stack(FDIV, result, a, loadNonConst(b)));
+                return result;
+            }
+            case Double: {
+                Variable result = newVariable(a.kind);
+                append(new Op2Stack(DDIV, result, a, loadNonConst(b)));
+                return result;
+            }
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Variable emitRem(CiValue a, CiValue b) {
+        switch(a.kind) {
+            case Int:
+                emitMove(a, RAX_I);
+                append(new DivOp(IREM, RDX_I, RAX_I, load(b), state()));
+                return emitMove(RDX_I);
+            case Long:
+                emitMove(a, RAX_L);
+                append(new DivOp(LREM, RDX_L, RAX_L, load(b), state()));
+                return emitMove(RDX_L);
+            case Float:
+                return emitCallToRuntime(CiRuntimeCall.ArithmeticFrem, false, a, b);
+            case Double:
+                return emitCallToRuntime(CiRuntimeCall.ArithmeticDrem, false, a, b);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Variable emitUDiv(CiValue a, CiValue b) {
+        switch(a.kind) {
+            case Int:
+                emitMove(a, RAX_I);
+                append(new DivOp(IUDIV, RAX_I, RAX_I, load(b), state()));
+                return emitMove(RAX_I);
+            case Long:
+                emitMove(a, RAX_L);
+                append(new DivOp(LUDIV, RAX_L, RAX_L, load(b), state()));
+                return emitMove(RAX_L);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Variable emitURem(CiValue a, CiValue b) {
+        switch(a.kind) {
+            case Int:
+                emitMove(a, RAX_I);
+                append(new DivOp(IUREM, RDX_I, RAX_I, load(b), state()));
+                return emitMove(RDX_I);
+            case Long:
+                emitMove(a, RAX_L);
+                append(new DivOp(LUREM, RDX_L, RAX_L, load(b), state()));
+                return emitMove(RDX_L);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    @Override
+    public Variable emitAnd(CiValue a, CiValue b) {
+        Variable result = newVariable(a.kind);
+        switch(a.kind) {
+            case Int:    append(new Op2Stack(IAND, result, a, loadNonConst(b))); break;
+            case Long:   append(new Op2Stack(LAND, result, a, loadNonConst(b))); break;
+            default:     throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitOr(CiValue a, CiValue b) {
+        Variable result = newVariable(a.kind);
+        switch(a.kind) {
+            case Int:    append(new Op2Stack(IOR, result, a, loadNonConst(b))); break;
+            case Long:   append(new Op2Stack(LOR, result, a, loadNonConst(b))); break;
+            default:     throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitXor(CiValue a, CiValue b) {
+        Variable result = newVariable(a.kind);
+        switch(a.kind) {
+            case Int:    append(new Op2Stack(IXOR, result, a, loadNonConst(b))); break;
+            case Long:   append(new Op2Stack(LXOR, result, a, loadNonConst(b))); break;
+            default:     throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+
+    @Override
+    public Variable emitShl(CiValue a, CiValue b) {
+        Variable result = newVariable(a.kind);
+        switch (a.kind) {
+            case Int:    append(new ShiftOp(ISHL, result, a, loadShiftCount(b))); break;
+            case Long:   append(new ShiftOp(LSHL, result, a, loadShiftCount(b))); break;
+            default: GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitShr(CiValue a, CiValue b) {
+        Variable result = newVariable(a.kind);
+        switch (a.kind) {
+            case Int:    append(new ShiftOp(ISHR, result, a, loadShiftCount(b))); break;
+            case Long:   append(new ShiftOp(LSHR, result, a, loadShiftCount(b))); break;
+            default: GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    @Override
+    public Variable emitUShr(CiValue a, CiValue b) {
+        Variable result = newVariable(a.kind);
+        switch (a.kind) {
+            case Int:    append(new ShiftOp(IUSHR, result, a, loadShiftCount(b))); break;
+            case Long:   append(new ShiftOp(LUSHR, result, a, loadShiftCount(b))); break;
+            default: GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+    private CiValue loadShiftCount(CiValue value) {
+        if (isConstant(value)) {
+            return value;
+        }
+        // Non-constant shift count must be in RCX
+        emitMove(value, RCX_I);
+        return RCX_I;
+    }
+
+
+    @Override
+    public Variable emitConvert(ConvertNode.Op opcode, CiValue inputVal) {
+        Variable input = load(inputVal);
+        Variable result = newVariable(opcode.to);
+        switch (opcode) {
+            case I2L: append(new Op1Reg(I2L, result, input)); break;
+            case L2I: append(new Op1Stack(L2I, result, input)); break;
+            case I2B: append(new Op1Stack(I2B, result, input)); break;
+            case I2C: append(new Op1Stack(I2C, result, input)); break;
+            case I2S: append(new Op1Stack(I2S, result, input)); break;
+            case F2D: append(new Op1Reg(F2D, result, input)); break;
+            case D2F: append(new Op1Reg(D2F, result, input)); break;
+            case I2F: append(new Op1Reg(I2F, result, input)); break;
+            case I2D: append(new Op1Reg(I2D, result, input)); break;
+            case F2I: append(new Op1Reg(F2I, result, input)); break;
+            case D2I: append(new Op1Reg(D2I, result, input)); break;
+            case L2F: append(new Op1Reg(L2F, result, input)); break;
+            case L2D: append(new Op1Reg(L2D, result, input)); break;
+            case F2L: append(new Op1Reg(F2L, result, input)); break;
+            case D2L: append(new Op1Reg(D2L, result, input)); break;
+            case MOV_I2F: append(new Op1Reg(MOV_I2F, result, input)); break;
+            case MOV_L2D: append(new Op1Reg(MOV_L2D, result, input)); break;
+            case MOV_F2I: append(new Op1Reg(MOV_F2I, result, input)); break;
+            case MOV_D2L: append(new Op1Reg(MOV_D2L, result, input)); break;
+            default: throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
+    }
+
+
+    @Override
+    public void emitDeoptimizeOn(Condition cond, DeoptAction action, Object deoptInfo) {
+        LIRDebugInfo info = state();
+        LabelRef stubEntry = createDeoptStub(action, info, deoptInfo);
+        if (cond != null) {
+            append(new BranchOp(cond, stubEntry, info));
+        } else {
+            append(new JumpOp(stubEntry, info));
+        }
+    }
+
+    @Override
+    public void emitMembar(int barriers) {
+        int necessaryBarriers = target.arch.requiredBarriers(barriers);
+        if (target.isMP && necessaryBarriers != 0) {
+            append(new MembarOp(necessaryBarriers));
+        }
+    }
+
+    @Override
+    protected void emitCall(Object targetMethod, CiValue result, List<CiValue> arguments, CiValue targetAddress, LIRDebugInfo info, Map<XirMark, Mark> marks) {
+        if (isConstant(targetAddress)) {
+            assert asConstant(targetAddress).isDefaultValue() : "destination address should be zero";
+            append(new DirectCallOp(targetMethod, result, arguments.toArray(new CiValue[arguments.size()]), info, marks));
+        } else {
+            append(new IndirectCallOp(targetMethod, result, arguments.toArray(new CiValue[arguments.size()]), targetAddress, info, marks));
+        }
+    }
+
+    @Override
+    protected void emitReturn(CiValue input) {
+        append(new ReturnOp(input));
+    }
+
+    @Override
+    protected void emitXir(XirSnippet snippet, CiValue[] operands, CiValue outputOperand, CiValue[] inputs, CiValue[] temps, int[] inputOperandIndices, int[] tempOperandIndices, int outputOperandIndex,
+                    LIRDebugInfo info, LIRDebugInfo infoAfter, LabelRef trueSuccessor, LabelRef falseSuccessor) {
+        append(new AMD64XirOp(snippet, operands, outputOperand, inputs, temps, inputOperandIndices, tempOperandIndices, outputOperandIndex, info, infoAfter, trueSuccessor, falseSuccessor));
+    }
+
+    @Override
+    protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, CiValue index) {
+        // Making a copy of the switch value is necessary because jump table destroys the input value
+        Variable tmp = emitMove(index);
+        append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(target.wordKind)));
+    }
+
+    @Override
+    protected LabelRef createDeoptStub(DeoptAction action, LIRDebugInfo info, Object deoptInfo) {
+        assert info.topFrame.bci >= 0 : "invalid bci for deopt framestate";
+        AMD64DeoptimizationStub stub = new AMD64DeoptimizationStub(action, info, deoptInfo);
+        lir.deoptimizationStubs.add(stub);
+        return LabelRef.forLabel(stub.label);
+    }
+
+    @Override
+    protected void emitNullCheckGuard(NullCheckNode node) {
+        assert !node.expectedNull;
+        Variable value = load(operand(node.object()));
+        LIRDebugInfo info = state();
+        append(new NullCheckOp(value, info));
+    }
+
+    // TODO The CompareAndSwapNode in its current form needs to be lowered to several Nodes before code generation to separate three parts:
+    // * The write barriers (and possibly read barriers) when accessing an object field
+    // * The distinction of returning a boolean value (semantic similar to a BooleanNode to be used as a condition?) or the old value being read
+    // * The actual compare-and-swap
+    @Override
+    public void visitCompareAndSwap(CompareAndSwapNode node) {
+        CiKind kind = node.newValue().kind();
+        assert kind == node.expected().kind();
+
+        CiValue expected = loadNonConst(operand(node.expected()));
+        Variable newValue = load(operand(node.newValue()));
+
+        CiAddress address;
+        CiValue index = operand(node.offset());
+        if (isConstant(index) && NumUtil.isInt(asConstant(index).asLong())) {
+            address = new CiAddress(kind, load(operand(node.object())), (int) asConstant(index).asLong());
+        } else {
+            address = new CiAddress(kind, load(operand(node.object())), load(index), CiAddress.Scale.Times1, 0);
+        }
+
+        if (kind == CiKind.Object) {
+            address = new CiAddress(kind, emitLea(address));
+            preGCWriteBarrier(address.base, false, null);
+        }
+
+        CiRegisterValue rax = AMD64.rax.asValue(kind);
+        emitMove(expected, rax);
+        append(new CompareAndSwapOp(rax, address, rax, newValue));
+
+        Variable result = newVariable(node.kind());
+        if (node.directResult()) {
+            emitMove(rax, result);
+        } else {
+            append(new CondMoveOp(result, Condition.EQ, load(CiConstant.TRUE), CiConstant.FALSE));
+        }
+        setResult(node, result);
+
+        if (kind == CiKind.Object) {
+            postGCWriteBarrier(address.base, newValue);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRLowerable.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,28 @@
+/*
+ * 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.max.graal.compiler.target.amd64;
+
+public interface AMD64LIRLowerable {
+
+    void generateAmd64(AMD64LIRGenerator generator);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64MethodEndStub.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.compiler.target.amd64;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.lir.amd64.*;
+import com.oracle.max.graal.lir.asm.*;
+
+public class AMD64MethodEndStub extends AMD64SlowPath {
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        for (int i = 0; i < GraalOptions.MethodEndBreakpointGuards; ++i) {
+            masm.int3();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirAssembler.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.compiler.target.amd64;
+
+import static com.oracle.max.cri.xir.XirTemplate.GlobalFlags.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.xir.*;
+
+/**
+ * AMD64 version of {@link CiXirAssembler}.
+ *
+ */
+public class AMD64XirAssembler extends CiXirAssembler {
+    public AMD64XirAssembler(CiTarget target) {
+        super(target);
+    }
+
+    @Override
+    protected XirTemplate buildTemplate(String name, boolean isStub) {
+        List<XirInstruction> fastPath = new ArrayList<>(instructions.size());
+        List<XirInstruction> slowPath = new ArrayList<>();
+
+        int flags = 0;
+
+        if (isStub) {
+            flags |= GLOBAL_STUB.mask;
+        }
+
+        List<XirInstruction> currentList = fastPath;
+
+        XirOperand fixedRDX = null;
+        XirOperand fixedRAX = null;
+        XirOperand fixedRCX = null;
+        XirOperand fixedRSI = null;
+        XirOperand fixedRDI = null;
+        HashSet<XirLabel> boundLabels = new HashSet<>();
+
+        for (XirInstruction i : instructions) {
+            boolean appended = false;
+            switch (i.op) {
+                case Mov:
+                    break;
+
+                case Add:
+                case Sub:
+                case Div:
+                case Mul:
+                case Mod:
+                case Shl:
+                case Shr:
+                case And:
+                case Or:
+                case Xor:
+                    // Convert to two operand form
+                    XirOperand xOp = i.x();
+                    if (i.op == XirOp.Div || i.op == XirOp.Mod) {
+                        if (fixedRDX == null) {
+                            fixedRDX = createRegisterTemp("divModTemp", CiKind.Int, AMD64.rdx);
+                        }
+                        // Special treatment to make sure that the left input of % and / is in RAX
+                        if (fixedRAX == null) {
+                            fixedRAX = createRegisterTemp("divModLeftInput", CiKind.Int, AMD64.rax);
+                        }
+                        currentList.add(new XirInstruction(i.x().kind, XirOp.Mov, fixedRAX, i.x()));
+                        xOp = fixedRAX;
+                    } else {
+                        if (i.result != i.x()) {
+                            currentList.add(new XirInstruction(i.result.kind, XirOp.Mov, i.result, i.x()));
+                            xOp = i.result;
+                        }
+                    }
+
+                    XirOperand yOp = i.y();
+                    if ((i.op == XirOp.Shl || i.op == XirOp.Shr) && (!(i.y() instanceof XirConstantOperand))) {
+                        // Special treatment to make sure that the shift count is always in RCX
+                        if (fixedRCX == null) {
+                            fixedRCX = createRegisterTemp("fixedShiftCount", i.y().kind, AMD64.rcx);
+                        }
+                        currentList.add(new XirInstruction(i.result.kind, XirOp.Mov, fixedRCX, i.y()));
+                        yOp = fixedRCX;
+                    } else if (i.op == XirOp.Mul && (i.y() instanceof XirConstantOperand)) {
+                        // Cannot multiply directly with a constant, so introduce a new temporary variable
+                        XirOperand tempLocation = createTemp("mulTempLocation", i.y().kind);
+                        currentList.add(new XirInstruction(i.result.kind, XirOp.Mov, tempLocation, i.y()));
+                        yOp = tempLocation;
+
+                    }
+
+                    XirOperand resultOp = i.result;
+                    if (i.op == XirOp.Div) {
+                        resultOp = fixedRAX;
+                    } else if (i.op == XirOp.Mod) {
+                        resultOp = fixedRDX;
+                    }
+
+                    if (xOp != i.x() || yOp != i.y() || resultOp != i.result) {
+                        currentList.add(new XirInstruction(i.result.kind, i.op, resultOp, xOp, yOp));
+                        appended = true;
+                    }
+
+                    if (resultOp != i.result) {
+                        currentList.add(new XirInstruction(i.result.kind, XirOp.Mov, i.result, resultOp));
+                    }
+                    break;
+
+                case RepeatMoveWords:
+                case RepeatMoveBytes:
+                    if (fixedRSI == null) {
+                        fixedRSI = createRegisterTemp("fixedRSI", target.wordKind, AMD64.rsi);
+                    }
+                    if (fixedRDI == null) {
+                        fixedRDI = createRegisterTemp("fixedRDI", target.wordKind, AMD64.rdi);
+                    }
+                    if (fixedRCX == null) {
+                        fixedRCX = createRegisterTemp("fixedRCX", target.wordKind, AMD64.rcx);
+                    }
+                    currentList.add(new XirInstruction(target.wordKind, XirOp.Mov, fixedRSI, i.x()));
+                    currentList.add(new XirInstruction(target.wordKind, XirOp.Mov, fixedRDI, i.y()));
+                    currentList.add(new XirInstruction(target.wordKind, XirOp.Mov, fixedRCX, i.z()));
+                    currentList.add(new XirInstruction(CiKind.Illegal, i.op, i.result, fixedRSI, fixedRDI, fixedRCX));
+                    appended = true;
+                    break;
+
+                case NullCheck:
+                case PointerLoad:
+                case LoadEffectiveAddress:
+                case PointerStore:
+                case PointerLoadDisp:
+                case PointerStoreDisp:
+                    break;
+                case PointerCAS:
+                    if (fixedRAX == null) {
+                        fixedRAX = createRegisterTemp("fixedRAX", target.wordKind, AMD64.rax);
+                    }
+                    // x = source of cmpxch
+                    // y = new value
+                    // z = old value (i.e., the one compared to). Must be in RAX (and so must the result).
+                    currentList.add(new XirInstruction(target.wordKind, XirOp.Mov, fixedRAX, i.z()));
+                    currentList.add(new XirInstruction(i.kind, i.op, i.result, i.x(), i.y(), fixedRAX));
+                    appended = true;
+                    break;
+                case CallRuntime:
+                    flags |= HAS_RUNTIME_CALL.mask;
+                    break;
+                case Jmp:
+                    // jmp can be either into the snippet or to a runtime target
+                    flags |= i.extra instanceof XirLabel ? HAS_CONTROL_FLOW.mask : HAS_RUNTIME_CALL.mask;
+                    break;
+                case Jeq:
+                case Jneq:
+                case Jgt:
+                case Jgteq:
+                case Jugteq:
+                case Jlt:
+                case Jlteq:
+                case DecAndJumpNotZero:
+                case Jbset:
+                    flags |= HAS_CONTROL_FLOW.mask;
+                    break;
+                case Bind:
+                    XirLabel label = (XirLabel) i.extra;
+                    currentList = label.inline ? fastPath : slowPath;
+                    assert !boundLabels.contains(label) : "label may be bound only once";
+                    boundLabels.add(label);
+                    break;
+                case Safepoint:
+                case Align:
+                case StackOverflowCheck:
+                case PushFrame:
+                case PopFrame:
+                case Push:
+                case Pop:
+                case Mark:
+                case Nop:
+                case RawBytes:
+                case ShouldNotReachHere:
+                    break;
+                default:
+                    assert false : "Unknown XIR operation " + i.op;
+            }
+            if (!appended) {
+                currentList.add(i);
+            }
+        }
+        for (XirLabel label : labels) {
+            assert label.name == XirLabel.TrueSuccessor || label.name == XirLabel.FalseSuccessor || boundLabels.contains(label) : "label " + label.name + " is not bound!";
+        }
+        XirInstruction[] fp = fastPath.toArray(new XirInstruction[fastPath.size()]);
+        XirInstruction[] sp = slowPath.size() > 0 ? slowPath.toArray(new XirInstruction[slowPath.size()]) : null;
+        XirLabel[] xirLabels = labels.toArray(new XirLabel[labels.size()]);
+        XirParameter[] xirParameters = parameters.toArray(new XirParameter[parameters.size()]);
+        XirTemp[] temporaryOperands = temps.toArray(new XirTemp[temps.size()]);
+        XirConstant[] constantOperands = constants.toArray(new XirConstant[constants.size()]);
+        XirMark[] marksArray = marks.toArray(new XirMark[marks.size()]);
+        return new XirTemplate(name, this.variableCount, this.allocateResultOperand, resultOperand, fp, sp, xirLabels, xirParameters, temporaryOperands, constantOperands, flags, marksArray, outgoingStackSize);
+    }
+
+    @Override
+    public CiXirAssembler copy() {
+        return new AMD64XirAssembler(target);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirOp.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,553 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.compiler.target.amd64;
+
+import static com.oracle.max.cri.ci.CiCallingConvention.Type.*;
+import static com.oracle.max.cri.ci.CiValue.*;
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiTargetMethod.Mark;
+import com.oracle.max.cri.xir.*;
+import com.oracle.max.cri.xir.CiXirAssembler.RuntimeCallInformation;
+import com.oracle.max.cri.xir.CiXirAssembler.XirInstruction;
+import com.oracle.max.cri.xir.CiXirAssembler.XirLabel;
+import com.oracle.max.cri.xir.CiXirAssembler.XirMark;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.amd64.*;
+import com.oracle.max.graal.lir.asm.*;
+
+public class AMD64XirOp extends LIRXirInstruction {
+    public AMD64XirOp(XirSnippet snippet, CiValue[] operands, CiValue outputOperand, CiValue[] inputs, CiValue[] temps, int[] inputOperandIndices, int[] tempOperandIndices, int outputOperandIndex,
+                        LIRDebugInfo info, LIRDebugInfo infoAfter, LabelRef trueSuccessor, LabelRef falseSuccessor) {
+        super("XIR", snippet, operands, outputOperand, inputs, temps, inputOperandIndices, tempOperandIndices, outputOperandIndex, info, infoAfter, trueSuccessor, falseSuccessor);
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm) {
+        AMD64MacroAssembler masm = (AMD64MacroAssembler) tasm.asm;
+
+        Label endLabel = null;
+        Label[] labels = new Label[snippet.template.labels.length];
+        for (int i = 0; i < labels.length; i++) {
+            labels[i] = new Label();
+            if (snippet.template.labels[i].name == XirLabel.TrueSuccessor) {
+                if (trueSuccessor == null) {
+                    assert endLabel == null;
+                    endLabel = new Label();
+                    labels[i] = endLabel;
+                } else {
+                    labels[i] = trueSuccessor.label();
+                }
+            } else if (snippet.template.labels[i].name == XirLabel.FalseSuccessor) {
+                if (falseSuccessor == null) {
+                    assert endLabel == null;
+                    endLabel = new Label();
+                    labels[i] = endLabel;
+                } else {
+                    labels[i] = falseSuccessor.label();
+                }
+            }
+        }
+        emitXirInstructions(tasm, masm, snippet.template.fastPath, labels, getOperands(), snippet.marks);
+        if (endLabel != null) {
+            masm.bind(endLabel);
+        }
+
+        if (snippet.template.slowPath != null) {
+            tasm.slowPaths.add(new SlowPath(labels));
+        }
+    }
+
+    private class SlowPath extends AMD64SlowPath {
+        public final Label[] labels;
+
+        public SlowPath(Label[] labels) {
+            this.labels = labels;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            emitXirInstructions(tasm, masm, snippet.template.slowPath, labels, getOperands(), snippet.marks);
+            masm.nop();
+        }
+    }
+
+
+    protected void emitXirInstructions(TargetMethodAssembler tasm, AMD64MacroAssembler masm, XirInstruction[] instructions, Label[] labels, CiValue[] operands, Map<XirMark, Mark> marks) {
+        for (XirInstruction inst : instructions) {
+            switch (inst.op) {
+                case Add:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.IADD, AMD64Arithmetic.LADD, AMD64Arithmetic.FADD, AMD64Arithmetic.DADD, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Sub:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.ISUB, AMD64Arithmetic.LSUB, AMD64Arithmetic.FSUB, AMD64Arithmetic.DSUB, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Div:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.IDIV, AMD64Arithmetic.LDIV, AMD64Arithmetic.FDIV, AMD64Arithmetic.DDIV, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Mul:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.IMUL, AMD64Arithmetic.LMUL, AMD64Arithmetic.FMUL, AMD64Arithmetic.DMUL, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Mod:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.IREM, AMD64Arithmetic.LREM, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Shl:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.ISHL, AMD64Arithmetic.LSHL, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Sar:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.ISHR, AMD64Arithmetic.LSHR, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Shr:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.IUSHR, AMD64Arithmetic.LUSHR, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case And:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.IAND, AMD64Arithmetic.LAND, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Or:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.IOR, AMD64Arithmetic.LOR, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Xor:
+                    emitXirViaLir(tasm, masm, AMD64Arithmetic.IXOR, AMD64Arithmetic.LXOR, null, null, operands[inst.x().index], operands[inst.y().index], operands[inst.result.index]);
+                    break;
+
+                case Mov: {
+                    CiValue result = operands[inst.result.index];
+                    CiValue source = operands[inst.x().index];
+                    AMD64Move.move(tasm, masm, result, source);
+                    break;
+                }
+
+                case PointerLoad: {
+                    CiValue result = operands[inst.result.index];
+                    CiValue pointer = operands[inst.x().index];
+                    CiRegisterValue register = assureInRegister(tasm, masm, pointer);
+
+                    AMD64Move.load(tasm, masm, result, new CiAddress(inst.kind, register), (Boolean) inst.extra ? info : null);
+                    break;
+                }
+
+                case PointerStore: {
+                    CiValue value = assureNot64BitConstant(tasm, masm, operands[inst.y().index]);
+                    CiValue pointer = operands[inst.x().index];
+                    assert isRegister(pointer);
+
+                    AMD64Move.store(tasm, masm, new CiAddress(inst.kind, pointer), value, (Boolean) inst.extra ? info : null);
+                    break;
+                }
+
+                case PointerLoadDisp: {
+                    CiXirAssembler.AddressAccessInformation addressInformation = (CiXirAssembler.AddressAccessInformation) inst.extra;
+                    boolean canTrap = addressInformation.canTrap;
+
+                    CiAddress.Scale scale = addressInformation.scale;
+                    int displacement = addressInformation.disp;
+
+                    CiValue result = operands[inst.result.index];
+                    CiValue pointer = operands[inst.x().index];
+                    CiValue index = operands[inst.y().index];
+
+                    pointer = assureInRegister(tasm, masm, pointer);
+                    assert isRegister(pointer);
+
+                    CiAddress src;
+                    if (isConstant(index)) {
+                        assert index.kind == CiKind.Int;
+                        CiConstant constantIndex = (CiConstant) index;
+                        src = new CiAddress(inst.kind, pointer, constantIndex.asInt() * scale.value + displacement);
+                    } else {
+                        src = new CiAddress(inst.kind, pointer, index, scale, displacement);
+                    }
+
+                    AMD64Move.load(tasm, masm, result, src, canTrap ? info : null);
+                    break;
+                }
+
+                case LoadEffectiveAddress: {
+                    CiXirAssembler.AddressAccessInformation addressInformation = (CiXirAssembler.AddressAccessInformation) inst.extra;
+
+                    CiAddress.Scale scale = addressInformation.scale;
+                    int displacement = addressInformation.disp;
+
+                    CiValue result = operands[inst.result.index];
+                    CiValue pointer = operands[inst.x().index];
+                    CiValue index = operands[inst.y().index];
+
+                    pointer = assureInRegister(tasm, masm, pointer);
+                    assert isRegister(pointer);
+                    CiAddress src = new CiAddress(CiKind.Illegal, pointer, index, scale, displacement);
+                    masm.leaq(asRegister(result), src);
+                    break;
+                }
+
+                case PointerStoreDisp: {
+                    CiXirAssembler.AddressAccessInformation addressInformation = (CiXirAssembler.AddressAccessInformation) inst.extra;
+                    boolean canTrap = addressInformation.canTrap;
+
+                    CiAddress.Scale scale = addressInformation.scale;
+                    int displacement = addressInformation.disp;
+
+                    CiValue value = assureNot64BitConstant(tasm, masm, operands[inst.z().index]);
+                    CiValue pointer = operands[inst.x().index];
+                    CiValue index = operands[inst.y().index];
+
+                    pointer = assureInRegister(tasm, masm, pointer);
+                    assert isRegister(pointer);
+
+                    CiAddress dst;
+                    if (isConstant(index)) {
+                        assert index.kind == CiKind.Int;
+                        CiConstant constantIndex = (CiConstant) index;
+                        dst = new CiAddress(inst.kind, pointer, IllegalValue, scale, constantIndex.asInt() * scale.value + displacement);
+                    } else {
+                        dst = new CiAddress(inst.kind, pointer, index, scale, displacement);
+                    }
+
+                    AMD64Move.store(tasm, masm, dst, value, canTrap ? info : null);
+                    break;
+                }
+
+                case RepeatMoveBytes:
+                    assert asRegister(operands[inst.x().index]).equals(AMD64.rsi) : "wrong input x: " + operands[inst.x().index];
+                    assert asRegister(operands[inst.y().index]).equals(AMD64.rdi) : "wrong input y: " + operands[inst.y().index];
+                    assert asRegister(operands[inst.z().index]).equals(AMD64.rcx) : "wrong input z: " + operands[inst.z().index];
+                    masm.repeatMoveBytes();
+                    break;
+
+                case RepeatMoveWords:
+                    assert asRegister(operands[inst.x().index]).equals(AMD64.rsi) : "wrong input x: " + operands[inst.x().index];
+                    assert asRegister(operands[inst.y().index]).equals(AMD64.rdi) : "wrong input y: " + operands[inst.y().index];
+                    assert asRegister(operands[inst.z().index]).equals(AMD64.rcx) : "wrong input z: " + operands[inst.z().index];
+                    masm.repeatMoveWords();
+                    break;
+
+                case PointerCAS:
+                    assert asRegister(operands[inst.x().index]).equals(AMD64.rax) : "wrong input x: " + operands[inst.x().index];
+
+                    CiValue exchangedVal = operands[inst.y().index];
+                    CiValue exchangedAddress = operands[inst.x().index];
+                    CiRegisterValue pointerRegister = assureInRegister(tasm, masm, exchangedAddress);
+                    CiAddress addr = new CiAddress(tasm.target.wordKind, pointerRegister);
+
+                    if ((Boolean) inst.extra && info != null) {
+                        tasm.recordImplicitException(masm.codeBuffer.position(), info);
+                    }
+                    masm.cmpxchgq(asRegister(exchangedVal), addr);
+
+                    break;
+
+                case CallRuntime: {
+                    CiKind[] signature = new CiKind[inst.arguments.length];
+                    for (int i = 0; i < signature.length; i++) {
+                        signature[i] = inst.arguments[i].kind;
+                    }
+
+                    CiCallingConvention cc = tasm.frameMap.registerConfig.getCallingConvention(RuntimeCall, signature, tasm.target, false);
+                    for (int i = 0; i < inst.arguments.length; i++) {
+                        CiValue argumentLocation = cc.locations[i];
+                        CiValue argumentSourceLocation = operands[inst.arguments[i].index];
+                        if (argumentLocation != argumentSourceLocation) {
+                            AMD64Move.move(tasm, masm, argumentLocation, argumentSourceLocation);
+                        }
+                    }
+
+                    RuntimeCallInformation runtimeCallInformation = (RuntimeCallInformation) inst.extra;
+                    AMD64Call.directCall(tasm, masm, runtimeCallInformation.target, (runtimeCallInformation.useInfoAfter) ? infoAfter : info);
+
+                    if (inst.result != null && inst.result.kind != CiKind.Illegal && inst.result.kind != CiKind.Void) {
+                        CiRegister returnRegister = tasm.frameMap.registerConfig.getReturnRegister(inst.result.kind);
+                        CiValue resultLocation = returnRegister.asValue(inst.result.kind.stackKind());
+                        AMD64Move.move(tasm, masm, operands[inst.result.index], resultLocation);
+                    }
+                    break;
+                }
+                case Jmp: {
+                    if (inst.extra instanceof XirLabel) {
+                        Label label = labels[((XirLabel) inst.extra).index];
+                        masm.jmp(label);
+                    } else {
+                        AMD64Call.directJmp(tasm, masm, inst.extra);
+                    }
+                    break;
+                }
+                case DecAndJumpNotZero: {
+                    Label label = labels[((XirLabel) inst.extra).index];
+                    CiValue value = operands[inst.x().index];
+                    if (value.kind == CiKind.Long) {
+                        masm.decq(asRegister(value));
+                    } else {
+                        assert value.kind == CiKind.Int;
+                        masm.decl(asRegister(value));
+                    }
+                    masm.jcc(ConditionFlag.notZero, label);
+                    break;
+                }
+                case Jeq: {
+                    Label label = labels[((XirLabel) inst.extra).index];
+                    emitXirCompare(tasm, masm, inst, ConditionFlag.equal, operands, label);
+                    break;
+                }
+                case Jneq: {
+                    Label label = labels[((XirLabel) inst.extra).index];
+                    emitXirCompare(tasm, masm, inst, ConditionFlag.notEqual, operands, label);
+                    break;
+                }
+
+                case Jgt: {
+                    Label label = labels[((XirLabel) inst.extra).index];
+                    emitXirCompare(tasm, masm, inst, ConditionFlag.greater, operands, label);
+                    break;
+                }
+
+                case Jgteq: {
+                    Label label = labels[((XirLabel) inst.extra).index];
+                    emitXirCompare(tasm, masm, inst, ConditionFlag.greaterEqual, operands, label);
+                    break;
+                }
+
+                case Jugteq: {
+                    Label label = labels[((XirLabel) inst.extra).index];
+                    emitXirCompare(tasm, masm, inst, ConditionFlag.aboveEqual, operands, label);
+                    break;
+                }
+
+                case Jlt: {
+                    Label label = labels[((XirLabel) inst.extra).index];
+                    emitXirCompare(tasm, masm, inst, ConditionFlag.less, operands, label);
+                    break;
+                }
+
+                case Jlteq: {
+                    Label label = labels[((XirLabel) inst.extra).index];
+                    emitXirCompare(tasm, masm, inst, ConditionFlag.lessEqual, operands, label);
+                    break;
+                }
+
+                case Jbset: {
+                    Label label = labels[((XirLabel) inst.extra).index];
+                    CiValue pointer = operands[inst.x().index];
+                    CiValue offset = operands[inst.y().index];
+                    CiValue bit = operands[inst.z().index];
+                    assert isConstant(offset) && isConstant(bit);
+                    CiConstant constantOffset = (CiConstant) offset;
+                    CiConstant constantBit = (CiConstant) bit;
+                    CiAddress src = new CiAddress(inst.kind, pointer, constantOffset.asInt());
+                    masm.btli(src, constantBit.asInt());
+                    masm.jcc(ConditionFlag.aboveEqual, label);
+                    break;
+                }
+
+                case Bind: {
+                    XirLabel l = (XirLabel) inst.extra;
+                    Label label = labels[l.index];
+                    masm.bind(label);
+                    break;
+                }
+                case Safepoint: {
+                    assert info != null : "Must have debug info in order to create a safepoint.";
+                    tasm.recordSafepoint(masm.codeBuffer.position(), info);
+                    break;
+                }
+                case NullCheck: {
+                    tasm.recordImplicitException(masm.codeBuffer.position(), info);
+                    CiValue pointer = operands[inst.x().index];
+                    masm.nullCheck(asRegister(pointer));
+                    break;
+                }
+                case Align: {
+                    masm.align((Integer) inst.extra);
+                    break;
+                }
+                case StackOverflowCheck: {
+                    int frameSize = tasm.frameMap.frameSize();
+                    int lastFramePage = frameSize / tasm.target.pageSize;
+                    // emit multiple stack bangs for methods with frames larger than a page
+                    for (int i = 0; i <= lastFramePage; i++) {
+                        int offset = (i + GraalOptions.StackShadowPages) * tasm.target.pageSize;
+                        // Deduct 'frameSize' to handle frames larger than the shadow
+                        bangStackWithOffset(tasm, masm, offset - frameSize);
+                    }
+                    break;
+                }
+                case PushFrame: {
+                    int frameSize = tasm.frameMap.frameSize();
+                    masm.decrementq(AMD64.rsp, frameSize); // does not emit code for frameSize == 0
+                    if (GraalOptions.ZapStackOnMethodEntry) {
+                        final int intSize = 4;
+                        for (int i = 0; i < frameSize / intSize; ++i) {
+                            masm.movl(new CiAddress(CiKind.Int, AMD64.rsp.asValue(), i * intSize), 0xC1C1C1C1);
+                        }
+                    }
+                    CiCalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout();
+                    if (csl != null && csl.size != 0) {
+                        int frameToCSA = tasm.frameMap.offsetToCalleeSaveArea();
+                        assert frameToCSA >= 0;
+                        masm.save(csl, frameToCSA);
+                    }
+                    break;
+                }
+                case PopFrame: {
+                    int frameSize = tasm.frameMap.frameSize();
+
+                    CiCalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout();
+                    if (csl != null && csl.size != 0) {
+                        tasm.targetMethod.setRegisterRestoreEpilogueOffset(masm.codeBuffer.position());
+                        // saved all registers, restore all registers
+                        int frameToCSA = tasm.frameMap.offsetToCalleeSaveArea();
+                        masm.restore(csl, frameToCSA);
+                    }
+
+                    masm.incrementq(AMD64.rsp, frameSize);
+                    break;
+                }
+                case Push: {
+                    CiRegisterValue value = assureInRegister(tasm, masm, operands[inst.x().index]);
+                    masm.push(asRegister(value));
+                    break;
+                }
+                case Pop: {
+                    CiValue result = operands[inst.result.index];
+                    if (isRegister(result)) {
+                        masm.pop(asRegister(result));
+                    } else {
+                        CiRegister rscratch = tasm.frameMap.registerConfig.getScratchRegister();
+                        masm.pop(rscratch);
+                        AMD64Move.move(tasm, masm, result, rscratch.asValue());
+                    }
+                    break;
+                }
+                case Mark: {
+                    XirMark xmark = (XirMark) inst.extra;
+                    Mark[] references = new Mark[xmark.references.length];
+                    for (int i = 0; i < references.length; i++) {
+                        references[i] = marks.get(xmark.references[i]);
+                        assert references[i] != null;
+                    }
+                    Mark mark = tasm.recordMark(xmark.id, references);
+                    marks.put(xmark, mark);
+                    break;
+                }
+                case Nop: {
+                    for (int i = 0; i < (Integer) inst.extra; i++) {
+                        masm.nop();
+                    }
+                    break;
+                }
+                case RawBytes: {
+                    for (byte b : (byte[]) inst.extra) {
+                        masm.codeBuffer.emitByte(b & 0xff);
+                    }
+                    break;
+                }
+                case ShouldNotReachHere: {
+                    AMD64Call.shouldNotReachHere(tasm, masm);
+                    break;
+                }
+                default:
+                    throw GraalInternalError.shouldNotReachHere("Unknown XIR operation " + inst.op);
+            }
+        }
+    }
+
+    private static void emitXirViaLir(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Arithmetic intOp, AMD64Arithmetic longOp, AMD64Arithmetic floatOp,
+                    AMD64Arithmetic doubleOp, CiValue left, CiValue right, CiValue result) {
+        AMD64Arithmetic code;
+        switch (result.kind) {
+            case Int: code = intOp; break;
+            case Long: code = longOp; break;
+            case Float: code = floatOp; break;
+            case Double: code = doubleOp; break;
+            default: throw GraalInternalError.shouldNotReachHere();
+        }
+        assert left == result;
+        if (isRegister(right) && right.kind != result.kind) {
+            // XIR is not strongly typed, so we can have a type mismatch that we have to fix here.
+            AMD64Arithmetic.emit(tasm, masm, code, result, asRegister(right).asValue(result.kind), null);
+        } else {
+            AMD64Arithmetic.emit(tasm, masm, code, result, right, null);
+        }
+    }
+
+    private static void emitXirCompare(TargetMethodAssembler tasm, AMD64MacroAssembler masm, XirInstruction inst, ConditionFlag cflag, CiValue[] ops, Label label) {
+        CiValue x = ops[inst.x().index];
+        CiValue y = ops[inst.y().index];
+        AMD64Compare code;
+        switch (x.kind) {
+            case Int: code = AMD64Compare.ICMP; break;
+            case Long: code = AMD64Compare.LCMP; break;
+            case Object: code = AMD64Compare.ACMP; break;
+            case Float: code = AMD64Compare.FCMP; break;
+            case Double: code = AMD64Compare.DCMP; break;
+            default: throw GraalInternalError.shouldNotReachHere();
+        }
+        AMD64Compare.emit(tasm, masm, code, x, y);
+        masm.jcc(cflag, label);
+    }
+
+    /**
+     * @param offset the offset RSP at which to bang. Note that this offset is relative to RSP after RSP has been
+     *            adjusted to allocated the frame for the method. It denotes an offset "down" the stack.
+     *            For very large frames, this means that the offset may actually be negative (i.e. denoting
+     *            a slot "up" the stack above RSP).
+     */
+    private static void bangStackWithOffset(TargetMethodAssembler tasm, AMD64MacroAssembler masm, int offset) {
+        masm.movq(new CiAddress(tasm.target.wordKind, AMD64.RSP, -offset), AMD64.rax);
+    }
+
+    private static CiValue assureNot64BitConstant(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue value) {
+        if (isConstant(value) && (value.kind == CiKind.Long || value.kind == CiKind.Object)) {
+            CiRegisterValue register = tasm.frameMap.registerConfig.getScratchRegister().asValue(value.kind);
+            AMD64Move.move(tasm, masm, register, value);
+            return register;
+        }
+        return value;
+    }
+
+    private static CiRegisterValue assureInRegister(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue pointer) {
+        if (isConstant(pointer)) {
+            CiRegisterValue register = tasm.frameMap.registerConfig.getScratchRegister().asValue(pointer.kind);
+            AMD64Move.move(tasm, masm, register, pointer);
+            return register;
+        }
+
+        assert isRegister(pointer) : "should be register, but is: " + pointer;
+        return (CiRegisterValue) pointer;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/types/PostOrderBlockIterator.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.compiler.types;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+public abstract class PostOrderBlockIterator {
+
+    private final BitMap visitedEndBlocks;
+    private final Deque<Block> blockQueue;
+
+    public PostOrderBlockIterator(Block start, int blockCount) {
+        visitedEndBlocks = new BitMap(blockCount);
+        blockQueue = new ArrayDeque<>();
+        blockQueue.add(start);
+    }
+
+    public void apply() {
+        while (!blockQueue.isEmpty()) {
+            Block current = blockQueue.removeLast();
+            block(current);
+
+            for (int i = 0; i < current.getSuccessors().size(); i++) {
+                Block successor = current.getSuccessors().get(i);
+                if (successor.getPredecessors().size() > 1) {
+                    queueMerge(current, successor);
+                } else {
+                    blockQueue.addLast(successor);
+                }
+            }
+        }
+    }
+
+    protected abstract void block(Block block);
+
+    private void queueMerge(Block end, Block merge) {
+        visitedEndBlocks.set(end.getId());
+        for (Block pred : merge.getPredecessors()) {
+            if (!visitedEndBlocks.get(pred.getId())) {
+                return;
+            }
+        }
+        blockQueue.addFirst(merge);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/types/PropagateTypesPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,264 @@
+/*
+ * 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.max.graal.compiler.types;
+
+import java.util.*;
+import java.util.Map.Entry;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.compiler.graph.*;
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.compiler.schedule.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.graph.NodeClass.NodeClassIterator;
+import com.oracle.max.graal.graph.NodeClass.Position;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.java.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public class PropagateTypesPhase extends Phase {
+
+    private final CiTarget target;
+    private final RiRuntime runtime;
+    private final CiAssumptions assumptions;
+
+    private NodeWorkList changedNodes;
+
+    public PropagateTypesPhase(CiTarget target, RiRuntime runtime, CiAssumptions assumptions) {
+        this.target = target;
+        this.runtime = runtime;
+        this.assumptions = assumptions;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+
+        new DeadCodeEliminationPhase().apply(graph);
+
+        changedNodes = graph.createNodeWorkList(false, 10);
+
+        SchedulePhase schedule = new SchedulePhase();
+        schedule.apply(graph);
+
+        schedule.scheduleGraph();
+        Debug.dump(graph, "scheduled");
+
+        new PropagateTypes(graph.start()).apply();
+        Debug.dump(graph, "after propagation");
+
+        new UnscheduleNodes(graph.start()).apply();
+
+        CanonicalizerPhase.canonicalize(graph, changedNodes, runtime, target, assumptions);
+    }
+
+    private class PiNodeList {
+
+        public final PiNodeList last;
+        public final ValueNode replacement;
+        public final int depth;
+
+        public PiNodeList(ValueNode replacement, PiNodeList last) {
+            this.last = last;
+            this.replacement = replacement;
+            this.depth = last != null ? last.depth + 1 : 1;
+        }
+
+        public PiNodeList merge(PiNodeList other) {
+            PiNodeList thisList = this;
+            PiNodeList otherList = other;
+            while (thisList.depth > otherList.depth) {
+                thisList = thisList.last;
+            }
+            while (otherList.depth > thisList.depth) {
+                otherList = otherList.last;
+            }
+            while (thisList != otherList) {
+                thisList = thisList.last;
+                otherList = otherList.last;
+            }
+            return thisList;
+        }
+    }
+
+    private class TypeInfo implements MergeableState<TypeInfo> {
+
+        private HashMap<ValueNode, PiNodeList> piNodes = new HashMap<>();
+
+        public TypeInfo(HashMap<ValueNode, PiNodeList> piNodes) {
+            this.piNodes.putAll(piNodes);
+        }
+
+        @Override
+        public TypeInfo clone() {
+            return new TypeInfo(piNodes);
+        }
+
+        @Override
+        public boolean merge(MergeNode merge, Collection<TypeInfo> withStates) {
+            if (merge.forwardEndCount() > 1) {
+                HashMap<ValueNode, PiNodeList> newPiNodes = new HashMap<>();
+                for (Entry<ValueNode, PiNodeList> entry : piNodes.entrySet()) {
+                    PiNodeList list = entry.getValue();
+                    for (TypeInfo info : withStates) {
+                        PiNodeList other = info.piNodes.get(entry.getKey());
+                        if (other == null) {
+                            list = null;
+                        } else {
+                            list = list.merge(other);
+                        }
+                        if (list == null) {
+                            break;
+                        }
+                    }
+                    if (list != null) {
+                        newPiNodes.put(entry.getKey(), list);
+                    }
+                }
+                piNodes = newPiNodes;
+            }
+            return true;
+        }
+
+        @Override
+        public void loopBegin(LoopBeginNode loop) {
+        }
+
+        @Override
+        public void loopEnds(LoopBeginNode loop, Collection<TypeInfo> loopEndStates) {
+        }
+
+        @Override
+        public void afterSplit(FixedNode node) {
+            assert node.predecessor() != null;
+            assert node.predecessor() instanceof ControlSplitNode;
+//            TTY.println("after split: %s", node);
+            if (node.predecessor() instanceof IfNode) {
+                IfNode ifNode = (IfNode) node.predecessor();
+                if (ifNode.compare() instanceof InstanceOfNode) {
+                    InstanceOfNode instanceOf = (InstanceOfNode) ifNode.compare();
+                    assert node == ifNode.trueSuccessor() || node == ifNode.falseSuccessor();
+                    if ((node == ifNode.trueSuccessor() && !instanceOf.negated()) || (node == ifNode.falseSuccessor() && instanceOf.negated())) {
+                        ValueNode value = instanceOf.object();
+                        if (value.declaredType() != instanceOf.targetClass() || !value.stamp().nonNull()) {
+                            PiNode piNode = node.graph().unique(new PiNode(value, (BeginNode) node, StampFactory.declaredNonNull(instanceOf.targetClass())));
+                            PiNodeList list = piNodes.get(value);
+                            piNodes.put(value, new PiNodeList(piNode, list));
+                        }
+                    }
+                } else if (ifNode.compare() instanceof CompareNode) {
+                    CompareNode compare = (CompareNode) ifNode.compare();
+                    assert node == ifNode.trueSuccessor() || node == ifNode.falseSuccessor();
+                    if ((node == ifNode.trueSuccessor() && compare.condition() == Condition.EQ) || (node == ifNode.falseSuccessor() && compare.condition() == Condition.NE)) {
+                        if (compare.y().isConstant()) {
+                            ValueNode value = compare.x();
+                            PiNodeList list = piNodes.get(value);
+                            piNodes.put(value, new PiNodeList(compare.y(), list));
+                        }
+                    } else if ((node == ifNode.trueSuccessor() && compare.condition() == Condition.NE) || (node == ifNode.falseSuccessor() && compare.condition() == Condition.EQ)) {
+                        if (!compare.x().isConstant() && compare.y().isNullConstant() && !compare.x().stamp().nonNull()) {
+                            ValueNode value = compare.x();
+                            PiNode piNode;
+                            if (value.exactType() != null) {
+                                piNode = node.graph().unique(new PiNode(value, (BeginNode) node, StampFactory.declaredNonNull(value.exactType())));
+                            } else if (value.declaredType() != null) {
+                                piNode = node.graph().unique(new PiNode(value, (BeginNode) node, StampFactory.declaredNonNull(value.declaredType())));
+                            } else {
+                                piNode = node.graph().unique(new PiNode(value, (BeginNode) node, StampFactory.objectNonNull()));
+                            }
+                            PiNodeList list = piNodes.get(value);
+                            piNodes.put(value, new PiNodeList(piNode, list));
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private class Tool implements CanonicalizerTool {
+        @Override
+        public CiTarget target() {
+            return target;
+        }
+
+        @Override
+        public CiAssumptions assumptions() {
+            return assumptions;
+        }
+
+        @Override
+        public RiRuntime runtime() {
+            return runtime;
+        }
+    }
+
+    private final Tool tool = new Tool();
+
+    private class PropagateTypes extends ScheduledNodeIterator<TypeInfo> {
+
+        public PropagateTypes(FixedNode start) {
+            super(start, new TypeInfo(new HashMap<ValueNode, PiNodeList>()));
+        }
+
+        @Override
+        protected void node(ScheduledNode node) {
+            if (node instanceof Canonicalizable || node instanceof Invoke) {
+                NodeClassIterator iter = node.inputs().iterator();
+                ArrayList<Node> changedInputs = new ArrayList<>();
+                while (iter.hasNext()) {
+                    Position pos = iter.nextPosition();
+                    Node value = pos.get(node);
+                    PiNodeList list = state.piNodes.get(value);
+                    if (list != null) {
+                        changedInputs.add(list.replacement instanceof PiNode ? value : null);
+                        pos.set(node, list.replacement);
+                    } else {
+                        changedInputs.add(null);
+                    }
+                }
+
+                ValueNode canonical = null;
+                if (node instanceof Canonicalizable) {
+                    canonical = ((Canonicalizable) node).canonical(tool);
+                }
+
+                if (canonical == node) {
+                    iter = node.inputs().iterator();
+                    int i = 0;
+                    while (iter.hasNext()) {
+                        Position pos = iter.nextPosition();
+                        if (changedInputs.get(i) != null) {
+                            pos.set(node, changedInputs.get(i));
+                        }
+                        i++;
+                    }
+                } else {
+                    changedNodes.add(node);
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/types/ScheduledNodeIterator.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.compiler.types;
+
+import java.util.*;
+
+import com.oracle.max.graal.compiler.graph.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+
+public abstract class ScheduledNodeIterator<T extends MergeableState<T>> {
+
+    private final NodeBitMap visitedEnds;
+    private final Deque<ScheduledNode> nodeQueue;
+    private final IdentityHashMap<ScheduledNode, T> nodeStates;
+    private final FixedNode start;
+
+    protected T state;
+
+    public ScheduledNodeIterator(FixedNode start, T initialState) {
+        visitedEnds = start.graph().createNodeBitMap();
+        nodeQueue = new ArrayDeque<>();
+        nodeStates = new IdentityHashMap<>();
+        this.start = start;
+        this.state = initialState;
+    }
+
+    public void apply() {
+        ScheduledNode current = start;
+
+        do {
+            if (current instanceof LoopBeginNode) {
+                state.loopBegin((LoopBeginNode) current);
+                nodeStates.put(current, state);
+                state = state.clone();
+                loopBegin((LoopBeginNode) current);
+                current = current.scheduledNext();
+                assert current != null;
+            } else if (current instanceof LoopEndNode) {
+                loopEnd((LoopEndNode) current);
+                finishLoopEnds((LoopEndNode) current);
+                current = nextQueuedNode();
+            } else if (current instanceof MergeNode) {
+                merge((MergeNode) current);
+                current = current.scheduledNext();
+                assert current != null;
+            } else if (current instanceof EndNode) {
+                end((EndNode) current);
+                queueMerge((EndNode) current);
+                current = nextQueuedNode();
+            } else if (current instanceof ControlSplitNode) {
+                controlSplit((ControlSplitNode) current);
+                queueSuccessors(current);
+                current = nextQueuedNode();
+            } else {
+                ScheduledNode next = current.scheduledNext();
+                node(current);
+                if (next == null) {
+                    current = nextQueuedNode();
+                } else {
+                    current = next;
+                }
+            }
+        } while(current != null);
+    }
+
+    private void queueSuccessors(ScheduledNode x) {
+        nodeStates.put(x, state);
+        for (Node node : x.successors()) {
+            if (node != null) {
+                nodeQueue.addFirst((FixedNode) node);
+            }
+        }
+    }
+
+    private ScheduledNode nextQueuedNode() {
+        int maxIterations = nodeQueue.size();
+        while (maxIterations-- > 0) {
+            ScheduledNode node = nodeQueue.removeFirst();
+            if (node instanceof MergeNode) {
+                MergeNode merge = (MergeNode) node;
+                state = nodeStates.get(merge.forwardEndAt(0)).clone();
+                ArrayList<T> states = new ArrayList<>(merge.forwardEndCount() - 1);
+                for (int i = 1; i < merge.forwardEndCount(); i++) {
+                    T other = nodeStates.get(merge.forwardEndAt(i));
+                    assert other != null;
+                    states.add(other);
+                }
+                boolean ready = state.merge(merge, states);
+                if (ready) {
+                    return merge;
+                } else {
+                    nodeQueue.addLast(merge);
+                }
+            } else {
+                assert node.predecessor() != null;
+                state = nodeStates.get(node.predecessor()).clone();
+                state.afterSplit((FixedNode) node);
+                return node;
+            }
+        }
+        return null;
+    }
+
+    private void queueMerge(EndNode end) {
+        assert !visitedEnds.isMarked(end);
+        assert !nodeStates.containsKey(end);
+        nodeStates.put(end, state);
+        visitedEnds.mark(end);
+        MergeNode merge = end.merge();
+        boolean endsVisited = true;
+        for (int i = 0; i < merge.forwardEndCount(); i++) {
+            if (!visitedEnds.isMarked(merge.forwardEndAt(i))) {
+                endsVisited = false;
+                break;
+            }
+        }
+        if (endsVisited) {
+            nodeQueue.add(merge);
+        }
+    }
+
+    private void finishLoopEnds(LoopEndNode end) {
+        assert !visitedEnds.isMarked(end);
+        assert !nodeStates.containsKey(end);
+        nodeStates.put(end, state);
+        visitedEnds.mark(end);
+        LoopBeginNode begin = end.loopBegin();
+        boolean endsVisited = true;
+        for (LoopEndNode le : begin.loopEnds()) {
+            if (!visitedEnds.isMarked(le)) {
+                endsVisited = false;
+                break;
+            }
+        }
+        if (endsVisited) {
+            ArrayList<T> states = new ArrayList<>(begin.loopEnds().count());
+            for (LoopEndNode le : begin.orderedLoopEnds()) {
+                states.add(nodeStates.get(le));
+            }
+            T loopBeginState = nodeStates.get(begin);
+            if (loopBeginState != null) {
+                loopBeginState.loopEnds(begin, states);
+            }
+        }
+    }
+
+    protected abstract void node(ScheduledNode node);
+
+    protected void end(EndNode endNode) {
+        node(endNode);
+    }
+
+    protected void merge(MergeNode merge) {
+        node(merge);
+    }
+
+    protected void loopBegin(LoopBeginNode loopBegin) {
+        node(loopBegin);
+    }
+
+    protected void loopEnd(LoopEndNode loopEnd) {
+        node(loopEnd);
+    }
+
+    protected void controlSplit(ControlSplitNode controlSplit) {
+        node(controlSplit);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/ArrayMap.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.compiler.util;
+
+/**
+ * The {@code ArrayMap} class implements an efficient one-level map which is implemented
+ * as an array. Note that because of the one-level array inside, this data structure performs best
+ * when the range of integer keys is small and densely used. Note that the implementation can
+ * handle arbitrary intervals, including negative numbers, up to intervals of size 2^31 - 1.
+ */
+public class ArrayMap<T> {
+
+    private static final int INITIAL_SIZE = 5; // how big the initial array should be
+    private static final int EXTRA = 2; // how far on the left or right of a new element to grow
+
+    Object[] map;
+    int low;
+
+    /**
+     * Constructs a new {@code ArrayMap} with no initial assumptions.
+     */
+    public ArrayMap() {
+    }
+
+    /**
+     * Constructs a new {@code ArrayMap} that initially covers the specified interval.
+     * Note that this map will automatically expand if necessary later.
+     * @param low the low index, inclusive
+     * @param high the high index, exclusive
+     */
+    public ArrayMap(int low, int high) {
+        this.low = low;
+        this.map = new Object[high - low + 1];
+    }
+
+    /**
+     * Puts a new value in the map at the specified index.
+     * @param i the index at which to store the value
+     * @param value the value to store at the specified index
+     */
+    public void put(int i, T value) {
+        int index = i - low;
+        if (map == null) {
+            // no map yet
+            map = new Object[INITIAL_SIZE];
+            low = index - 2;
+            map[INITIAL_SIZE / 2] = value;
+        } else if (index < 0) {
+            // grow backwards
+            growBackward(i, value);
+        } else if (index >= map.length) {
+            // grow forwards
+            growForward(i, value);
+        } else {
+            // no growth necessary
+            map[index] = value;
+        }
+    }
+
+    /**
+     * Gets the value at the specified index in the map.
+     * @param i the index
+     * @return the value at the specified index; {@code null} if there is no value at the specified index,
+     * or if the index is out of the currently stored range
+     */
+    public T get(int i) {
+        int index = i - low;
+        if (map == null || index < 0 || index >= map.length) {
+            return null;
+        }
+        Class<T> type = null;
+        return Util.uncheckedCast(type, map[index]);
+    }
+
+    public int length() {
+        return map.length;
+    }
+
+    private void growBackward(int i, T value) {
+        int nlow = i - EXTRA;
+        Object[] nmap = new Object[low - nlow + map.length];
+        System.arraycopy(map, 0, nmap, low - nlow, map.length);
+        map = nmap;
+        low = nlow;
+        map[i - low] = value;
+    }
+
+    private void growForward(int i, T value) {
+        int nlen = i - low + 1 + EXTRA;
+        Object[] nmap = new Object[nlen];
+        System.arraycopy(map, 0, nmap, 0, map.length);
+        map = nmap;
+        map[i - low] = value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/BitMap2D.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.compiler.util;
+
+import com.oracle.max.graal.graph.*;
+
+/**
+ * This class implements a two-dimensional bitmap.
+ */
+public final class BitMap2D {
+
+    private BitMap map;
+    private final int bitsPerSlot;
+
+    private int bitIndex(int slotIndex, int bitWithinSlotIndex)  {
+      return slotIndex * bitsPerSlot + bitWithinSlotIndex;
+    }
+
+    private boolean verifyBitWithinSlotIndex(int index)  {
+      assert index < bitsPerSlot : "index " + index + " is out of bounds " + bitsPerSlot;
+      return true;
+    }
+
+    public BitMap2D(int sizeInSlots, int bitsPerSlot) {
+        map = new BitMap(sizeInSlots * bitsPerSlot);
+        this.bitsPerSlot = bitsPerSlot;
+    }
+
+    public int sizeInBits() {
+      return map.size();
+    }
+
+    // Returns number of full slots that have been allocated
+    public int sizeInSlots() {
+      return map.size() / bitsPerSlot;
+    }
+
+    public boolean isValidIndex(int slotIndex, int bitWithinSlotIndex) {
+      assert verifyBitWithinSlotIndex(bitWithinSlotIndex);
+      return (bitIndex(slotIndex, bitWithinSlotIndex) < sizeInBits());
+    }
+
+    public boolean at(int slotIndex, int bitWithinSlotIndex)  {
+      assert verifyBitWithinSlotIndex(bitWithinSlotIndex);
+      return map.get(bitIndex(slotIndex, bitWithinSlotIndex));
+    }
+
+    public void setBit(int slotIndex, int bitWithinSlotIndex) {
+      assert verifyBitWithinSlotIndex(bitWithinSlotIndex);
+      map.set(bitIndex(slotIndex, bitWithinSlotIndex));
+    }
+
+    public void clearBit(int slotIndex, int bitWithinSlotIndex) {
+      assert verifyBitWithinSlotIndex(bitWithinSlotIndex);
+      map.clear(bitIndex(slotIndex, bitWithinSlotIndex));
+    }
+
+    public void atPutGrow(int slotIndex, int bitWithinSlotIndex, boolean value) {
+       int size = sizeInSlots();
+       if (size <= slotIndex) {
+           while (size <= slotIndex) {
+               size *= 2;
+           }
+           BitMap newBitMap = new BitMap(size * bitsPerSlot);
+           newBitMap.setUnion(map);
+           map = newBitMap;
+       }
+
+       if (value) {
+           setBit(slotIndex, bitWithinSlotIndex);
+       } else {
+           clearBit(slotIndex, bitWithinSlotIndex);
+       }
+    }
+
+    public void clear() {
+        map.clearAll();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/BlockWorkList.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.compiler.util;
+
+import com.oracle.max.graal.nodes.*;
+
+/**
+ * This class implements a worklist for dealing with blocks. The worklist can
+ * operate either as a stack (i.e. first-in / last-out), or as a sorted list,
+ * where blocks can be sorted by a supplied number. The latter usage lends itself
+ * naturally to iterative dataflow analysis problems.
+ *
+ * This implementation is not able to tell if a block is in the worklist already.
+ * Note that this implementation is slightly less efficient than the dedicated
+ * work list in {@link com.oracle.max.graal.compiler.graph.ScopeData}, because this worklist uses
+ * an externally supplied number.
+ */
+public class BlockWorkList {
+    MergeNode[] workList;
+    int[] workListNumbers;
+    int workListIndex;
+
+    /**
+     * Adds a block to this list in an unsorted fashion, like a stack.
+     * @param block the block to add
+     */
+    public void add(MergeNode block) {
+        if (workList == null) {
+            // worklist not allocated yet
+            allocate();
+        } else if (workListIndex == workList.length) {
+            // need to grow the worklist
+            grow();
+        }
+        // put the block at the end of the array
+        workList[workListIndex++] = block;
+    }
+
+    /**
+     * Adds a block to this list, sorted by the supplied number. The block
+     * with the lowest number is returned upon subsequent removes.
+     * @param block the block to add
+     * @param number the number used to sort the block
+     */
+    public void addSorted(MergeNode block, int number) {
+        if (workList == null) {
+            // worklist not allocated yet
+            allocate();
+        } else if (workListIndex == workList.length) {
+            // need to grow the worklist
+            grow();
+        }
+        // put the block at the end of the array
+        workList[workListIndex] = block;
+        workListNumbers[workListIndex] = number;
+        workListIndex++;
+        int i = workListIndex - 2;
+        // push block towards the beginning of the array
+        for (; i >= 0; i--) {
+            int n = workListNumbers[i];
+            if (n >= number) {
+                break; // already in the right position
+            }
+            workList[i + 1] = workList[i]; // bubble b down by one
+            workList[i] = block;           // and overwrite its place with block
+            workListNumbers[i + 1] = n;    // bubble n down by one
+            workListNumbers[i] = number;   // and overwrite its place with number
+        }
+    }
+
+    /**
+     * Removes the next block from this work list. If the blocks have been added
+     * in a sorted order, then the block with the lowest number is returned. Otherwise,
+     * the last block added is returned.
+     * @return the next block in the list
+     */
+    public MergeNode removeFromWorkList() {
+        if (workListIndex != 0) {
+            return workList[--workListIndex];
+        }
+        return null;
+    }
+
+    /**
+     * Checks whether the list is empty.
+     * @return {@code true} if this list is empty
+     */
+    public boolean isEmpty() {
+        return workListIndex == 0;
+    }
+
+    private void allocate() {
+        workList = new MergeNode[5];
+        workListNumbers = new int[5];
+    }
+
+    private void grow() {
+        int prevLength = workList.length;
+        MergeNode[] nworkList = new MergeNode[prevLength * 3];
+        System.arraycopy(workList, 0, nworkList, 0, prevLength);
+        workList = nworkList;
+
+        int[] nworkListNumbers = new int[prevLength * 3];
+        System.arraycopy(workListNumbers, 0, nworkListNumbers, 0, prevLength);
+        workListNumbers = nworkListNumbers;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/GraphOrder.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.compiler.util;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+
+public class GraphOrder implements Iterable<Node> {
+
+    private final ArrayList<Node> nodes = new ArrayList<>();
+
+    private GraphOrder() {
+    }
+
+    public GraphOrder(Graph graph) {
+        NodeBitMap visited = graph.createNodeBitMap();
+
+        for (ReturnNode node : graph.getNodes(ReturnNode.class)) {
+            visitForward(visited, node);
+        }
+        for (UnwindNode node : graph.getNodes(UnwindNode.class)) {
+            visitForward(visited, node);
+        }
+        for (DeoptimizeNode node : graph.getNodes(DeoptimizeNode.class)) {
+            visitForward(visited, node);
+        }
+    }
+
+    public static GraphOrder forwardGraph(Graph graph) {
+        GraphOrder result = new GraphOrder();
+
+        NodeBitMap visited = graph.createNodeBitMap();
+
+        for (ReturnNode node : graph.getNodes(ReturnNode.class)) {
+            result.visitForward(visited, node);
+        }
+        for (UnwindNode node : graph.getNodes(UnwindNode.class)) {
+            result.visitForward(visited, node);
+        }
+        for (DeoptimizeNode node : graph.getNodes(DeoptimizeNode.class)) {
+            result.visitForward(visited, node);
+        }
+        return result;
+    }
+
+    public static GraphOrder backwardGraph(Graph graph) {
+        GraphOrder result = new GraphOrder();
+
+        NodeBitMap visited = graph.createNodeBitMap();
+
+        for (Node node : forwardGraph(graph)) {
+            result.visitBackward(visited, node);
+        }
+        return result;
+    }
+
+    private void visitForward(NodeBitMap visited, Node node) {
+        if (node != null && !visited.isMarked(node)) {
+            visited.mark(node);
+            if (node.predecessor() != null) {
+                visitForward(visited, node.predecessor());
+            }
+            if (node instanceof MergeNode) {
+                // make sure that the cfg predecessors of a MergeNode are processed first
+                MergeNode merge = (MergeNode) node;
+                for (int i = 0; i < merge.forwardEndCount(); i++) {
+                    visitForward(visited, merge.forwardEndAt(i));
+                }
+            }
+            for (Node input : node.inputs()) {
+                visitForward(visited, input);
+            }
+            nodes.add(node);
+        }
+    }
+
+    private void visitBackward(NodeBitMap visited, Node node) {
+        if (node != null && !visited.isMarked(node)) {
+            visited.mark(node);
+            for (Node successor : node.successors()) {
+                visitBackward(visited, successor);
+            }
+            for (Node usage : node.usages()) {
+                visitBackward(visited, usage);
+            }
+            nodes.add(node);
+        }
+    }
+
+    @Override
+    public Iterator<Node> iterator() {
+        return new Iterator<Node>() {
+
+            private int pos = 0;
+
+            private void removeDeleted() {
+                while (pos < nodes.size() && nodes.get(pos).isDeleted()) {
+                    pos++;
+                }
+            }
+
+            @Override
+            public boolean hasNext() {
+                removeDeleted();
+                return pos < nodes.size();
+            }
+
+            @Override
+            public Node next() {
+                return nodes.get(pos++);
+            }
+
+            @Override
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,905 @@
+/*
+ * 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.max.graal.compiler.util;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.cri.ri.RiType.Representation;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction;
+import com.oracle.max.graal.nodes.PhiNode.PhiType;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.java.*;
+import com.oracle.max.graal.nodes.java.MethodCallTargetNode.InvokeKind;
+import com.oracle.max.graal.nodes.util.*;
+
+public class InliningUtil {
+
+    public interface InliningCallback {
+        StructuredGraph buildGraph(RiResolvedMethod method);
+        double inliningWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke);
+        void recordMethodContentsAssumption(RiResolvedMethod method);
+        void recordConcreteMethodAssumption(RiResolvedMethod method, RiResolvedType context, RiResolvedMethod impl);
+    }
+
+    public static String methodName(RiResolvedMethod method) {
+        return CiUtil.format("%H.%n(%p):%r", method) + " (" + method.codeSize() + " bytes)";
+    }
+
+    private static String methodName(RiResolvedMethod method, Invoke invoke) {
+        if (Debug.isLogEnabled()) {
+            if (invoke != null && invoke.stateAfter() != null) {
+                RiMethod parent = invoke.stateAfter().method();
+                return parent.name() + "@" + invoke.bci() + ": " + CiUtil.format("%H.%n(%p):%r", method) + " (" + method.codeSize() + " bytes)";
+            } else {
+                return CiUtil.format("%H.%n(%p):%r", method) + " (" + method.codeSize() + " bytes)";
+            }
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Represents an opportunity for inlining at the given invoke, with the given weight and level.
+     * The weight is the amortized weight of the additional code - so smaller is better.
+     * The level is the number of nested inlinings that lead to this invoke.
+     */
+    public abstract static class InlineInfo implements Comparable<InlineInfo> {
+        public final Invoke invoke;
+        public final double weight;
+        public final int level;
+
+        public InlineInfo(Invoke invoke, double weight, int level) {
+            this.invoke = invoke;
+            this.weight = weight;
+            this.level = level;
+        }
+
+        public abstract int compiledCodeSize();
+
+        @Override
+        public int compareTo(InlineInfo o) {
+            return (weight < o.weight) ? -1 : (weight > o.weight) ? 1 : 0;
+        }
+
+        protected static StructuredGraph getGraph(final RiResolvedMethod concrete, final InliningCallback callback) {
+            return Debug.scope("Inlining", concrete, new Callable<StructuredGraph>() {
+                @Override
+                public StructuredGraph call() throws Exception {
+                    return callback.buildGraph(concrete);
+                }
+            });
+        }
+
+        public abstract boolean canDeopt();
+
+        /**
+         * Performs the inlining described by this object and returns the node that represents the return value of the
+         * inlined method (or null for void methods and methods that have no non-exceptional exit).
+         *
+         * @param graph
+         * @param runtime
+         * @param callback
+         */
+        public abstract void inline(StructuredGraph graph, GraalRuntime runtime, InliningCallback callback);
+    }
+
+    /**
+     * Represents an inlining opportunity where the compiler can statically determine a monomorphic target method and
+     * therefore is able to determine the called method exactly.
+     */
+    private static class ExactInlineInfo extends InlineInfo {
+        public final RiResolvedMethod concrete;
+
+        public ExactInlineInfo(Invoke invoke, double weight, int level, RiResolvedMethod concrete) {
+            super(invoke, weight, level);
+            this.concrete = concrete;
+        }
+
+        @Override
+        public void inline(StructuredGraph compilerGraph, GraalRuntime runtime, final InliningCallback callback) {
+            StructuredGraph graph = getGraph(concrete, callback);
+            assert !IntrinsificationPhase.canIntrinsify(invoke, concrete, runtime);
+            callback.recordMethodContentsAssumption(concrete);
+            InliningUtil.inline(invoke, graph, true);
+        }
+
+        @Override
+        public int compiledCodeSize() {
+            return concrete.compiledCodeSize();
+        }
+
+        @Override
+        public String toString() {
+            return "exact inlining " + CiUtil.format("%H.%n(%p):%r", concrete);
+        }
+
+        @Override
+        public boolean canDeopt() {
+            return false;
+        }
+    }
+
+    /**
+     * Represents an inlining opportunity for which profiling information suggests a monomorphic receiver, but for which
+     * the receiver type cannot be proven. A type check guard will be generated if this inlining is performed.
+     */
+    private static class TypeGuardInlineInfo extends InlineInfo {
+        public final RiResolvedMethod concrete;
+        public final RiResolvedType type;
+
+        public TypeGuardInlineInfo(Invoke invoke, double weight, int level, RiResolvedMethod concrete, RiResolvedType type) {
+            super(invoke, weight, level);
+            this.concrete = concrete;
+            this.type = type;
+        }
+
+        @Override
+        public int compiledCodeSize() {
+            return concrete.compiledCodeSize();
+        }
+
+        @Override
+        public void inline(StructuredGraph graph, GraalRuntime runtime, InliningCallback callback) {
+            // receiver null check must be before the type check
+            InliningUtil.receiverNullCheck(invoke);
+            ValueNode receiver = invoke.callTarget().receiver();
+            ReadHubNode objectClass = graph.add(new ReadHubNode(receiver));
+            IsTypeNode isTypeNode = graph.unique(new IsTypeNode(objectClass, type));
+            FixedGuardNode guard = graph.add(new FixedGuardNode(isTypeNode));
+            AnchorNode anchor = graph.add(new AnchorNode());
+            assert invoke.predecessor() != null;
+
+            CheckCastNode checkCast = createAnchoredReceiver(graph, runtime, anchor, type, receiver);
+            invoke.callTarget().replaceFirstInput(receiver, checkCast);
+
+            graph.addBeforeFixed(invoke.node(), objectClass);
+            graph.addBeforeFixed(invoke.node(), guard);
+            graph.addBeforeFixed(invoke.node(), anchor);
+
+            Debug.log("inlining 1 method using 1 type check");
+
+            StructuredGraph calleeGraph = getGraph(concrete, callback);
+            assert !IntrinsificationPhase.canIntrinsify(invoke, concrete, runtime);
+            callback.recordMethodContentsAssumption(concrete);
+            InliningUtil.inline(invoke, calleeGraph, false);
+        }
+
+        @Override
+        public String toString() {
+            return "type-checked inlining " + CiUtil.format("%H.%n(%p):%r", concrete);
+        }
+
+        @Override
+        public boolean canDeopt() {
+            return true;
+        }
+    }
+
+    /**
+     * Polymorphic inlining of m methods with n type checks (n >= m) in case that the profiling information suggests a reasonable
+     * amounts of different receiver types and different methods. If an unknown type is encountered a deoptimization is triggered.
+     */
+    private static class MultiTypeGuardInlineInfo extends InlineInfo {
+        public final List<RiResolvedMethod> concretes;
+        public final RiResolvedType[] types;
+        public final int[] typesToConcretes;
+        public final double[] branchProbabilities;
+        public final double notRecordedTypeProbability;
+
+        public MultiTypeGuardInlineInfo(Invoke invoke, double weight, int level, List<RiResolvedMethod> concretes, RiResolvedType[] types,
+                        int[] typesToConcretes, double[] branchProbabilities, double notRecordedTypeProbability) {
+            super(invoke, weight, level);
+            assert concretes.size() > 0 && concretes.size() <= types.length : "must have at least one method but no more than types methods";
+            assert types.length == typesToConcretes.length && types.length == branchProbabilities.length : "array length must match";
+
+            this.concretes = concretes;
+            this.types = types;
+            this.typesToConcretes = typesToConcretes;
+            this.branchProbabilities = branchProbabilities;
+            this.notRecordedTypeProbability = notRecordedTypeProbability;
+        }
+
+        @Override
+        public int compiledCodeSize() {
+            int result = 0;
+            for (RiResolvedMethod m: concretes) {
+                result += m.compiledCodeSize();
+            }
+            return result;
+        }
+
+        @Override
+        public void inline(StructuredGraph graph, GraalRuntime runtime, InliningCallback callback) {
+            int numberOfMethods = concretes.size();
+            boolean hasReturnValue = invoke.node().kind() != CiKind.Void;
+
+            // receiver null check must be the first node
+            InliningUtil.receiverNullCheck(invoke);
+            if (numberOfMethods > 1 || shouldFallbackToInvoke()) {
+                inlineMultipleMethods(graph, runtime, callback, numberOfMethods, hasReturnValue);
+            } else {
+                inlineSingleMethod(graph, runtime, callback);
+            }
+
+            Debug.log("inlining %d methods with %d type checks and falling back to %s if violated", numberOfMethods, types.length, shouldFallbackToInvoke() ? "invocation" : "deoptimization");
+        }
+
+        private boolean shouldFallbackToInvoke() {
+            return notRecordedTypeProbability > 0;
+        }
+
+        private void inlineMultipleMethods(StructuredGraph graph, GraalRuntime runtime, InliningCallback callback, int numberOfMethods, boolean hasReturnValue) {
+            FixedNode continuation = invoke.next();
+
+            // setup merge and phi nodes for results and exceptions
+            MergeNode returnMerge = graph.add(new MergeNode());
+            returnMerge.setProbability(invoke.probability());
+            returnMerge.setStateAfter(invoke.stateAfter().duplicate(invoke.stateAfter().bci));
+
+            PhiNode returnValuePhi = null;
+            if (hasReturnValue) {
+                returnValuePhi = graph.unique(new PhiNode(invoke.node().kind(), returnMerge, PhiType.Value));
+            }
+
+            MergeNode exceptionMerge = null;
+            PhiNode exceptionObjectPhi = null;
+            if (invoke instanceof InvokeWithExceptionNode) {
+                InvokeWithExceptionNode invokeWithException = (InvokeWithExceptionNode) invoke;
+                BeginNode exceptionEdge = invokeWithException.exceptionEdge();
+                ExceptionObjectNode exceptionObject = (ExceptionObjectNode) exceptionEdge.next();
+
+                exceptionMerge = graph.add(new MergeNode());
+                exceptionMerge.setProbability(exceptionEdge.probability());
+
+                FixedNode exceptionSux = exceptionObject.next();
+                graph.addBeforeFixed(exceptionSux, exceptionMerge);
+                exceptionObjectPhi = graph.unique(new PhiNode(CiKind.Object, exceptionMerge, PhiType.Value));
+                exceptionMerge.setStateAfter(exceptionEdge.stateAfter().duplicateModified(invoke.stateAfter().bci, true, CiKind.Void, exceptionObjectPhi));
+            }
+
+            // create one separate block for each invoked method
+            BeginNode[] calleeEntryNodes = new BeginNode[numberOfMethods];
+            for (int i = 0; i < numberOfMethods; i++) {
+                int predecessors = getPredecessorCount(i);
+                calleeEntryNodes[i] = createInvocationBlock(graph, invoke, returnMerge, returnValuePhi, exceptionMerge, exceptionObjectPhi, predecessors, true);
+            }
+
+            // create the successor for an unknown type
+            FixedNode unknownTypeNode;
+            if (shouldFallbackToInvoke()) {
+                unknownTypeNode = createInvocationBlock(graph, invoke, returnMerge, returnValuePhi, exceptionMerge, exceptionObjectPhi, 1, false);
+            } else {
+                unknownTypeNode = graph.add(new DeoptimizeNode(DeoptAction.InvalidateReprofile));
+            }
+
+            // replace the invoke exception edge
+            if (invoke instanceof InvokeWithExceptionNode) {
+                InvokeWithExceptionNode invokeWithExceptionNode = (InvokeWithExceptionNode) invoke;
+                BeginNode exceptionEdge = invokeWithExceptionNode.exceptionEdge();
+                ExceptionObjectNode exceptionObject = (ExceptionObjectNode) exceptionEdge.next();
+                exceptionObject.replaceAtUsages(exceptionObjectPhi);
+                exceptionObject.setNext(null);
+                GraphUtil.killCFG(invokeWithExceptionNode.exceptionEdge());
+            }
+
+            // replace the invoke with a cascade of if nodes
+            ReadHubNode objectClassNode = graph.add(new ReadHubNode(invoke.callTarget().receiver()));
+            graph.addBeforeFixed(invoke.node(), objectClassNode);
+            FixedNode dispatchOnType = createDispatchOnType(graph, objectClassNode, calleeEntryNodes, unknownTypeNode);
+
+            assert invoke.next() == continuation;
+            invoke.setNext(null);
+            returnMerge.setNext(continuation);
+            invoke.node().replaceAtUsages(returnValuePhi);
+            invoke.node().replaceAndDelete(dispatchOnType);
+
+            // do the actual inlining for every invoke
+            for (int i = 0; i < calleeEntryNodes.length; i++) {
+                BeginNode node = calleeEntryNodes[i];
+                Invoke invokeForInlining = (Invoke) node.next();
+
+                RiResolvedType commonType = getLeastCommonType(i);
+                ValueNode receiver = invokeForInlining.callTarget().receiver();
+                CheckCastNode checkCast = createAnchoredReceiver(graph, runtime, node, commonType, receiver);
+                invokeForInlining.callTarget().replaceFirstInput(receiver, checkCast);
+
+                RiResolvedMethod concrete = concretes.get(i);
+                StructuredGraph calleeGraph = getGraph(concrete, callback);
+                callback.recordMethodContentsAssumption(concrete);
+                assert !IntrinsificationPhase.canIntrinsify(invokeForInlining, concrete, runtime);
+                InliningUtil.inline(invokeForInlining, calleeGraph, false);
+            }
+        }
+
+        private RiResolvedType getLeastCommonType(int concreteMethodIndex) {
+            RiResolvedType commonType = null;
+            for (int i = 0; i < typesToConcretes.length; i++) {
+                if (typesToConcretes[i] == concreteMethodIndex) {
+                    if (commonType == null) {
+                        commonType = types[i];
+                    } else {
+                        commonType = commonType.leastCommonAncestor(types[i]);
+                    }
+                }
+            }
+            assert commonType != null;
+            return commonType;
+        }
+
+        private void inlineSingleMethod(StructuredGraph graph, GraalRuntime runtime, InliningCallback callback) {
+            assert concretes.size() == 1 && types.length > 1 && !shouldFallbackToInvoke() && notRecordedTypeProbability == 0;
+
+            MergeNode calleeEntryNode = graph.add(new MergeNode());
+            calleeEntryNode.setProbability(invoke.probability());
+            ReadHubNode objectClassNode = graph.add(new ReadHubNode(invoke.callTarget().receiver()));
+            graph.addBeforeFixed(invoke.node(), objectClassNode);
+
+            FixedNode unknownTypeNode = graph.add(new DeoptimizeNode(DeoptAction.InvalidateReprofile));
+            FixedNode dispatchOnType = createDispatchOnType(graph, objectClassNode, new BeginNode[] {calleeEntryNode}, unknownTypeNode);
+
+            FixedWithNextNode pred = (FixedWithNextNode) invoke.node().predecessor();
+            pred.setNext(dispatchOnType);
+            calleeEntryNode.setNext(invoke.node());
+
+            RiResolvedMethod concrete = concretes.get(0);
+            StructuredGraph calleeGraph = getGraph(concrete, callback);
+            assert !IntrinsificationPhase.canIntrinsify(invoke, concrete, runtime);
+            callback.recordMethodContentsAssumption(concrete);
+            InliningUtil.inline(invoke, calleeGraph, false);
+        }
+
+        private FixedNode createDispatchOnType(StructuredGraph graph, ReadHubNode objectClassNode, BeginNode[] calleeEntryNodes, FixedNode unknownTypeSux) {
+            assert types.length > 1;
+
+            // TODO (ch) set probabilities for all created fixed nodes...
+            int lastIndex = types.length - 1;
+            FixedNode nextNode = createTypeCheck(graph, objectClassNode, types[lastIndex], calleeEntryNodes[typesToConcretes[lastIndex]], unknownTypeSux, branchProbabilities[lastIndex]);
+            for (int i = lastIndex - 1; i >= 0; i--) {
+                nextNode = createTypeCheck(graph, objectClassNode, types[i], calleeEntryNodes[typesToConcretes[i]], nextNode, branchProbabilities[i]);
+            }
+
+            return nextNode;
+        }
+
+        private static FixedNode createTypeCheck(StructuredGraph graph, ReadHubNode objectClassNode, RiResolvedType type, BeginNode tsux, FixedNode nextNode, double tsuxProbability) {
+            IfNode result;
+            IsTypeNode isTypeNode = graph.unique(new IsTypeNode(objectClassNode, type));
+            if (tsux instanceof MergeNode) {
+                EndNode endNode = graph.add(new EndNode());
+                result = graph.add(new IfNode(isTypeNode, endNode, nextNode, tsuxProbability));
+                ((MergeNode) tsux).addForwardEnd(endNode);
+            } else {
+                result = graph.add(new IfNode(isTypeNode, tsux, nextNode, tsuxProbability));
+            }
+            return result;
+        }
+
+        private int getPredecessorCount(int concreteMethodIndex) {
+            if (concretes.size() == types.length) {
+                return 1;
+            } else {
+                int count = 0;
+                for (int i = 0; i < typesToConcretes.length; i++) {
+                    if (typesToConcretes[i] == concreteMethodIndex) {
+                        count++;
+                    }
+                }
+                return count;
+            }
+        }
+
+        private static BeginNode createInvocationBlock(StructuredGraph graph, Invoke invoke, MergeNode returnMerge, PhiNode returnValuePhi,
+                        MergeNode exceptionMerge, PhiNode exceptionObjectPhi, int predecessors, boolean useForInlining) {
+            Invoke duplicatedInvoke = duplicateInvokeForInlining(graph, invoke, exceptionMerge, exceptionObjectPhi, useForInlining);
+            // TODO (ch) set probabilities
+            BeginNode calleeEntryNode = graph.add(predecessors > 1 ? new MergeNode() : new BeginNode());
+            calleeEntryNode.setNext(duplicatedInvoke.node());
+
+            EndNode endNode = graph.add(new EndNode());
+            // TODO (ch) set probability
+            duplicatedInvoke.setNext(endNode);
+            returnMerge.addForwardEnd(endNode);
+            if (returnValuePhi != null) {
+                returnValuePhi.addInput(duplicatedInvoke.node());
+            }
+            return calleeEntryNode;
+        }
+
+        private static Invoke duplicateInvokeForInlining(StructuredGraph graph, Invoke invoke, MergeNode exceptionMerge, PhiNode exceptionObjectPhi, boolean useForInlining) {
+            Invoke result = (Invoke) invoke.node().copyWithInputs();
+            Node callTarget = result.callTarget().copyWithInputs();
+            result.node().replaceFirstInput(result.callTarget(), callTarget);
+            result.setUseForInlining(useForInlining);
+
+            CiKind kind = invoke.node().kind();
+            if (!kind.isVoid()) {
+                FrameState stateAfter = invoke.stateAfter();
+                stateAfter = stateAfter.duplicate(stateAfter.bci);
+                stateAfter.replaceFirstInput(invoke.node(), result.node());
+                result.setStateAfter(stateAfter);
+            }
+
+            if (invoke instanceof InvokeWithExceptionNode) {
+                assert exceptionMerge != null && exceptionObjectPhi != null;
+
+                InvokeWithExceptionNode invokeWithException = (InvokeWithExceptionNode) invoke;
+                BeginNode exceptionEdge = invokeWithException.exceptionEdge();
+                ExceptionObjectNode exceptionObject = (ExceptionObjectNode) exceptionEdge.next();
+                FrameState stateAfterException = exceptionObject.stateAfter();
+
+                BeginNode newExceptionEdge = (BeginNode) exceptionEdge.copyWithInputs();
+                ExceptionObjectNode newExceptionObject = (ExceptionObjectNode) exceptionObject.copyWithInputs();
+                // set new state (pop old exception object, push new one)
+                newExceptionObject.setStateAfter(stateAfterException.duplicateModified(stateAfterException.bci, stateAfterException.rethrowException(), CiKind.Object, newExceptionObject));
+                newExceptionEdge.setNext(newExceptionObject);
+
+                EndNode endNode = graph.add(new EndNode());
+                newExceptionObject.setNext(endNode);
+                exceptionMerge.addForwardEnd(endNode);
+                exceptionObjectPhi.addInput(newExceptionObject);
+
+                ((InvokeWithExceptionNode) result).setExceptionEdge(newExceptionEdge);
+            }
+            return result;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder builder = new StringBuilder(String.format("inlining %d methods with %d type checks: ", concretes.size(), types.length));
+            for (int i = 0; i < concretes.size(); i++) {
+                builder.append(CiUtil.format("  %H.%n(%p):%r", concretes.get(i)));
+            }
+            return builder.toString();
+        }
+
+        @Override
+        public boolean canDeopt() {
+            return true;
+        }
+    }
+
+
+    /**
+     * Represents an inlining opportunity where the current class hierarchy leads to a monomorphic target method,
+     * but for which an assumption has to be registered because of non-final classes.
+     */
+    private static class AssumptionInlineInfo extends ExactInlineInfo {
+        public final RiResolvedType context;
+
+        public AssumptionInlineInfo(Invoke invoke, double weight, int level, RiResolvedType context, RiResolvedMethod concrete) {
+            super(invoke, weight, level, concrete);
+            this.context = context;
+        }
+
+        @Override
+        public void inline(StructuredGraph graph, GraalRuntime runtime, InliningCallback callback) {
+            if (Debug.isLogEnabled()) {
+                String targetName = CiUtil.format("%H.%n(%p):%r", invoke.callTarget().targetMethod());
+                String concreteName = CiUtil.format("%H.%n(%p):%r", concrete);
+                Debug.log("recording concrete method assumption: %s on receiver type %s -> %s", targetName, context, concreteName);
+            }
+            callback.recordConcreteMethodAssumption(invoke.callTarget().targetMethod(), context, concrete);
+
+            super.inline(graph, runtime, callback);
+        }
+
+        @Override
+        public String toString() {
+            return "inlining with assumption " + CiUtil.format("%H.%n(%p):%r", concrete);
+        }
+
+        @Override
+        public boolean canDeopt() {
+            return true;
+        }
+    }
+
+    /**
+     * Determines if inlining is possible at the given invoke node.
+     * @param invoke the invoke that should be inlined
+     * @param level the number of nested inlinings that lead to this invoke, or 0 if the invoke was part of the initial graph
+     * @param runtime a GraalRuntime instance used to determine of the invoke can be inlined and/or should be intrinsified
+     * @param callback a callback that is used to determine the weight of a specific inlining
+     * @return an instance of InlineInfo, or null if no inlining is possible at the given invoke
+     */
+    public static InlineInfo getInlineInfo(Invoke invoke, int level, GraalRuntime runtime, CiAssumptions assumptions, InliningCallback callback) {
+        if (!checkInvokeConditions(invoke)) {
+            return null;
+        }
+        RiResolvedMethod parent = invoke.stateAfter().method();
+        MethodCallTargetNode callTarget = invoke.callTarget();
+        RiResolvedMethod targetMethod = callTarget.targetMethod();
+
+        if (targetMethod == null) {
+            return null;
+        }
+        if (callTarget.invokeKind() == InvokeKind.Special || targetMethod.canBeStaticallyBound()) {
+            if (checkTargetConditions(invoke, targetMethod)) {
+                double weight = callback == null ? 0 : callback.inliningWeight(parent, targetMethod, invoke);
+                return new ExactInlineInfo(invoke, weight, level, targetMethod);
+            }
+            return null;
+        }
+        if (callTarget.receiver().exactType() != null) {
+            RiResolvedType exact = callTarget.receiver().exactType();
+            assert exact.isSubtypeOf(targetMethod.holder()) : exact + " subtype of " + targetMethod.holder() + " for " + targetMethod;
+            RiResolvedMethod resolved = exact.resolveMethodImpl(targetMethod);
+            if (checkTargetConditions(invoke, resolved)) {
+                double weight = callback == null ? 0 : callback.inliningWeight(parent, resolved, invoke);
+                return new ExactInlineInfo(invoke, weight, level, resolved);
+            }
+            return null;
+        }
+        RiResolvedType holder = targetMethod.holder();
+
+        if (callTarget.receiver().declaredType() != null) {
+            RiResolvedType declared = callTarget.receiver().declaredType();
+            // the invoke target might be more specific than the holder (happens after inlining: locals lose their declared type...)
+            // TODO (ls) fix this
+            if (declared != null && declared.isSubtypeOf(holder)) {
+                holder = declared;
+            }
+        }
+        // TODO (tw) fix this
+        if (assumptions != null) {
+            RiResolvedMethod concrete = holder.uniqueConcreteMethod(targetMethod);
+            if (concrete != null) {
+                if (checkTargetConditions(invoke, concrete)) {
+                    double weight = callback == null ? 0 : callback.inliningWeight(parent, concrete, invoke);
+                    return new AssumptionInlineInfo(invoke, weight, level, holder, concrete);
+                }
+                return null;
+            }
+        }
+
+        // type check based inlining
+        RiProfilingInfo profilingInfo = parent.profilingInfo();
+        RiTypeProfile typeProfile = profilingInfo.getTypeProfile(invoke.bci());
+        if (typeProfile != null) {
+            RiResolvedType[] types = typeProfile.getTypes();
+            double[] probabilities = typeProfile.getProbabilities();
+
+            if (types != null && probabilities != null && types.length > 0) {
+                assert types.length == probabilities.length : "length must match";
+                double notRecordedTypeProbability = typeProfile.getNotRecordedProbability();
+                if (types.length == 1 && notRecordedTypeProbability == 0) {
+                    if (GraalOptions.InlineMonomorphicCalls) {
+                        RiResolvedType type = types[0];
+                        RiResolvedMethod concrete = type.resolveMethodImpl(targetMethod);
+                        if (checkTargetConditions(invoke, concrete)) {
+                            double weight = callback == null ? 0 : callback.inliningWeight(parent, concrete, invoke);
+                            return new TypeGuardInlineInfo(invoke, weight, level, concrete, type);
+                        }
+
+                        Debug.log("not inlining %s because method can't be inlined", methodName(targetMethod, invoke));
+                        return null;
+                    } else {
+                        Debug.log("not inlining %s because GraalOptions.InlinePolymorphicCalls == false", methodName(targetMethod, invoke));
+                        return null;
+                    }
+                } else {
+                    if (GraalOptions.InlinePolymorphicCalls && notRecordedTypeProbability == 0 || GraalOptions.InlineMegamorphicCalls && notRecordedTypeProbability > 0) {
+                        // TODO (ch) inlining of multiple methods should work differently
+                        // 1. check which methods can be inlined
+                        // 2. for those methods, use weight and probability to compute which of them should be inlined
+                        // 3. do the inlining
+                        //    a) all seen methods can be inlined -> do so and guard with deopt
+                        //    b) some methods can be inlined -> inline them and fall back to invocation if violated
+                        // TODO (ch) sort types by probability
+
+                        // determine concrete methods and map type to specific method
+                        ArrayList<RiResolvedMethod> concreteMethods = new ArrayList<>();
+                        int[] typesToConcretes = new int[types.length];
+                        for (int i = 0; i < types.length; i++) {
+                            RiResolvedMethod concrete = types[i].resolveMethodImpl(targetMethod);
+
+                            int index = concreteMethods.indexOf(concrete);
+                            if (index < 0) {
+                                index = concreteMethods.size();
+                                concreteMethods.add(concrete);
+                            }
+                            typesToConcretes[i] = index;
+                        }
+
+                        double totalWeight = 0;
+                        boolean canInline = true;
+                        for (RiResolvedMethod concrete: concreteMethods) {
+                            if (!checkTargetConditions(invoke, concrete)) {
+                                canInline = false;
+                                break;
+                            }
+                            totalWeight += callback == null ? 0 : callback.inliningWeight(parent, concrete, invoke);
+                        }
+
+                        if (canInline) {
+                            convertTypeToBranchProbabilities(probabilities, notRecordedTypeProbability);
+                            return new MultiTypeGuardInlineInfo(invoke, totalWeight, level, concreteMethods, types, typesToConcretes, probabilities, notRecordedTypeProbability);
+                        } else {
+                            Debug.log("not inlining %s because it is a polymorphic method call and at least one invoked method cannot be inlined", methodName(targetMethod, invoke));
+                            return null;
+                        }
+                    } else {
+                        Debug.log("not inlining %s because GraalOptions.InlineMonomorphicCalls == false", methodName(targetMethod, invoke));
+                        return null;
+                    }
+                }
+            }
+
+            Debug.log("not inlining %s because no types/probabilities were recorded", methodName(targetMethod, invoke));
+            return null;
+        } else {
+            Debug.log("not inlining %s because no type profile exists", methodName(targetMethod, invoke));
+            return null;
+        }
+    }
+
+    private static CheckCastNode createAnchoredReceiver(StructuredGraph graph, GraalRuntime runtime, FixedNode anchor, RiResolvedType commonType, ValueNode receiver) {
+        // to avoid that floating reads on receiver fields float above the type check
+        ConstantNode typeConst = graph.unique(ConstantNode.forCiConstant(commonType.getEncoding(Representation.ObjectHub), runtime, graph));
+        CheckCastNode checkCast = graph.unique(new CheckCastNode(anchor, typeConst, commonType, receiver, false));
+        return checkCast;
+    }
+
+    private static void convertTypeToBranchProbabilities(double[] typeProbabilities, double notRecordedTypeProbability) {
+        // avoid branches with 0.0/1.0 probability
+        double total = Math.max(1E-10, notRecordedTypeProbability);
+
+        for (int i = typeProbabilities.length - 1; i >= 0; i--) {
+            total += typeProbabilities[i];
+            typeProbabilities[i] = typeProbabilities[i] / total;
+        }
+        assert total > 0.99 && total < 1.01;
+    }
+
+    private static boolean checkInvokeConditions(Invoke invoke) {
+        if (invoke.stateAfter() == null) {
+            Debug.log("not inlining %s because the invoke has no after state", methodName(invoke.callTarget().targetMethod(), invoke));
+            return false;
+        }
+        if (invoke.predecessor() == null) {
+            Debug.log("not inlining %s because the invoke is dead code", methodName(invoke.callTarget().targetMethod(), invoke));
+            return false;
+        }
+        if (!invoke.useForInlining()) {
+            Debug.log("not inlining %s because invoke is marked to be not used for inlining", methodName(invoke.callTarget().targetMethod(), invoke));
+            return false;
+        }
+        return true;
+    }
+
+    private static boolean checkTargetConditions(Invoke invoke, RiMethod method) {
+        if (method == null) {
+            Debug.log("not inlining because method is not resolved");
+            return false;
+        }
+        if (!(method instanceof RiResolvedMethod)) {
+            Debug.log("not inlining %s because it is unresolved", method.toString());
+            return false;
+        }
+        RiResolvedMethod resolvedMethod = (RiResolvedMethod) method;
+        if (Modifier.isNative(resolvedMethod.accessFlags())) {
+            Debug.log("not inlining %s because it is a native method", methodName(resolvedMethod));
+            return false;
+        }
+        if (Modifier.isAbstract(resolvedMethod.accessFlags())) {
+            Debug.log("not inlining %s because it is an abstract method", methodName(resolvedMethod));
+            return false;
+        }
+        if (!resolvedMethod.holder().isInitialized()) {
+            Debug.log("not inlining %s because of non-initialized class", methodName(resolvedMethod));
+            return false;
+        }
+        if (!resolvedMethod.canBeInlined()) {
+            Debug.log("not inlining %s because it is marked non-inlinable", methodName(resolvedMethod));
+            return false;
+        }
+        if (computeRecursiveInliningLevel(invoke.stateAfter(), (RiResolvedMethod) method) > GraalOptions.MaximumRecursiveInlining) {
+            Debug.log("not inlining %s because it exceeds the maximum recursive inlining depth", methodName(resolvedMethod));
+            return false;
+        }
+
+        return true;
+    }
+
+    private static int computeRecursiveInliningLevel(FrameState state, RiResolvedMethod method) {
+        assert state != null;
+
+        int count = 0;
+        FrameState curState = state;
+        while (curState != null) {
+            if (curState.method() == method) {
+                count++;
+            }
+            curState = curState.outerFrameState();
+        }
+        return count;
+    }
+
+    /**
+     * Performs an actual inlining, thereby replacing the given invoke with the given inlineGraph.
+     * @param invoke the invoke that will be replaced
+     * @param inlineGraph the graph that the invoke will be replaced with
+     * @param receiverNullCheck true if a null check needs to be generated for non-static inlinings, false if no such check is required
+     * @return The node that represents the return value, or null for void methods and methods that have no non-exceptional exit.
+     */
+    public static void inline(Invoke invoke, StructuredGraph inlineGraph, boolean receiverNullCheck) {
+        NodeInputList<ValueNode> parameters = invoke.callTarget().arguments();
+        StructuredGraph graph = (StructuredGraph) invoke.node().graph();
+
+        FrameState stateAfter = invoke.stateAfter();
+        assert stateAfter.isAlive();
+
+        IdentityHashMap<Node, Node> replacements = new IdentityHashMap<>();
+        ArrayList<Node> nodes = new ArrayList<>();
+        ReturnNode returnNode = null;
+        UnwindNode unwindNode = null;
+        BeginNode entryPointNode = inlineGraph.start();
+        FixedNode firstCFGNode = entryPointNode.next();
+        for (Node node : inlineGraph.getNodes()) {
+            if (node == entryPointNode || node == entryPointNode.stateAfter()) {
+                // Do nothing.
+            } else if (node instanceof LocalNode) {
+                replacements.put(node, parameters.get(((LocalNode) node).index()));
+            } else {
+                nodes.add(node);
+                if (node instanceof ReturnNode) {
+                    returnNode = (ReturnNode) node;
+                } else if (node instanceof UnwindNode) {
+                    unwindNode = (UnwindNode) node;
+                }
+            }
+        }
+
+        assert invoke.node().successors().first() != null : invoke;
+        assert invoke.node().predecessor() != null;
+
+        Map<Node, Node> duplicates = graph.addDuplicates(nodes, replacements);
+        FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode);
+        if (receiverNullCheck) {
+            receiverNullCheck(invoke);
+        }
+        invoke.node().replaceAtPredecessors(firstCFGNodeDuplicate);
+
+        FrameState stateAtExceptionEdge = null;
+        if (invoke instanceof InvokeWithExceptionNode) {
+            InvokeWithExceptionNode invokeWithException = ((InvokeWithExceptionNode) invoke);
+            if (unwindNode != null) {
+                assert unwindNode.predecessor() != null;
+                assert invokeWithException.exceptionEdge().successors().count() == 1;
+                ExceptionObjectNode obj = (ExceptionObjectNode) invokeWithException.exceptionEdge().next();
+                stateAtExceptionEdge = obj.stateAfter();
+                UnwindNode unwindDuplicate = (UnwindNode) duplicates.get(unwindNode);
+                obj.replaceAtUsages(unwindDuplicate.exception());
+                unwindDuplicate.clearInputs();
+                Node n = obj.next();
+                obj.setNext(null);
+                unwindDuplicate.replaceAndDelete(n);
+            } else {
+                invokeWithException.killExceptionEdge();
+            }
+        } else {
+            if (unwindNode != null) {
+                UnwindNode unwindDuplicate = (UnwindNode) duplicates.get(unwindNode);
+                DeoptimizeNode deoptimizeNode = new DeoptimizeNode(DeoptAction.InvalidateRecompile);
+                unwindDuplicate.replaceAndDelete(graph.add(deoptimizeNode));
+                // move the deopt upwards if there is a monitor exit that tries to use the "after exception" frame state
+                // (because there is no "after exception" frame state!)
+                if (deoptimizeNode.predecessor() instanceof MonitorExitNode) {
+                    MonitorExitNode monitorExit = (MonitorExitNode) deoptimizeNode.predecessor();
+                    if (monitorExit.stateAfter() != null && monitorExit.stateAfter().bci == FrameState.AFTER_EXCEPTION_BCI) {
+                        FrameState monitorFrameState = monitorExit.stateAfter();
+                        graph.removeFixed(monitorExit);
+                        monitorFrameState.safeDelete();
+                    }
+                }
+            }
+        }
+
+        FrameState outerFrameState = null;
+        double invokeProbability = invoke.node().probability();
+        for (Node node : duplicates.values()) {
+            if (GraalOptions.ProbabilityAnalysis) {
+                if (node instanceof FixedNode) {
+                    FixedNode fixed = (FixedNode) node;
+                    double newProbability = fixed.probability() * invokeProbability;
+                    if (GraalOptions.LimitInlinedProbability) {
+                        newProbability = Math.min(newProbability, invokeProbability);
+                    }
+                    fixed.setProbability(newProbability);
+                }
+            }
+            if (node instanceof FrameState) {
+                FrameState frameState = (FrameState) node;
+                assert frameState.bci != FrameState.BEFORE_BCI;
+                if (frameState.bci == FrameState.AFTER_BCI) {
+                    frameState.replaceAndDelete(stateAfter);
+                } else if (frameState.bci == FrameState.AFTER_EXCEPTION_BCI) {
+                    if (frameState.isAlive()) {
+                        assert stateAtExceptionEdge != null;
+                        frameState.replaceAndDelete(stateAtExceptionEdge);
+                    } else {
+                        assert stateAtExceptionEdge == null;
+                    }
+                } else {
+                    if (outerFrameState == null) {
+                        outerFrameState = stateAfter.duplicateModified(invoke.bci(), stateAfter.rethrowException(), invoke.node().kind());
+                        outerFrameState.setDuringCall(true);
+                    }
+                    frameState.setOuterFrameState(outerFrameState);
+                }
+            }
+        }
+
+        Node returnValue = null;
+        if (returnNode != null) {
+            if (returnNode.result() instanceof LocalNode) {
+                returnValue = replacements.get(returnNode.result());
+            } else {
+                returnValue = duplicates.get(returnNode.result());
+            }
+            invoke.node().replaceAtUsages(returnValue);
+            Node returnDuplicate = duplicates.get(returnNode);
+            returnDuplicate.clearInputs();
+            Node n = invoke.next();
+            invoke.setNext(null);
+            if (n instanceof BeginNode) {
+                BeginNode begin = (BeginNode) n;
+                FixedNode next = begin.next();
+                begin.setNext(null);
+                returnDuplicate.replaceAndDelete(next);
+                begin.safeDelete();
+            } else {
+                returnDuplicate.replaceAndDelete(n);
+            }
+        }
+
+        invoke.node().clearInputs();
+        invoke.node().replaceAtUsages(null);
+        GraphUtil.killCFG(invoke.node());
+
+        if (stateAfter.usages().isEmpty()) {
+            stateAfter.safeDelete();
+        }
+    }
+
+    public static void receiverNullCheck(Invoke invoke) {
+        MethodCallTargetNode callTarget = invoke.callTarget();
+        StructuredGraph graph = (StructuredGraph) invoke.graph();
+        NodeInputList<ValueNode> parameters = callTarget.arguments();
+        ValueNode firstParam = parameters.size() <= 0 ? null : parameters.get(0);
+        if (!callTarget.isStatic() && firstParam.kind() == CiKind.Object && !firstParam.stamp().nonNull()) {
+            graph.addBeforeFixed(invoke.node(), graph.add(new FixedGuardNode(graph.unique(new NullCheckNode(firstParam, false)))));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/IntList.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2010, 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.max.graal.compiler.util;
+
+import java.util.*;
+
+/**
+ * An expandable and indexable list of {@code int}s.
+ *
+ * This class avoids the boxing/unboxing incurred by {@code ArrayList<Integer>}.
+ */
+public final class IntList {
+
+    private int[] array;
+    private int size;
+
+    /**
+     * Creates an int list with a specified initial capacity.
+     *
+     * @param initialCapacity
+     */
+    public IntList(int initialCapacity) {
+        array = new int[initialCapacity];
+    }
+
+    /**
+     * Creates an int list with a specified initial array.
+     *
+     * @param array the initial array used for the list (no copy is made)
+     * @param initialSize the initial {@linkplain #size() size} of the list (must be less than or equal to {@code array.length}
+     */
+    public IntList(int[] array, int initialSize) {
+        assert initialSize <= array.length;
+        this.array = array;
+        this.size = initialSize;
+    }
+
+    /**
+     * Makes a new int list by copying a range from a given int list.
+     *
+     * @param other the list from which a range of values is to be copied into the new list
+     * @param startIndex the index in {@code other} at which to start copying
+     * @param length the number of values to copy from {@code other}
+     * @return a new int list whose {@linkplain #size() size} and capacity is {@code length}
+     */
+    public static IntList copy(IntList other, int startIndex, int length) {
+        return copy(other, startIndex, length, length);
+    }
+
+    /**
+     * Makes a new int list by copying a range from a given int list.
+     *
+     * @param other the list from which a range of values is to be copied into the new list
+     * @param startIndex the index in {@code other} at which to start copying
+     * @param length the number of values to copy from {@code other}
+     * @param initialCapacity the initial capacity of the new int list (must be greater or equal to {@code length})
+     * @return a new int list whose {@linkplain #size() size} is {@code length}
+     */
+    public static IntList copy(IntList other, int startIndex, int length, int initialCapacity) {
+        assert initialCapacity >= length : "initialCapacity < length";
+        int[] array = new int[initialCapacity];
+        System.arraycopy(other.array, startIndex, array, 0, length);
+        return new IntList(array, length);
+    }
+
+    public int size() {
+        return size;
+    }
+
+    /**
+     * Appends a value to the end of this list, increasing its {@linkplain #size() size} by 1.
+     *
+     * @param value the value to append
+     */
+    public void add(int value) {
+        if (size == array.length) {
+            int newSize = (size * 3) / 2 + 1;
+            array = Arrays.copyOf(array, newSize);
+        }
+        array[size++] = value;
+    }
+
+    /**
+     * Gets the value in this list at a given index.
+     *
+     * @param index the index of the element to return
+     * @throws IndexOutOfBoundsException if {@code index < 0 || index >= size()}
+     */
+    public int get(int index) {
+        if (index >= size) {
+            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
+        }
+        return array[index];
+    }
+
+    /**
+     * Sets the size of this list to 0.
+     */
+    public void clear() {
+        size = 0;
+    }
+
+    /**
+     * Sets a value at a given index in this list.
+     *
+     * @param index the index of the element to update
+     * @param value the new value of the element
+     * @throws IndexOutOfBoundsException if {@code index < 0 || index >= size()}
+     */
+    public void set(int index, int value) {
+        if (index >= size) {
+            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
+        }
+        array[index] = value;
+    }
+
+    /**
+     * Adjusts the {@linkplain #size() size} of this int list.
+     *
+     * If {@code newSize < size()}, the size is changed to {@code newSize}.
+     * If {@code newSize > size()}, sufficient 0 elements are {@linkplain #add(int) added}
+     * until {@code size() == newSize}.
+     *
+     * @param newSize the new size of this int list
+     */
+    public void setSize(int newSize) {
+        if (newSize < size) {
+            size = newSize;
+        } else if (newSize > size) {
+            array = Arrays.copyOf(array, newSize);
+        }
+    }
+
+    @Override
+    public String toString() {
+        if (array.length == size) {
+            return Arrays.toString(array);
+        }
+        return Arrays.toString(Arrays.copyOf(array, size));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.compiler.util;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.calc.*;
+
+/**
+ * The {@code Util} class contains a motley collection of utility methods used throughout the compiler.
+ */
+public class Util {
+
+    public static final int PRINTING_LINE_WIDTH = 40;
+    public static final char SECTION_CHARACTER = '*';
+    public static final char SUB_SECTION_CHARACTER = '=';
+    public static final char SEPERATOR_CHARACTER = '-';
+
+    public static <T> boolean replaceInList(T a, T b, List<T> list) {
+        final int max = list.size();
+        for (int i = 0; i < max; i++) {
+            if (list.get(i) == a) {
+                list.set(i, b);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static <T> boolean replaceAllInList(T a, T b, List<T> list) {
+        final int max = list.size();
+        for (int i = 0; i < max; i++) {
+            if (list.get(i) == a) {
+                list.set(i, b);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Statically cast an object to an arbitrary Object type. Dynamically checked.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T uncheckedCast(@SuppressWarnings("unused") Class<T> type, Object object) {
+        return (T) object;
+    }
+
+    /**
+     * Statically cast an object to an arbitrary Object type. Dynamically checked.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T uncheckedCast(Object object) {
+        return (T) object;
+    }
+
+    /**
+     * Utility method to combine a base hash with the identity hash of one or more objects.
+     *
+     * @param hash the base hash
+     * @param x the object to add to the hash
+     * @return the combined hash
+     */
+    public static int hash1(int hash, Object x) {
+        // always set at least one bit in case the hash wraps to zero
+        return 0x10000000 | (hash + 7 * System.identityHashCode(x));
+    }
+
+    /**
+     * Utility method to combine a base hash with the identity hash of one or more objects.
+     *
+     * @param hash the base hash
+     * @param x the first object to add to the hash
+     * @param y the second object to add to the hash
+     * @return the combined hash
+     */
+    public static int hash2(int hash, Object x, Object y) {
+        // always set at least one bit in case the hash wraps to zero
+        return 0x20000000 | (hash + 7 * System.identityHashCode(x) + 11 * System.identityHashCode(y));
+    }
+
+    /**
+     * Utility method to combine a base hash with the identity hash of one or more objects.
+     *
+     * @param hash the base hash
+     * @param x the first object to add to the hash
+     * @param y the second object to add to the hash
+     * @param z the third object to add to the hash
+     * @return the combined hash
+     */
+    public static int hash3(int hash, Object x, Object y, Object z) {
+        // always set at least one bit in case the hash wraps to zero
+        return 0x30000000 | (hash + 7 * System.identityHashCode(x) + 11 * System.identityHashCode(y) + 13 * System.identityHashCode(z));
+    }
+
+    /**
+     * Utility method to combine a base hash with the identity hash of one or more objects.
+     *
+     * @param hash the base hash
+     * @param x the first object to add to the hash
+     * @param y the second object to add to the hash
+     * @param z the third object to add to the hash
+     * @param w the fourth object to add to the hash
+     * @return the combined hash
+     */
+    public static int hash4(int hash, Object x, Object y, Object z, Object w) {
+        // always set at least one bit in case the hash wraps to zero
+        return 0x40000000 | (hash + 7 * System.identityHashCode(x) + 11 * System.identityHashCode(y) + 13 * System.identityHashCode(z) + 17 * System.identityHashCode(w));
+    }
+
+    static {
+        assert CiUtil.log2(2) == 1;
+        assert CiUtil.log2(4) == 2;
+        assert CiUtil.log2(8) == 3;
+        assert CiUtil.log2(16) == 4;
+        assert CiUtil.log2(32) == 5;
+        assert CiUtil.log2(0x40000000) == 30;
+
+        assert CiUtil.log2(2L) == 1;
+        assert CiUtil.log2(4L) == 2;
+        assert CiUtil.log2(8L) == 3;
+        assert CiUtil.log2(16L) == 4;
+        assert CiUtil.log2(32L) == 5;
+        assert CiUtil.log2(0x4000000000000000L) == 62;
+
+        assert !CiUtil.isPowerOf2(3);
+        assert !CiUtil.isPowerOf2(5);
+        assert !CiUtil.isPowerOf2(7);
+        assert !CiUtil.isPowerOf2(-1);
+
+        assert CiUtil.isPowerOf2(2);
+        assert CiUtil.isPowerOf2(4);
+        assert CiUtil.isPowerOf2(8);
+        assert CiUtil.isPowerOf2(16);
+        assert CiUtil.isPowerOf2(32);
+        assert CiUtil.isPowerOf2(64);
+    }
+
+    /**
+     * Sets the element at a given position of a list and ensures that this position exists. If the list is current
+     * shorter than the position, intermediate positions are filled with a given value.
+     *
+     * @param list the list to put the element into
+     * @param pos the position at which to insert the element
+     * @param x the element that should be inserted
+     * @param filler the filler element that is used for the intermediate positions in case the list is shorter than pos
+     */
+    public static <T> void atPutGrow(List<T> list, int pos, T x, T filler) {
+        if (list.size() < pos + 1) {
+            while (list.size() < pos + 1) {
+                list.add(filler);
+            }
+            assert list.size() == pos + 1;
+        }
+
+        assert list.size() >= pos + 1;
+        list.set(pos, x);
+    }
+
+    public static void breakpoint() {
+        // do nothing.
+    }
+
+    public static void guarantee(boolean b, String string) {
+        if (!b) {
+            throw new CiBailout(string);
+        }
+    }
+
+    public static void warning(String string) {
+        TTY.println("WARNING: " + string);
+    }
+
+    public static int safeToInt(long l) {
+        assert (int) l == l;
+        return (int) l;
+    }
+
+    public static int roundUp(int number, int mod) {
+        return ((number + mod - 1) / mod) * mod;
+    }
+
+    public static void truncate(List<?> list, int length) {
+        while (list.size() > length) {
+            list.remove(list.size() - 1);
+        }
+    }
+
+    public static void printSection(String name, char sectionCharacter) {
+
+        String header = " " + name + " ";
+        int remainingCharacters = PRINTING_LINE_WIDTH - header.length();
+        int leftPart = remainingCharacters / 2;
+        int rightPart = remainingCharacters - leftPart;
+        for (int i = 0; i < leftPart; i++) {
+            TTY.print(sectionCharacter);
+        }
+
+        TTY.print(header);
+
+        for (int i = 0; i < rightPart; i++) {
+            TTY.print(sectionCharacter);
+        }
+
+        TTY.println();
+    }
+
+    /**
+     * Prints entries in a byte array as space separated hex values to {@link TTY}.
+     *
+     * @param address an address at which the bytes are located. This is used to print an address prefix per line of output.
+     * @param array the array containing all the bytes to print
+     * @param bytesPerLine the number of values to print per line of output
+     */
+    public static void printBytes(long address, byte[] array, int bytesPerLine) {
+        printBytes(address, array, 0, array.length, bytesPerLine);
+    }
+
+    /**
+     * Prints entries in a byte array as space separated hex values to {@link TTY}.
+     *
+     * @param address an address at which the bytes are located. This is used to print an address prefix per line of output.
+     * @param array the array containing the bytes to print
+     * @param offset the offset in {@code array} of the values to print
+     * @param length the number of values from {@code array} print
+     * @param bytesPerLine the number of values to print per line of output
+     */
+    public static void printBytes(long address, byte[] array, int offset, int length, int bytesPerLine) {
+        assert bytesPerLine > 0;
+        boolean newLine = true;
+        for (int i = 0; i < length; i++) {
+            if (newLine) {
+                TTY.print("%08x: ", address + i);
+                newLine = false;
+            }
+            TTY.print("%02x ", array[i]);
+            if (i % bytesPerLine == bytesPerLine - 1) {
+                TTY.println();
+                newLine = true;
+            }
+        }
+
+        if (length % bytesPerLine != bytesPerLine) {
+            TTY.println();
+        }
+    }
+
+    public static boolean isShiftCount(int x) {
+        return 0 <= x && x < 32;
+    }
+
+    /**
+     * Determines if a given {@code int} value is the range of unsigned byte values.
+     */
+    public static boolean isUByte(int x) {
+        return (x & 0xff) == x;
+    }
+
+    /**
+     * Determines if a given {@code int} value is the range of signed byte values.
+     */
+    public static boolean isByte(int x) {
+        return (byte) x == x;
+    }
+
+    /**
+     * Determines if a given {@code long} value is the range of unsigned byte values.
+     */
+    public static boolean isUByte(long x) {
+        return (x & 0xffL) == x;
+    }
+
+    /**
+     * Determines if a given {@code long} value is the range of signed byte values.
+     */
+    public static boolean isByte(long l) {
+        return (byte) l == l;
+    }
+
+    /**
+     * Determines if a given {@code long} value is the range of unsigned int values.
+     */
+    public static boolean isUInt(long x) {
+        return (x & 0xffffffffL) == x;
+    }
+
+    /**
+     * Determines if a given {@code long} value is the range of signed int values.
+     */
+    public static boolean isInt(long l) {
+        return (int) l == l;
+    }
+    /**
+     * Determines if a given {@code int} value is the range of signed short values.
+     */
+    public static boolean isShort(int x) {
+        return (short) x == x;
+    }
+
+    public static boolean is32bit(long x) {
+        return -0x80000000L <= x && x < 0x80000000L;
+    }
+
+    public static short safeToShort(int v) {
+        assert isShort(v);
+        return (short) v;
+    }
+
+    /**
+     * Checks that two instructions are equivalent, optionally comparing constants.
+     * @param x the first instruction
+     * @param y the second instruction
+     * @param compareConstants {@code true} if equivalent constants should be considered equivalent
+     * @return {@code true} if the instructions are equivalent; {@code false} otherwise
+     */
+    public static boolean equivalent(FixedWithNextNode x, FixedWithNextNode y, boolean compareConstants) {
+        if (x == y) {
+            return true;
+        }
+        if (compareConstants && x != null && y != null) {
+            if (x.isConstant() && x.asConstant().equivalent(y.asConstant())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static boolean isFixed(Node n) {
+        return n instanceof FixedNode;
+    }
+
+    public static boolean isFloating(Node n) {
+        return n instanceof FloatingNode;
+    }
+
+    public static boolean isFinalClass(RiResolvedType type) {
+        return Modifier.isFinal(type.accessFlags()) || (type.isArrayClass() && Modifier.isFinal(type.componentType().accessFlags()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/Debug.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,217 @@
+/*
+ * 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.max.graal.debug;
+
+import com.oracle.max.graal.debug.internal.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+public class Debug {
+
+    private static boolean ENABLED = false;
+
+    public static void enable() {
+        ENABLED = true;
+        DebugScope.initialize();
+    }
+
+    public static boolean isEnabled() {
+        return ENABLED;
+    }
+
+    public static boolean isDumpEnabled() {
+        return ENABLED && DebugScope.getInstance().isDumpEnabled();
+    }
+
+    public static boolean isMeterEnabled() {
+        return ENABLED && DebugScope.getInstance().isMeterEnabled();
+    }
+
+    public static boolean isTimeEnabled() {
+        return ENABLED && DebugScope.getInstance().isTimeEnabled();
+    }
+
+    public static boolean isLogEnabled() {
+        return ENABLED && DebugScope.getInstance().isLogEnabled();
+    }
+
+    public static void sandbox(String name, Runnable runnable) {
+        if (ENABLED) {
+            DebugScope.getInstance().scope(name, runnable, null, true, new Object[0]);
+        } else {
+            runnable.run();
+        }
+    }
+
+    public static void scope(String name, Runnable runnable) {
+        scope(name, null, runnable);
+    }
+
+    public static <T> T scope(String name, Callable<T> callable) {
+        return scope(name, null, callable);
+    }
+
+    public static void scope(String name, Object context, Runnable runnable) {
+        if (ENABLED) {
+            DebugScope.getInstance().scope(name, runnable, null, false, new Object[] {context});
+        } else {
+            runnable.run();
+        }
+    }
+
+    public static String currentScope() {
+        if (ENABLED) {
+            return DebugScope.getInstance().getQualifiedName();
+        } else {
+            return "";
+        }
+    }
+
+    public static <T> T scope(String name, Object context, Callable<T> callable) {
+        if (ENABLED) {
+            return DebugScope.getInstance().scope(name, null, callable, false, new Object[] {context});
+        } else {
+            return DebugScope.call(callable);
+        }
+    }
+
+    public static void log(String msg, Object... args) {
+        if (ENABLED && DebugScope.getInstance().isLogEnabled()) {
+            DebugScope.getInstance().log(msg, args);
+        }
+    }
+
+    public static void dump(Object object, String msg, Object... args) {
+        if (ENABLED && DebugScope.getInstance().isDumpEnabled()) {
+            DebugScope.getInstance().dump(object, msg, args);
+        }
+    }
+
+    public static Iterable<Object> context() {
+        if (ENABLED) {
+            return DebugScope.getInstance().getCurrentContext();
+        } else {
+            return Collections.emptyList();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> List<T> contextSnapshot(Class<T> clazz) {
+        if (ENABLED) {
+            List<T> result = new ArrayList<>();
+            for (Object o : context()) {
+                if (clazz.isInstance(o)) {
+                    result.add((T) o);
+                }
+            }
+            return result;
+        } else {
+            return Collections.emptyList();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> T contextLookup(Class<T> clazz) {
+        if (ENABLED) {
+            for (Object o : context()) {
+                if (clazz.isInstance(o)) {
+                    return ((T) o);
+                }
+            }
+        }
+        return null;
+    }
+
+    public static DebugMetric metric(String name) {
+        if (ENABLED) {
+            return new MetricImpl(name);
+        } else {
+            return VOID_METRIC;
+        }
+    }
+
+    public static void setConfig(DebugConfig config) {
+        if (ENABLED) {
+            DebugScope.getInstance().setConfig(config);
+        }
+    }
+
+    public static DebugConfig fixedConfig(final boolean isLogEnabled, final boolean isDumpEnabled, final boolean isMeterEnabled, final boolean isTimerEnabled, final Collection<? extends DebugDumpHandler> dumpHandlers) {
+        return new DebugConfig() {
+
+            @Override
+            public boolean isLogEnabled() {
+                return isLogEnabled;
+            }
+
+            @Override
+            public boolean isMeterEnabled() {
+                return isMeterEnabled;
+            }
+
+            @Override
+            public boolean isDumpEnabled() {
+                return isDumpEnabled;
+            }
+
+            @Override
+            public boolean isTimeEnabled() {
+                return isTimerEnabled;
+            }
+
+            @Override
+            public RuntimeException interceptException(Throwable e) {
+                return null;
+            }
+
+            @Override
+            public Collection< ? extends DebugDumpHandler> dumpHandlers() {
+                return dumpHandlers;
+            }
+        };
+    }
+
+    private static final DebugMetric VOID_METRIC = new DebugMetric() {
+
+        public void increment() {
+        }
+
+        public void add(int value) {
+        }
+    };
+
+    public static DebugTimer timer(String name) {
+        if (ENABLED) {
+            return new TimerImpl(name);
+        } else {
+            return VOID_TIMER;
+        }
+    }
+
+    private static final DebugTimer VOID_TIMER = new DebugTimer() {
+
+        public TimerCloseable start() {
+            return TimerImpl.VOID_CLOSEABLE;
+        }
+    };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/DebugConfig.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,35 @@
+/*
+ * 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.max.graal.debug;
+
+import java.util.*;
+
+
+public interface DebugConfig {
+    boolean isLogEnabled();
+    boolean isMeterEnabled();
+    boolean isDumpEnabled();
+    boolean isTimeEnabled();
+    RuntimeException interceptException(Throwable e);
+    Collection<? extends DebugDumpHandler> dumpHandlers();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/DebugDumpHandler.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,27 @@
+/*
+ * 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.max.graal.debug;
+
+public interface DebugDumpHandler {
+    void dump(Object object, String message);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/DebugDumpScope.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,41 @@
+/*
+ * 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.max.graal.debug;
+
+public final class DebugDumpScope {
+
+    private final String name;
+
+    public DebugDumpScope(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return "DebugDumpScope[" + name + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/DebugMetric.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,28 @@
+/*
+ * 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.max.graal.debug;
+
+public interface DebugMetric {
+    void increment();
+    void add(int value);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/DebugTimer.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,29 @@
+/*
+ * 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.max.graal.debug;
+
+import com.oracle.max.graal.debug.internal.*;
+
+public interface DebugTimer {
+    TimerCloseable start();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/DebugScope.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,295 @@
+/*
+ * 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.max.graal.debug.internal;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import com.oracle.max.graal.debug.*;
+
+public final class DebugScope {
+
+    private static ThreadLocal<DebugScope> instanceTL = new ThreadLocal<>();
+    private static ThreadLocal<DebugConfig> configTL = new ThreadLocal<>();
+    private static ThreadLocal<Throwable> lastExceptionThrownTL = new ThreadLocal<>();
+    private static DebugTimer scopeTime = Debug.timer("ScopeTime");
+    private static DebugMetric scopeCount = Debug.metric("ScopeCount");
+
+    private final DebugScope parent;
+
+    private Object[] context;
+
+    private List<DebugScope> children;
+    private DebugValueMap valueMap;
+    private String qualifiedName;
+    private String name;
+
+    private static final char SCOPE_SEP = '.';
+
+    private boolean logEnabled;
+    private boolean meterEnabled;
+    private boolean timeEnabled;
+    private boolean dumpEnabled;
+
+    public static DebugScope getInstance() {
+        DebugScope result = instanceTL.get();
+        if (result == null) {
+            DebugScope topLevelDebugScope = new DebugScope(Thread.currentThread().getName(), "", null);
+            instanceTL.set(topLevelDebugScope);
+            DebugValueMap.registerTopLevel(topLevelDebugScope.getValueMap());
+            return topLevelDebugScope;
+        } else {
+            return result;
+        }
+    }
+
+    public static DebugConfig getConfig() {
+        return configTL.get();
+    }
+
+    private DebugScope(String name, String qualifiedName, DebugScope parent, Object... context) {
+        this.name = name;
+        this.parent = parent;
+        this.context = context;
+        this.qualifiedName = qualifiedName;
+        assert context != null;
+    }
+
+    public boolean isDumpEnabled() {
+        return dumpEnabled;
+    }
+
+    public boolean isLogEnabled() {
+        return logEnabled;
+    }
+
+    public boolean isMeterEnabled() {
+        return meterEnabled;
+    }
+
+    public boolean isTimeEnabled() {
+        return timeEnabled;
+    }
+
+    public void log(String msg, Object... args) {
+        if (isLogEnabled()) {
+            cachedOut.println(String.format(msg, args));
+        }
+    }
+
+    public void dump(Object object, String formatString, Object[] args) {
+        if (isDumpEnabled()) {
+            DebugConfig config = getConfig();
+            if (config != null) {
+                String message = String.format(formatString, args);
+                for (DebugDumpHandler dumpHandler : config.dumpHandlers()) {
+                    dumpHandler.dump(object, message);
+                }
+            }
+        }
+    }
+
+    public <T> T scope(String newName, Runnable runnable, Callable<T> callable, boolean sandbox, Object[] newContext) {
+        DebugScope oldContext = getInstance();
+        DebugConfig oldConfig = getConfig();
+        DebugScope newChild = null;
+        if (sandbox) {
+            newChild = new DebugScope(newName, newName, null, newContext);
+            setConfig(null);
+        } else {
+            newChild = oldContext.createChild(newName, newContext);
+        }
+        instanceTL.set(newChild);
+        newChild.updateFlags();
+        scopeCount.increment();
+        try (TimerCloseable a = scopeTime.start()) {
+            return executeScope(runnable, callable);
+        } finally {
+            if (!sandbox && newChild.hasValueMap()) {
+                getValueMap().addChild(newChild.getValueMap());
+            }
+            newChild.context = null;
+            instanceTL.set(oldContext);
+            setConfig(oldConfig);
+        }
+    }
+
+    private <T> T executeScope(Runnable runnable, Callable<T> callable) {
+        try {
+            if (runnable != null) {
+                runnable.run();
+            }
+            if (callable != null) {
+                return call(callable);
+            }
+        } catch (Throwable e) {
+            if (e == lastExceptionThrownTL.get()) {
+                throw e;
+            } else {
+                RuntimeException newException = interceptException(e);
+                if (newException == null) {
+                    lastExceptionThrownTL.set(e);
+                    throw e;
+                } else {
+                    lastExceptionThrownTL.set(newException);
+                    throw newException;
+                }
+            }
+        }
+        return null;
+    }
+
+    private void updateFlags() {
+        DebugConfig config = getConfig();
+        if (config == null) {
+            logEnabled = false;
+            meterEnabled = false;
+            timeEnabled = false;
+            dumpEnabled = false;
+        } else {
+            logEnabled = config.isLogEnabled();
+            meterEnabled = config.isMeterEnabled();
+            timeEnabled = config.isTimeEnabled();
+            dumpEnabled = config.isDumpEnabled();
+        }
+    }
+
+    private RuntimeException interceptException(final Throwable e) {
+        final DebugConfig config = getConfig();
+        if (config != null) {
+            return scope("InterceptException", null, new Callable<RuntimeException>() {
+
+                @Override
+                public RuntimeException call() throws Exception {
+                    try {
+                        return config.interceptException(e);
+                    } catch (Throwable t) {
+                        return new RuntimeException("Exception while intercepting exception", t);
+                    }
+                }
+            }, false, new Object[] {e});
+        }
+        return null;
+    }
+
+    private DebugValueMap getValueMap() {
+        if (valueMap == null) {
+            valueMap = new DebugValueMap(name);
+        }
+        return valueMap;
+    }
+
+    private boolean hasValueMap() {
+        return valueMap != null;
+    }
+
+    long getCurrentValue(int index) {
+        return getValueMap().getCurrentValue(index);
+    }
+
+    void setCurrentValue(int index, long l) {
+        getValueMap().setCurrentValue(index, l);
+    }
+
+    private DebugScope createChild(String newName, Object[] newContext) {
+        String newQualifiedName = newName;
+        if (this.qualifiedName.length() > 0) {
+            newQualifiedName = this.qualifiedName + SCOPE_SEP + newName;
+        }
+        DebugScope result = new DebugScope(newName, newQualifiedName, this, newContext);
+        if (children == null) {
+            children = new ArrayList<>(4);
+        }
+        children.add(result);
+        return result;
+    }
+
+    public Iterable<Object> getCurrentContext() {
+        return new Iterable<Object>() {
+
+            @Override
+            public Iterator<Object> iterator() {
+                return new Iterator<Object>() {
+
+                    DebugScope currentScope = DebugScope.this;
+                    int objectIndex;
+
+                    @Override
+                    public boolean hasNext() {
+                        selectScope();
+                        return currentScope != null;
+                    }
+
+                    private void selectScope() {
+                        while (currentScope != null && currentScope.context.length <= objectIndex) {
+                            currentScope = currentScope.parent;
+                            objectIndex = 0;
+                        }
+                    }
+
+                    @Override
+                    public Object next() {
+                        selectScope();
+                        if (currentScope != null) {
+                            return currentScope.context[objectIndex++];
+                        }
+                        throw new IllegalStateException("May only be called if there is a next element.");
+                    }
+
+                    @Override
+                    public void remove() {
+                        throw new UnsupportedOperationException("This iterator is read only.");
+                    }
+                };
+            }
+        };
+    }
+
+    public static <T> T call(Callable<T> callable) {
+        try {
+            return callable.call();
+        } catch (Exception e) {
+            if (e instanceof RuntimeException) {
+                throw (RuntimeException) e;
+            } else {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public void setConfig(DebugConfig newConfig) {
+        configTL.set(newConfig);
+        updateFlags();
+    }
+
+    public String getQualifiedName() {
+        return qualifiedName;
+    }
+
+    public static PrintStream cachedOut;
+
+    public static void initialize() {
+        cachedOut = System.out;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/DebugValue.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,62 @@
+/*
+ * 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.max.graal.debug.internal;
+
+public class DebugValue {
+
+    private String name;
+    private int index;
+
+    protected DebugValue(String name) {
+        this.name = name;
+        this.index = -1;
+    }
+
+    protected long getCurrentValue() {
+        ensureInitialized();
+        return DebugScope.getInstance().getCurrentValue(index);
+    }
+
+    protected void setCurrentValue(long l) {
+        ensureInitialized();
+        DebugScope.getInstance().setCurrentValue(index, l);
+    }
+
+    private void ensureInitialized() {
+        if (index == -1) {
+            index = KeyRegistry.register(name, this);
+        }
+    }
+
+    protected void addToCurrentValue(long timeSpan) {
+        setCurrentValue(getCurrentValue() + timeSpan);
+    }
+
+    public int getIndex() {
+        return index;
+    }
+
+    public String getName() {
+        return name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/DebugValueMap.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,151 @@
+/*
+ * 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.max.graal.debug.internal;
+
+import java.util.*;
+
+public class DebugValueMap {
+
+    private static List<DebugValueMap> topLevelMaps = new ArrayList<>();
+
+    private long[] values;
+    private List<DebugValueMap> children;
+    private String name;
+
+    public DebugValueMap(String name) {
+        this.name = name;
+    }
+
+    public void setCurrentValue(int index, long l) {
+        ensureSize(index);
+        values[index] = l;
+    }
+
+    public long getCurrentValue(int index) {
+        ensureSize(index);
+        return values[index];
+    }
+
+    private void ensureSize(int index) {
+        if (values == null) {
+            values = new long[index + 1];
+        }
+        if (values.length <= index) {
+            values = Arrays.copyOf(values, index + 1);
+        }
+    }
+
+    private int capacity() {
+        return (values == null) ? 0 : values.length;
+    }
+
+    public void addChild(DebugValueMap map) {
+        if (children == null) {
+            children = new ArrayList<>(4);
+        }
+        children.add(map);
+    }
+
+    public List<DebugValueMap> getChildren() {
+        if (children == null) {
+            return Collections.emptyList();
+        } else {
+            return Collections.unmodifiableList(children);
+        }
+    }
+
+    public boolean hasChildren() {
+        return children != null && !children.isEmpty();
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    @Override
+    public String toString() {
+        return "DebugValueMap<" + getName() + ">";
+    }
+
+    public static synchronized void registerTopLevel(DebugValueMap map) {
+        topLevelMaps.add(map);
+    }
+
+    public static synchronized List<DebugValueMap> getTopLevelMaps() {
+        return topLevelMaps;
+    }
+
+    public void normalize() {
+        if (this.hasChildren()) {
+            Map<String, DebugValueMap> occurred = new HashMap<>();
+            for (DebugValueMap map : this.children) {
+                String mapName = map.getName();
+                if (!occurred.containsKey(mapName)) {
+                    occurred.put(mapName, map);
+                    map.normalize();
+                } else {
+                    occurred.get(mapName).mergeWith(map);
+                    occurred.get(mapName).normalize();
+                }
+            }
+
+            if (occurred.values().size() < children.size()) {
+                // At least one duplicate was found.
+                children.clear();
+                for (DebugValueMap map : occurred.values()) {
+                    children.add(map);
+                    map.normalize();
+                }
+            }
+        }
+    }
+
+    private void mergeWith(DebugValueMap map) {
+        if (map.hasChildren()) {
+            if (hasChildren()) {
+                children.addAll(map.children);
+            } else {
+                children = map.children;
+            }
+            map.children = null;
+        }
+
+        int size = Math.max(this.capacity(), map.capacity());
+        ensureSize(size);
+        for (int i = 0; i < size; ++i) {
+            long curValue = getCurrentValue(i);
+            long otherValue = map.getCurrentValue(i);
+            setCurrentValue(i, curValue + otherValue);
+        }
+    }
+
+    public void group() {
+        if (this.hasChildren()) {
+            List<DebugValueMap> oldChildren = new ArrayList<>(this.children);
+            this.children.clear();
+            for (DebugValueMap map : oldChildren) {
+                mergeWith(map);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/KeyRegistry.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * 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.max.graal.debug.internal;
+
+import java.util.*;
+
+public class KeyRegistry {
+    private static int keyCount;
+    private static Map<String, Integer> keyMap = new HashMap<>();
+    private static List<DebugValue> debugValues = new ArrayList<>();
+
+    public static synchronized int register(String name, DebugValue value) {
+        if (!keyMap.containsKey(name)) {
+            keyMap.put(name, keyCount++);
+            debugValues.add(value);
+        }
+        return keyMap.get(name);
+    }
+
+    public static synchronized List<DebugValue> getDebugValues() {
+        return Collections.unmodifiableList(debugValues);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/MetricImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,42 @@
+/*
+ * 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.max.graal.debug.internal;
+
+import com.oracle.max.graal.debug.*;
+
+public final class MetricImpl extends DebugValue implements DebugMetric {
+
+    public MetricImpl(String name) {
+        super(name);
+    }
+
+    public void increment() {
+        add(1);
+    }
+
+    public void add(int value) {
+        if (Debug.isMeterEnabled()) {
+            super.addToCurrentValue(value);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/TimerCloseable.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,27 @@
+/*
+ * 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.max.graal.debug.internal;
+
+public interface TimerCloseable extends AutoCloseable {
+    void close();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/TimerImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * 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.max.graal.debug.internal;
+
+import com.oracle.max.graal.debug.*;
+
+public final class TimerImpl extends DebugValue implements DebugTimer {
+
+    public static final TimerCloseable VOID_CLOSEABLE = new TimerCloseable() {
+        @Override
+        public void close() {
+        }
+    };
+
+    public TimerImpl(String name) {
+        super(name);
+    }
+
+    @Override
+    public TimerCloseable start() {
+        if (Debug.isTimeEnabled()) {
+            final long startTime = System.currentTimeMillis();
+            return new TimerCloseable() {
+                @Override
+                public void close() {
+                    long timeSpan = System.currentTimeMillis() - startTime;
+                    TimerImpl.this.addToCurrentValue(timeSpan);
+                }
+            };
+        } else {
+            return VOID_CLOSEABLE;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/.checkstyle_checks.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
+
+<!--
+    This configuration file was written by the eclipse-cs plugin configuration editor
+-->
+<!--
+    Checkstyle-Configuration: Maxine Checks
+    Description: none
+-->
+<module name="Checker">
+  <property name="severity" value="warning"/>
+  <module name="TreeWalker">
+    <property name="tabWidth" value="4"/>
+    <module name="FileContentsHolder"/>
+    <module name="JavadocStyle">
+      <property name="checkHtml" value="false"/>
+    </module>
+    <module name="LocalFinalVariableName"/>
+    <module name="LocalVariableName"/>
+    <module name="MemberName">
+      <property name="format" value="^(([a-z][a-zA-Z0-9]*$)|(_[A-Z][a-zA-Z0-9]*_[a-z][a-zA-Z0-9]*$))"/>
+    </module>
+    <module name="MethodName">
+      <property name="format" value="^[a-z][a-z_A-Z0-9]*$"/>
+    </module>
+    <module name="PackageName"/>
+    <module name="ParameterName"/>
+    <module name="TypeName">
+      <property name="format" value="^[A-Z][_a-zA-Z0-9]*$"/>
+    </module>
+    <module name="RedundantImport"/>
+    <module name="LineLength">
+      <property name="max" value="250"/>
+    </module>
+    <module name="MethodParamPad"/>
+    <module name="NoWhitespaceAfter">
+      <property name="tokens" value="ARRAY_INIT,BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS"/>
+    </module>
+    <module name="NoWhitespaceBefore">
+      <property name="tokens" value="SEMI,DOT,POST_DEC,POST_INC"/>
+    </module>
+    <module name="ParenPad"/>
+    <module name="TypecastParenPad">
+      <property name="tokens" value="RPAREN,TYPECAST"/>
+    </module>
+    <module name="WhitespaceAfter"/>
+    <module name="WhitespaceAround">
+      <property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV,DIV_ASSIGN,EQUAL,GE,GT,LAND,LE,LITERAL_ASSERT,LITERAL_CATCH,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_RETURN,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS,PLUS_ASSIGN,QUESTION,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND"/>
+    </module>
+    <module name="RedundantModifier"/>
+    <module name="AvoidNestedBlocks">
+      <property name="allowInSwitchCase" value="true"/>
+    </module>
+    <module name="EmptyBlock">
+      <property name="option" value="text"/>
+      <property name="tokens" value="LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_IF,LITERAL_TRY,LITERAL_WHILE,STATIC_INIT"/>
+    </module>
+    <module name="LeftCurly"/>
+    <module name="NeedBraces"/>
+    <module name="RightCurly"/>
+    <module name="DoubleCheckedLocking">
+      <property name="severity" value="error"/>
+    </module>
+    <module name="EmptyStatement"/>
+    <module name="HiddenField">
+      <property name="severity" value="ignore"/>
+      <property name="ignoreConstructorParameter" value="true"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="FinalClass"/>
+    <module name="HideUtilityClassConstructor">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="ArrayTypeStyle"/>
+    <module name="UpperEll"/>
+    <module name="FallThrough"/>
+    <module name="FinalLocalVariable">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="MultipleVariableDeclarations"/>
+    <module name="StringLiteralEquality">
+      <property name="severity" value="error"/>
+    </module>
+    <module name="SuperFinalize"/>
+    <module name="UnnecessaryParentheses">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="Indentation">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="StaticVariableName">
+      <property name="format" value="^[A-Za-z][a-zA-Z0-9]*$"/>
+    </module>
+    <module name="EmptyForInitializerPad"/>
+    <module name="EmptyForIteratorPad"/>
+    <module name="ModifierOrder"/>
+    <module name="DefaultComesLast"/>
+    <module name="InnerAssignment">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="JUnitTestCase"/>
+    <module name="ModifiedControlVariable"/>
+    <module name="MutableException">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="ParameterAssignment">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <metadata name="net.sf.eclipsecs.core.comment" value="Illegal trailing whitespace(s) at the end of the line."/>
+      <property name="format" value="\s$"/>
+      <property name="message" value="Illegal trailing whitespace(s) at the end of the line."/>
+      <property name="ignoreComments" value="true"/>
+      <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Checks for trailing spaces at the end of a line"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <metadata name="net.sf.eclipsecs.core.comment" value="illegal space before a comma"/>
+      <property name="format" value=" ,"/>
+      <property name="message" value="illegal space before a comma"/>
+      <property name="ignoreComments" value="true"/>
+      <metadata name="com.atlassw.tools.eclipse.checkstyle.customMessage" value="Illegal whitespace before a comma."/>
+      <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Checks for whitespace before a comma."/>
+    </module>
+  </module>
+  <module name="RegexpHeader">
+    <property name="header" value="/\*\n \* Copyright \(c\) (20[0-9][0-9], )?20[0-9][0-9], Oracle and/or its affiliates. All rights reserved.\n \* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n \*\n \* This code is free software; you can redistribute it and/or modify it\n \* under the terms of the GNU General Public License version 2 only, as\n \* published by the Free Software Foundation.\n \*\n \* This code is distributed in the hope that it will be useful, but WITHOUT\n \* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n \* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n \* version 2 for more details \(a copy is included in the LICENSE file that\n \* accompanied this code\).\n \*\n \* You should have received a copy of the GNU General Public License version\n \* 2 along with this work; if not, write to the Free Software Foundation,\n \* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n \*\n \* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n \* or visit www.oracle.com if you need additional information or have any\n \* questions.\n \*/\n"/>
+  </module>
+  <module name="FileTabCharacter">
+    <property name="severity" value="error"/>
+  </module>
+  <module name="NewlineAtEndOfFile">
+    <property name="lineSeparator" value="lf"/>
+  </module>
+  <module name="Translation"/>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop constant name check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume constant name check"/>
+    <property name="checkFormat" value="ConstantNameCheck"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Allow non-conforming constant names"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop method name check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume method name check"/>
+    <property name="checkFormat" value="MethodName"/>
+    <property name="checkC" value="false"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable method name checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: stop parameter assignment check"/>
+    <property name="onCommentFormat" value="CheckStyle: resume parameter assignment check"/>
+    <property name="checkFormat" value="ParameterAssignment"/>
+    <property name="checkC" value="false"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable Parameter Assignment"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop final variable check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume final variable check"/>
+    <property name="checkFormat" value="FinalLocalVariable"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable final variable checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop"/>
+    <property name="onCommentFormat" value="Checkstyle: resume"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable all checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="// START GENERATED RAW ASSEMBLER METHODS"/>
+    <property name="onCommentFormat" value="// END GENERATED RAW ASSEMBLER METHODS"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable all checks for generated raw assembler methods"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="// START GENERATED LABEL ASSEMBLER METHODS"/>
+    <property name="onCommentFormat" value="// END GENERATED LABEL ASSEMBLER METHODS"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable all checks for generated label assembler methods"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: stop inner assignment check"/>
+    <property name="onCommentFormat" value="CheckStyle: resume inner assignment check"/>
+    <property name="checkFormat" value="InnerAssignment"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable inner assignment checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop field name check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume field name check"/>
+    <property name="checkFormat" value="MemberName"/>
+    <property name="checkC" value="false"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable field name checks"/>
+  </module>
+  <module name="RegexpMultiline">
+    <metadata name="net.sf.eclipsecs.core.comment" value="illegal Windows line ending"/>
+    <property name="format" value="\r\n"/>
+    <property name="message" value="illegal Windows line ending"/>
+  </module>
+</module>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/BitMap.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,702 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.graph;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.BitSet;
+
+/**
+ * Implements a bitmap that stores a single bit for a range of integers (0-n).
+ */
+public final class BitMap implements Serializable {
+
+    public static final long serialVersionUID = 0L;
+
+    private static final int ADDRESS_BITS_PER_WORD = 6;
+    private static final int BITS_PER_WORD = 1 << ADDRESS_BITS_PER_WORD;
+    private static final int BIT_INDEX_MASK = BITS_PER_WORD - 1;
+
+    public static final int DEFAULT_LENGTH = BITS_PER_WORD;
+
+    public static int roundUpLength(int length) {
+        return ((length + (BITS_PER_WORD - 1)) >> ADDRESS_BITS_PER_WORD) << ADDRESS_BITS_PER_WORD;
+    }
+
+    private int size;
+    private long low;
+    private long[] extra;
+
+    /**
+     * Constructs a new bit map with the {@linkplain #DEFAULT_LENGTH default length}.
+     */
+    public BitMap() {
+        this(DEFAULT_LENGTH);
+    }
+
+    /**
+     * Constructs a new bit map from a byte array encoded bit map.
+     *
+     * @param bitmap the bit map to convert
+     */
+    public BitMap(byte[] bitmap) {
+        this(bitmap, 0, bitmap.length);
+    }
+
+    /**
+     * Constructs a new bit map from a byte array encoded bit map.
+     *
+     * @param arr the byte array containing the bit map to convert
+     * @param off the byte index in {@code arr} at which the bit map starts
+     * @param numberOfBytes the number of bytes worth of bits to copy from {@code arr}
+     */
+    public BitMap(byte[] arr, int off, int numberOfBytes) {
+        this(numberOfBytes * 8);
+        int byteIndex = off;
+        int end = off + numberOfBytes;
+        assert end <= arr.length;
+        while (byteIndex < end && (byteIndex - off) < 8) {
+            long bite = (long) arr[byteIndex] & 0xff;
+            low |= bite << ((byteIndex - off) * 8);
+            byteIndex++;
+        }
+        if (byteIndex < end) {
+            assert (byteIndex - off) == 8;
+            int remBytes = end - byteIndex;
+            int remWords = (remBytes + 7) / 8;
+            for (int word = 0; word < remWords; word++) {
+                long w = 0L;
+                for (int i = 0; i < 8 && byteIndex < end; i++) {
+                    long bite = (long) arr[byteIndex] & 0xff;
+                    w |= bite << (i * 8);
+                    byteIndex++;
+                }
+                extra[word] = w;
+            }
+        }
+    }
+
+    /**
+     * Converts a {@code long} to a {@link BitMap}.
+     */
+    public static BitMap fromLong(long bitmap) {
+        BitMap bm = new BitMap(64);
+        bm.low = bitmap;
+        return bm;
+    }
+
+    /**
+     * Constructs a new bit map with the specified length.
+     *
+     * @param length the length of the bitmap
+     */
+    public BitMap(int length) {
+        assert length >= 0;
+        this.size = length;
+        if (length > BITS_PER_WORD) {
+            extra = new long[length >> ADDRESS_BITS_PER_WORD];
+        }
+    }
+
+    /**
+     * Sets the bit at the specified index.
+     *
+     * @param i the index of the bit to set
+     */
+    public void set(int i) {
+        if (checkIndex(i) < BITS_PER_WORD) {
+            low |= 1L << i;
+        } else {
+            int pos = wordIndex(i);
+            int index = bitInWord(i);
+            extra[pos] |= 1L << index;
+        }
+    }
+
+    /**
+     * Grows this bitmap to a new size, appending necessary zero bits.
+     *
+     * @param newLength the new length of the bitmap
+     */
+    public void grow(int newLength) {
+        if (newLength > size) {
+            // grow this bitmap to the new length
+            int newSize = newLength >> ADDRESS_BITS_PER_WORD;
+            if (newLength > 0) {
+                if (extra == null) {
+                    // extra just needs to be allocated now
+                    extra = new long[newSize];
+                } else {
+                    if (extra.length < newSize) {
+                        // extra needs to be copied
+                        long[] newExtra = new long[newSize];
+                        for (int i = 0; i < extra.length; i++) {
+                            newExtra[i] = extra[i];
+                        }
+                        extra = newExtra;
+                    } else {
+                        // nothing to do, extra is already the right size
+                    }
+                }
+            }
+            size = newLength;
+        }
+    }
+
+    private static int bitInWord(int i) {
+        return i & BIT_INDEX_MASK;
+    }
+
+    private static int wordIndex(int i) {
+        return (i >> ADDRESS_BITS_PER_WORD) - 1;
+    }
+
+    /**
+     * Clears the bit at the specified index.
+     * @param i the index of the bit to clear
+     */
+    public void clear(int i) {
+        if (checkIndex(i) < BITS_PER_WORD) {
+            low &= ~(1L << i);
+        } else {
+            int pos = wordIndex(i);
+            int index = bitInWord(i);
+            extra[pos] &= ~(1L << index);
+        }
+    }
+
+    /**
+     * Sets all the bits in this bitmap.
+     */
+    public void setAll() {
+        low = -1;
+        if (extra != null) {
+            for (int i = 0; i < extra.length; i++) {
+                extra[i] = -1;
+            }
+        }
+    }
+
+    /**
+     * Clears all the bits in this bitmap.
+     */
+    public void clearAll() {
+        low = 0;
+        if (extra != null) {
+            for (int i = 0; i < extra.length; i++) {
+                extra[i] = 0;
+            }
+        }
+    }
+
+    /**
+     * Gets the value of the bit at the specified index.
+     *
+     * @param i the index of the bit to get
+     * @return {@code true} if the bit at the specified position is {@code 1}
+     */
+    public boolean get(int i) {
+        if (checkIndex(i) < BITS_PER_WORD) {
+            return ((low >> i) & 1) != 0;
+        }
+        int pos = wordIndex(i);
+        int index = bitInWord(i);
+        long bits = extra[pos];
+        return ((bits >> index) & 1) != 0;
+    }
+
+    /**
+     * Gets the value of the bit at the specified index, returning {@code false} if the
+     * bitmap does not cover the specified index.
+     *
+     * @param i the index of the bit to get
+     * @return {@code true} if the bit at the specified position is {@code 1}
+     */
+    public boolean getDefault(int i) {
+        if (i < 0 || i >= size) {
+            return false;
+        }
+        if (i < BITS_PER_WORD) {
+            return ((low >> i) & 1) != 0;
+        }
+        int pos = wordIndex(i);
+        int index = bitInWord(i);
+        long bits = extra[pos];
+        return ((bits >> index) & 1) != 0;
+    }
+
+    /**
+     * Performs the union operation on this bitmap with the specified bitmap. That is, all bits set in either of the two
+     * bitmaps will be set in this bitmap following this operation.
+     *
+     * @param other the other bitmap for the union operation
+     */
+    public void setUnion(BitMap other) {
+        low |= other.low;
+        if (extra != null && other.extra != null) {
+            for (int i = 0; i < extra.length && i < other.extra.length; i++) {
+                extra[i] |= other.extra[i];
+            }
+        }
+    }
+
+    /**
+     * Performs the union operation on this bitmap with the specified bitmap. That is, a bit is set in this
+     * bitmap if and only if it is set in both this bitmap and the specified bitmap.
+     *
+     * @param other the other bitmap for this operation
+     * @return {@code true} if any bits were cleared as a result of this operation
+     */
+    public boolean setIntersect(BitMap other) {
+        boolean same = true;
+        long intx = low & other.low;
+        if (low != intx) {
+            same = false;
+            low = intx;
+        }
+        long[] oxtra = other.extra;
+        if (extra != null && oxtra != null) {
+            for (int i = 0; i < extra.length; i++) {
+                long a = extra[i];
+                if (i < oxtra.length) {
+                    // zero bits out of this map
+                    long ax = a & oxtra[i];
+                    if (a != ax) {
+                        same = false;
+                        extra[i] = ax;
+                    }
+                } else {
+                    // this bitmap is larger than the specified bitmap; zero remaining bits
+                    if (a != 0) {
+                        same = false;
+                        extra[i] = 0;
+                    }
+                }
+            }
+        }
+        return !same;
+    }
+
+    /**
+     * Gets the number of addressable bits in this bitmap.
+     *
+     * @return the size of this bitmap
+     */
+    public int size() {
+        return size;
+    }
+
+    private int checkIndex(int i) {
+        if (i < 0 || i >= size) {
+            throw new IndexOutOfBoundsException("Index " + i + " is out of bounds (size=" + size + ")");
+        }
+        return i;
+    }
+
+    public void setFrom(BitMap other) {
+        assert this.size == other.size : "must have same size";
+
+        low = other.low;
+        if (extra != null) {
+            for (int i = 0; i < extra.length; i++) {
+                extra[i] = other.extra[i];
+            }
+        }
+    }
+
+    public void setDifference(BitMap other) {
+        assert this.size == other.size : "must have same size";
+
+        low &= ~other.low;
+        if (extra != null) {
+            for (int i = 0; i < extra.length; i++) {
+                extra[i] &= ~other.extra[i];
+            }
+        }
+    }
+
+    public void negate() {
+        low = ~low;
+        if (extra != null) {
+            for (int i = 0; i < extra.length; i++) {
+                extra[i] = ~extra[i];
+            }
+        }
+    }
+
+    public boolean isSame(BitMap other) {
+        if (this.size != other.size || this.low != other.low) {
+            return false;
+        }
+
+        if (extra != null) {
+            for (int i = 0; i < extra.length; i++) {
+                if (extra[i] != other.extra[i]) {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns the index of the first set bit that occurs on or after a specified start index.
+     * If no such bit exists then -1 is returned.
+     * <p>
+     * To iterate over the set bits in a {@code BitMap}, use the following loop:
+     *
+     * <pre>
+     * for (int i = bitMap.nextSetBit(0); i &gt;= 0; i = bitMap.nextSetBit(i + 1)) {
+     *     // operate on index i here
+     * }
+     * </pre>
+     *
+     * @param fromIndex the index to start checking from (inclusive)
+     * @return the index of the lowest set bit between {@code [fromIndex .. size())} or -1 if there is no set bit in this range
+     * @throws IndexOutOfBoundsException if the specified index is negative.
+     */
+    public int nextSetBit(int fromIndex) {
+        return nextSetBit(fromIndex, size());
+    }
+
+    /**
+     * Returns the index of the first set bit that occurs on or after a specified start index
+     * and before a specified end index. If no such bit exists then -1 is returned.
+     * <p>
+     * To iterate over the set bits in a {@code BitMap}, use the following loop:
+     *
+     * <pre>
+     * for (int i = bitMap.nextSetBit(0, bitMap.size()); i &gt;= 0; i = bitMap.nextSetBit(i + 1, bitMap.size())) {
+     *     // operate on index i here
+     * }
+     * </pre>
+     *
+     * @param fromIndex the index to start checking from (inclusive)
+     * @param toIndex the index at which to stop checking (exclusive)
+     * @return the index of the lowest set bit between {@code [fromIndex .. toIndex)} or -1 if there is no set bit in this range
+     * @throws IndexOutOfBoundsException if the specified index is negative.
+     */
+    public int nextSetBit(int fromIndex, int toIndex) {
+        assert fromIndex <= size() : "index out of bounds";
+        assert toIndex <= size() : "index out of bounds";
+        assert fromIndex <= toIndex : "fromIndex > toIndex";
+
+        if (fromIndex == toIndex) {
+            return -1;
+        }
+        int fromWordIndex = wordIndex(fromIndex);
+        int toWordIndex = wordIndex(toIndex - 1) + 1;
+        int resultIndex = fromIndex;
+
+        // check bits including and to the left_ of offset's position
+        int pos = bitInWord(resultIndex);
+        long res = map(fromWordIndex) >> pos;
+        if (res != 0) {
+            resultIndex += Long.numberOfTrailingZeros(res);
+            assert resultIndex >= fromIndex && resultIndex < toIndex : "just checking";
+            if (resultIndex < toIndex) {
+                return resultIndex;
+            }
+            return -1;
+        }
+        // skip over all word length 0-bit runs
+        for (fromWordIndex++; fromWordIndex < toWordIndex; fromWordIndex++) {
+            res = map(fromWordIndex);
+            if (res != 0) {
+                // found a 1, return the offset
+                resultIndex = bitIndex(fromWordIndex) + Long.numberOfTrailingZeros(res);
+                assert resultIndex >= fromIndex : "just checking";
+                if (resultIndex < toIndex) {
+                    return resultIndex;
+                }
+                return -1;
+            }
+        }
+        return -1;
+    }
+
+    private static int bitIndex(int index) {
+        return (index + 1) << ADDRESS_BITS_PER_WORD;
+    }
+
+    private long map(int index) {
+        if (index == -1) {
+            return low;
+        }
+        return extra[index];
+    }
+
+    private static boolean allZeros(int start, long[] arr) {
+        for (int i = start; i < arr.length; i++) {
+            if (arr[i] != 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Compares this object against the specified object.
+     * The result is {@code true} if and only if {@code obj} is
+     * not {@code null} and is a {@code CiBitMap} object that has
+     * exactly the same set of bits set to {@code true} as this bit
+     * set.
+     *
+     * @param   obj   the object to compare with.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof BitMap) {
+            BitMap bm = (BitMap) obj;
+            if (bm.low == low) {
+                if (bm.extra == null) {
+                    if (extra == null) {
+                        // Common case
+                        return true;
+                    }
+                    return allZeros(0, extra);
+                }
+                if (extra == null) {
+                    return allZeros(0, bm.extra);
+                }
+                // both 'extra' array non null:
+                int i = 0;
+                int length = Math.min(extra.length, bm.extra.length);
+                while (i < length) {
+                    if (extra[i] != bm.extra[i]) {
+                        return false;
+                    }
+                    i++;
+                }
+                if (extra.length > bm.extra.length) {
+                    return allZeros(length, extra);
+                }
+                if (extra.length < bm.extra.length) {
+                    return allZeros(length, bm.extra);
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns a string representation of this bit map
+     * that is the same as the string returned by {@link BitSet#toString()}
+     * for a bit set with the same bits set as this bit map.
+     */
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(size * 2);
+        sb.append('{');
+
+        int bit = nextSetBit(0);
+        if (bit != -1) {
+            sb.append(bit);
+            for (bit = nextSetBit(bit + 1); bit >= 0; bit = nextSetBit(bit + 1)) {
+                sb.append(", ").append(bit);
+            }
+        }
+
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + Arrays.hashCode(extra);
+        result = prime * result + (int) (low ^ (low >>> 32));
+        result = prime * result + size;
+        return result;
+    }
+
+    public static int highestOneBitIndex(long value) {
+        int bit = Long.numberOfTrailingZeros(Long.highestOneBit(value));
+        if (bit == 64) {
+            return -1;
+        }
+        return bit;
+    }
+
+    /**
+     * Returns the number of bits set to {@code true} in this bit map.
+     */
+    public int cardinality() {
+        int sum = Long.bitCount(low);
+        if (extra != null) {
+            for (long word : extra) {
+                sum += Long.bitCount(word);
+            }
+        }
+        return sum;
+    }
+
+    /**
+     * Returns the "logical size" of this bit map: the index of
+     * the highest set bit in the bit map plus one. Returns zero
+     * if the bit map contains no set bits.
+     *
+     * @return  the logical size of this bit map
+     */
+    public int length() {
+        if (extra != null) {
+            for (int i = extra.length - 1; i >= 0; i--) {
+                if (extra[i] != 0) {
+                    return (highestOneBitIndex(extra[i]) + ((i + 1) * 64)) + 1;
+                }
+            }
+        }
+        return highestOneBitIndex(low) + 1;
+    }
+
+    /**
+     * Returns a string representation of this bit map with every set bit represented as {@code '1'}
+     * and every unset bit represented as {@code '0'}. The first character in the returned string represents
+     * bit 0 in this bit map.
+     *
+     * @param length the number of bits represented in the returned string. If {@code length < 0 || length > size()},
+     *            then the value of {@link #length()} is used.
+     */
+    public String toBinaryString() {
+        int length = length();
+        if (length == 0) {
+            return "";
+        }
+        StringBuilder sb = new StringBuilder(length);
+        for (int i = 0; i < length; ++i) {
+            sb.append(get(i) ? '1' : '0');
+        }
+        return sb.toString();
+    }
+
+    static final char[] hexDigits = {
+        '0', '1', '2', '3', '4', '5', '6', '7',
+        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+    };
+
+    /**
+     * Returns a string representation of this bit map in hex.
+     */
+    public String toHexString() {
+        if (size == 0) {
+            return "";
+        }
+        int hexSize = align(this.size, 4);
+        StringBuilder sb = new StringBuilder(hexSize / 4);
+        for (int i = 0; i < hexSize; i += 4) {
+            int nibble = get(i) ? 1 : 0;
+            if (get(i + 1)) {
+                nibble |= 2;
+            }
+            if (get(i + 2)) {
+                nibble |= 4;
+            }
+            if (get(i + 3)) {
+                nibble |= 8;
+            }
+
+            sb.append(hexDigits[nibble]);
+        }
+        return sb.toString();
+    }
+
+    private static int align(int size, int align) {
+        return (size + align - 1) & ~(align - 1);
+    }
+
+    public BitMap copy() {
+        BitMap n = new BitMap(BITS_PER_WORD);
+        n.low = low;
+        if (extra != null) {
+            n.extra = Arrays.copyOf(extra, extra.length);
+        }
+        n.size = size;
+        return n;
+    }
+
+    /**
+     * Copies this bit map into a given byte array.
+     *
+     * @param arr the destination
+     * @param off the byte index in {@code arr} at which to start writing
+     * @param numberOfBytes the number of bytes worth of bits to copy from this bit map.
+     * @return the number of bytes written to {@code arr}
+     */
+    public int copyTo(byte[] arr, int off, int numberOfBytes) {
+        for (int i = 0; i < numberOfBytes; ++i) {
+            long word = low;
+            int byteInWord;
+            if (i >= 8) {
+                int wordIndex = (i - 8) / 8;
+                word = extra[wordIndex];
+                byteInWord = i & 0x7;
+            } else {
+                byteInWord = i;
+            }
+            assert byteInWord < 8;
+            byte b = (byte) (word >> (byteInWord * 8));
+            arr[off + i] = b;
+        }
+        return numberOfBytes;
+    }
+
+    /**
+     * Converts this bit map to a byte array. The length of the returned
+     * byte array is {@code ((size() + 7) / 8)}.
+     */
+    public byte[] toByteArray() {
+        byte[] arr = new byte[(size + 7) / 8];
+        copyTo(arr, 0, arr.length);
+        return arr;
+    }
+
+    /**
+     * Converts this bit map to a long.
+     *
+     * @throws IllegalArgumentException if {@code (size() > 64)}
+     */
+    public long toLong() {
+        if (size > 64) {
+            throw new IllegalArgumentException("bit map of size " + size + " cannot be converted to long");
+        }
+        return low;
+    }
+
+    public boolean containsAll(BitMap other) {
+        assert this.size == other.size : "must have same size";
+        if ((low & other.low) != other.low) {
+            return false;
+        }
+        if (extra != null) {
+            for (int i = 0; i < extra.length; i++) {
+                if ((extra[i] & other.extra[i]) != other.extra[i]) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/GraalInternalError.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,145 @@
+/*
+ * 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.max.graal.graph;
+
+import java.util.*;
+
+/**
+ * This error represents a conditions that should never occur during normal operation.
+ */
+public class GraalInternalError extends Error {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 8776065085829593278L;
+    private Node node;
+    private Graph graph;
+    private final ArrayList<String> context = new ArrayList<>();
+
+    public static RuntimeException unimplemented() {
+        throw new GraalInternalError("unimplemented");
+    }
+
+    public static RuntimeException unimplemented(String msg) {
+        throw new GraalInternalError("unimplemented: %s", msg);
+    }
+
+    public static RuntimeException shouldNotReachHere() {
+        throw new GraalInternalError("should not reach here");
+    }
+
+    public static RuntimeException shouldNotReachHere(String msg) {
+        throw new GraalInternalError("should not reach here: %s", msg);
+    }
+
+
+    /**
+     * This constructor creates a {@link GraalInternalError} with a message assembled via {@link String#format(String, Object...)}.
+     * It always uses the ENGLISH locale in order to always generate the same output.
+     * @param msg the message that will be associated with the error, in String.format syntax
+     * @param args parameters to String.format - parameters that implement {@link Iterable} will be expanded into a [x, x, ...] representation.
+     */
+    public GraalInternalError(String msg, Object... args) {
+        super(format(msg, args));
+    }
+
+    /**
+     * This constructor creates a {@link GraalInternalError} for a given causing Throwable instance.
+     * @param cause the original exception that contains additional information on this error
+     */
+    public GraalInternalError(Throwable cause) {
+        super(cause);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder str = new StringBuilder();
+        str.append(super.toString());
+        for (String s : context) {
+            str.append("\n\tat ").append(s);
+        }
+        return str.toString();
+    }
+
+    private static String format(String msg, Object... args) {
+        if (args != null) {
+            // expand Iterable parameters into a list representation
+            for (int i = 0; i < args.length; i++) {
+                if (args[i] instanceof Iterable<?>) {
+                    ArrayList<Object> list = new ArrayList<>();
+                    for (Object o : (Iterable<?>) args[i]) {
+                        list.add(o);
+                    }
+                    args[i] = list.toString();
+                }
+            }
+        }
+        return String.format(Locale.ENGLISH, msg, args);
+    }
+
+    public GraalInternalError addContext(String newContext) {
+        this.context.add(newContext);
+        return this;
+    }
+
+    public GraalInternalError addContext(String name, Object obj) {
+        return addContext(format("%s: %s", name, obj));
+    }
+
+    /**
+     * Adds a graph to the context of this VerificationError. The first graph added via this method will be returned by {@link #graph()}.
+     * @param newGraph the graph which is in a incorrect state, if the verification error was not caused by a specific node
+     */
+    public GraalInternalError addContext(Graph newGraph) {
+        if (newGraph != this.graph) {
+            addContext("graph", newGraph);
+            if (this.graph == null) {
+                this.graph = newGraph;
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Adds a node to the context of this VerificationError. The first node added via this method will be returned by {@link #node()}.
+     * @param newNode the node which is in a incorrect state, if the verification error was caused by a node
+     */
+    public GraalInternalError addContext(Node newNode) {
+        if (newNode != this.node) {
+            addContext("node", newNode);
+            if (this.node == null) {
+                this.node = newNode;
+            }
+        }
+        return this;
+    }
+
+    public Node node() {
+        return node;
+    }
+
+    public Graph graph() {
+        return graph;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Graph.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,506 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.graph;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.GraphEvent.NodeEvent;
+import com.oracle.max.graal.graph.Node.IterableNodeType;
+import com.oracle.max.graal.graph.Node.ValueNumberable;
+import com.oracle.max.graal.graph.iterators.*;
+
+/**
+ * This class is a graph container, it contains the set of nodes that belong to this graph.
+ */
+public class Graph {
+
+    protected final String name;
+
+    private static final boolean TIME_TRAVEL = false;
+
+    private final ArrayList<Node> nodes;
+
+    // these two arrays contain one entry for each NodeClass, indexed by NodeClass.iterableId.
+    // they contain the first and last pointer to a linked list of all nodes with this type.
+    private final ArrayList<Node> nodeCacheFirst;
+    private final ArrayList<Node> nodeCacheLast;
+    private int deletedNodeCount;
+    private int mark;
+    private GraphEventLog eventLog;
+
+    ArrayList<Node> usagesDropped = new ArrayList<>();
+    NodeWorkList inputChanged;
+    private final HashMap<CacheEntry, Node> cachedNodes = new HashMap<>();
+
+    private static final class CacheEntry {
+
+        private final Node node;
+
+        public CacheEntry(Node node) {
+            this.node = node;
+        }
+
+        @Override
+        public int hashCode() {
+            return node.getNodeClass().valueNumber(node);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this) {
+                return true;
+            }
+            if (obj instanceof CacheEntry) {
+                CacheEntry other = (CacheEntry) obj;
+                NodeClass nodeClass = node.getNodeClass();
+                if (other.node.getNodeClass() == nodeClass) {
+                    return nodeClass.valueNumberable() && nodeClass.valueEqual(node, other.node) && nodeClass.edgesEqual(node, other.node);
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Creates an empty Graph with no name.
+     */
+    public Graph() {
+        this(null);
+    }
+
+    /**
+     * Creates an empty Graph with a given name.
+     *
+     * @param name the name of the graph, used for debugging purposes
+     */
+    public Graph(String name) {
+        nodes = new ArrayList<>(32);
+        nodeCacheFirst = new ArrayList<>(NodeClass.cacheSize());
+        nodeCacheLast = new ArrayList<>(NodeClass.cacheSize());
+        this.name = name;
+    }
+
+    /**
+     * Creates a copy of this graph.
+     */
+    public Graph copy() {
+        return copy(name);
+    }
+
+    /**
+     * Creates a copy of this graph.
+     *
+     * @param name the name of the copy, used for debugging purposes (can be null)
+     */
+    public Graph copy(String newName) {
+        Graph copy = new Graph(newName);
+        Map<Node, Node> emptyMap = Collections.emptyMap();
+        copy.addDuplicates(getNodes(), emptyMap);
+        return copy;
+    }
+
+    @Override
+    public String toString() {
+        return name == null ? super.toString() : "Graph " + name;
+    }
+
+    /**
+     * Gets the number of live nodes in this graph. That is the number of nodes which have been added to the graph minus the number of deleted nodes.
+     * @return the number of live nodes in this graph
+     */
+    public int getNodeCount() {
+        return nodes.size() - getDeletedNodeCount();
+    }
+
+    /**
+     * Gets the number of node which have been deleted from this graph.
+     * @return the number of node which have been deleted from this graph
+     */
+    public int getDeletedNodeCount() {
+        return deletedNodeCount;
+    }
+
+    /**
+     * Adds a new node to the graph.
+     * @param node the node to be added
+     * @return the node which was added to the graph
+     */
+    public <T extends Node> T add(T node) {
+        node.initialize(this);
+        return node;
+    }
+
+    public int getUsagesDroppedNodesCount() {
+        return usagesDropped.size();
+    }
+
+    public List<Node> getAndCleanUsagesDroppedNodes() {
+        ArrayList<Node> result = usagesDropped;
+        usagesDropped = new ArrayList<>();
+        return result;
+    }
+
+    public void trackInputChange(NodeWorkList worklist) {
+        this.inputChanged = worklist;
+    }
+
+    public void stopTrackingInputChange() {
+        inputChanged = null;
+    }
+
+    /**
+     * Adds a new node to the graph, if a <i>similar</i> node already exists in the graph, the provided node will not be added to the graph but the <i>similar</i> node will be returned instead.
+     * @param node
+     * @return the node which was added to the graph or a <i>similar</i> which was already in the graph.
+     */
+    @SuppressWarnings("unchecked")
+    public <T extends Node & ValueNumberable> T unique(T node) {
+        assert checkValueNumberable(node);
+
+        for (Node input : node.inputs()) {
+            if (input != null) {
+                for (Node usage : input.usages()) {
+                    if (usage != node && node.getNodeClass().valueEqual(node, usage) && node.getNodeClass().edgesEqual(node, usage)) {
+                        return (T) usage;
+                    }
+                }
+                return add(node);
+            }
+        }
+        Node cachedNode = cachedNodes.get(new CacheEntry(node));
+        if (cachedNode != null && cachedNode.isAlive()) {
+            return (T) cachedNode;
+        } else {
+            Node result = add(node);
+            cachedNodes.put(new CacheEntry(node), result);
+            return (T) result;
+        }
+    }
+
+    public Node findDuplicate(Node node) {
+        if (node.getNodeClass().valueNumberable()) {
+            for (Node input : node.inputs()) {
+                if (input != null) {
+                    for (Node usage : input.usages()) {
+                        if (usage != node && node.getNodeClass().valueEqual(node, usage) && node.getNodeClass().edgesEqual(node, usage)) {
+                            return usage;
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+        return null;
+    }
+
+    private static boolean checkValueNumberable(Node node) {
+        if (!node.getNodeClass().valueNumberable()) {
+            throw new VerificationError("node is not valueNumberable").addContext(node);
+        }
+        return true;
+    }
+
+    public void mark() {
+        this.mark = nodeIdCount();
+    }
+
+    private class NodeIterator implements Iterator<Node> {
+        private int index;
+
+        public NodeIterator() {
+            this(0);
+        }
+
+        public NodeIterator(int index) {
+            this.index = index - 1;
+            forward();
+        }
+
+        private void forward() {
+            if (index < nodes.size()) {
+                do {
+                    index++;
+                } while (index < nodes.size() && nodes.get(index) == null);
+            }
+        }
+
+        @Override
+        public boolean hasNext() {
+            checkForDeletedNode();
+            return index < nodes.size();
+        }
+
+        private void checkForDeletedNode() {
+            if (index < nodes.size()) {
+                while (index < nodes.size() && nodes.get(index) == null) {
+                    index++;
+                }
+            }
+        }
+
+        @Override
+        public Node next() {
+            try {
+                return nodes.get(index);
+            } finally {
+                forward();
+            }
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    /**
+     * Returns an {@link Iterable} providing all nodes added since the last {@link Graph#mark() mark}.
+     * @return an {@link Iterable} providing the new nodes
+     */
+    public NodeIterable<Node> getNewNodes() {
+        final int index = this.mark;
+        return new NodeIterable<Node>() {
+            @Override
+            public Iterator<Node> iterator() {
+                return new NodeIterator(index);
+            }
+        };
+    }
+
+    /**
+     * Returns an {@link Iterable} providing all the live nodes.
+     * @return an {@link Iterable} providing all the live nodes.
+     */
+    public NodeIterable<Node> getNodes() {
+        return new NodeIterable<Node>() {
+            @Override
+            public Iterator<Node> iterator() {
+                return new NodeIterator();
+            }
+        };
+    }
+
+    private static class TypedNodeIterator<T extends IterableNodeType> implements Iterator<T> {
+        private Node current;
+        private final Node start;
+
+        public TypedNodeIterator(Node start) {
+            if (start != null && start.isDeleted()) {
+                this.current = start;
+            } else {
+                this.current = null;
+            }
+            this.start = start;
+        }
+
+        @Override
+        public boolean hasNext() {
+            if (current != null) {
+                Node next = current.typeCacheNext;
+                if (next != null) {
+                    while (next.isDeleted()) {
+                        next = next.typeCacheNext;
+                        if (next == null) {
+                            return false;
+                        }
+                        current.typeCacheNext = next;
+                    }
+                    return true;
+                }
+                return false;
+            } else {
+                return start != null;
+            }
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public T next() {
+            if (current == null) {
+                Node result = start;
+                current = result;
+                return (T) result;
+            } else {
+                Node result = current.typeCacheNext;
+                current = result;
+                return (T) result;
+            }
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    /**
+     * Returns an {@link Iterable} providing all the live nodes whose type is compatible with {@code type}.
+     * @param type the type of node to return
+     * @return an {@link Iterable} providing all the matching nodes.
+     */
+    public <T extends Node & IterableNodeType> NodeIterable<T> getNodes(final Class<T> type) {
+        final Node start = getStartNode(type);
+        return new NodeIterable<T>() {
+            @Override
+            public Iterator<T> iterator() {
+                return new TypedNodeIterator<>(start);
+            }
+        };
+    }
+
+    /**
+     * Returns whether the graph contains at least one node of the given type.
+     * @param type the type of node that is checked for occurrence
+     * @return whether there is at least one such node
+     */
+    public <T extends Node & IterableNodeType> boolean hasNode(final Class<T> type) {
+        return getNodes(type).iterator().hasNext();
+    }
+
+    private <T> Node getStartNode(final Class<T> type) {
+        int nodeClassId = NodeClass.get(type).iterableId();
+        assert nodeClassId != -1 : type + " is not iterable within graphs (missing \"implements IterableNodeType\"?)";
+        Node start = nodeCacheFirst.size() <= nodeClassId ? null : nodeCacheFirst.get(nodeClassId);
+        return start;
+    }
+
+    public NodeBitMap createNodeBitMap() {
+        return new NodeBitMap(this);
+    }
+
+    public <T> NodeMap<T> createNodeMap() {
+        return new NodeMap<>(this);
+    }
+
+    public NodeFlood createNodeFlood() {
+        return new NodeFlood(this);
+    }
+
+    public NodeWorkList createNodeWorkList() {
+        return new NodeWorkList(this);
+    }
+
+    public NodeWorkList createNodeWorkList(boolean fill, int iterationLimitPerNode) {
+        return new NodeWorkList(this, fill, iterationLimitPerNode);
+    }
+
+    void register(Node node) {
+        assert node.id() == Node.INITIAL_ID;
+        int id = nodes.size();
+        nodes.add(id, node);
+
+        int nodeClassId = node.getNodeClass().iterableId();
+        if (nodeClassId != NodeClass.NOT_ITERABLE) {
+            while (nodeCacheFirst.size() <= nodeClassId) {
+                nodeCacheFirst.add(null);
+                nodeCacheLast.add(null);
+            }
+            Node prev = nodeCacheLast.get(nodeClassId);
+            if (prev != null) {
+                prev.typeCacheNext = node;
+            } else {
+                nodeCacheFirst.set(nodeClassId, node);
+            }
+            nodeCacheLast.set(nodeClassId, node);
+        }
+
+        node.id = id;
+        logNodeAdded(node);
+    }
+
+    void logNodeAdded(Node node) {
+        if (TIME_TRAVEL) {
+            log(new GraphEvent.NodeEvent(node, GraphEvent.NodeEvent.Type.ADDED));
+        }
+    }
+
+    void logNodeDeleted(Node node) {
+        if (TIME_TRAVEL) {
+            log(new GraphEvent.NodeEvent(node, GraphEvent.NodeEvent.Type.DELETED));
+        }
+    }
+
+    private void log(NodeEvent nodeEvent) {
+        if (eventLog == null) {
+            eventLog = new GraphEventLog();
+        }
+        eventLog.add(nodeEvent);
+    }
+
+    public GraphEventLog getEventLog() {
+        return eventLog;
+    }
+
+    void unregister(Node node) {
+        assert !node.isDeleted() : "cannot delete a node twice! node=" + node;
+        logNodeDeleted(node);
+        nodes.set(node.id(), null);
+        deletedNodeCount++;
+
+        // nodes aren't removed from the type cache here - they will be removed during iteration
+    }
+
+    public boolean verify() {
+        for (Node node : getNodes()) {
+            try {
+                try {
+                    assert node.verify();
+                } catch (AssertionError t) {
+                    throw new GraalInternalError(t);
+                } catch (RuntimeException t) {
+                    throw new GraalInternalError(t);
+                }
+            } catch (GraalInternalError e) {
+                throw e.addContext(node).addContext(this);
+            }
+        }
+        return true;
+    }
+
+    Node getNode(int i) {
+        return nodes.get(i);
+    }
+
+    /**
+     * Returns the number of node ids generated so far.
+     * @return the number of node ids generated so far
+     */
+    int nodeIdCount() {
+        return nodes.size();
+    }
+
+    /**
+     * Adds duplicates of the nodes in {@code nodes} to this graph.
+     * This will recreate any edges between the duplicate nodes. The {@code replacement} map can be used to
+     * replace a node from the source graph by a given node (which must already be in this graph).
+     * Edges between duplicate and replacement nodes will also be recreated so care should be taken
+     * regarding the matching of node types in the replacement map.
+     *
+     * @param newNodes the nodes to be duplicated
+     * @param replacements the replacement map (can be null if no replacement is to be performed)
+     * @return a map which associates the original nodes from {@code nodes} to their duplicates
+     */
+    public Map<Node, Node> addDuplicates(Iterable<Node> newNodes, Map<Node, Node> replacements) {
+        return NodeClass.addGraphDuplicate(this, newNodes, replacements);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/GraphEvent.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.graph;
+
+
+public abstract class GraphEvent {
+
+    private Exception exceptionContext;
+
+    public static class NodeEvent extends GraphEvent {
+
+        public static enum Type {
+            ADDED,
+            DELETED,
+            CHANGED
+        }
+
+        public final Node node;
+        public final Type type;
+        private final String nodeString;
+
+        public NodeEvent(Node n, Type type) {
+            this.node = n;
+            this.type = type;
+            nodeString = n.toString();
+        }
+
+        @Override
+        public StackTraceElement[] print(StackTraceElement[] last) {
+            System.out.println(type.toString() + ", " + nodeString);
+            return super.print(last);
+        }
+    }
+
+    public static class EdgeEvent extends GraphEvent {
+
+        public static enum Type {
+            INPUT,
+            SUCC
+        }
+
+        public final Node node;
+        public final int index;
+        public final Node newValue;
+        public final Type type;
+
+        public EdgeEvent(Node node, int index, Node newValue, Type type) {
+            this.node = node;
+            this.index = index;
+            this.newValue = newValue;
+            this.type = type;
+        }
+    }
+
+    public GraphEvent() {
+        exceptionContext = new Exception();
+    }
+
+    public StackTraceElement[] print(StackTraceElement[] last) {
+        StackTraceElement[] stackTrace = exceptionContext.getStackTrace();
+
+        boolean atTop = true;
+        for (int i = 0; i < stackTrace.length; ++i) {
+            StackTraceElement elem = stackTrace[i];
+            int toBottom = stackTrace.length - i;
+            if (atTop) {
+                if (!elem.getClassName().startsWith("com.oracle.max.graal.graph.Graph") && !elem.getClassName().startsWith("com.oracle.max.graal.graph.Node")) {
+                    atTop = false;
+                } else {
+                    continue;
+                }
+            } else {
+                if (last.length >= toBottom && last[last.length - toBottom].equals(elem)) {
+                    continue;
+                }
+            }
+            System.out.println(String.format("%s.%s(%s:%d)", elem.getClassName(), elem.getMethodName(), elem.getFileName(), elem.getLineNumber()));
+        }
+        return stackTrace;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/GraphEventLog.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.graph;
+
+import java.util.*;
+
+
+public class GraphEventLog {
+
+    private List<GraphEvent> events = new ArrayList<>();
+
+    public void add(GraphEvent e) {
+        this.events.add(e);
+    }
+
+    public void printEvents() {
+        StackTraceElement[] last = new StackTraceElement[0];
+        for (GraphEvent e : events) {
+            last = e.print(last);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,561 @@
+/*
+ * 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.max.graal.graph;
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import com.oracle.max.graal.graph.NodeClass.*;
+
+
+/**
+ * This class is the base class for all nodes, it represent a node which can be inserted in a {@link Graph}.<br>
+ * Once a node has been added to a graph, it has a graph-unique {@link #id()}. Edges in the subclasses are represented
+ * with annotated fields. There are two kind of edges : {@link Input} and {@link Successor}. If a field, of a type
+ * compatible with {@link Node}, annotated with either {@link Input} and {@link Successor} is not null, then there is an
+ * edge from this node to the node this field points to.<br>
+ * Fields in a node subclass can also be annotated with {@link Data} : such fields will be used when comparing 2 nodes
+ * with {@link #equals(Object)}, for value numbering and for debugging purposes.<br>
+ * Nodes which are be value numberable should implement the {@link ValueNumberable} interface.
+ *
+ * <h1>Assertions and Verification</h1>
+ *
+ * The Node class supplies the {@link #assertTrue(boolean, String, Object...)} and
+ * {@link #assertFalse(boolean, String, Object...)} methods, which will check the supplied boolean and throw a
+ * VerificationError if it has the wrong value. Both methods will always either throw an exception or return true.
+ * They can thus be used within an assert statement, so that the check is only performed if assertions are enabled.
+ *
+ *
+ */
+public abstract class Node implements Cloneable, Formattable {
+
+    static final int DELETED_ID_START = -1000000000;
+    static final int INITIAL_ID = -1;
+    static final int ALIVE_ID_START = 0;
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.FIELD)
+    public static @interface Input {
+        boolean notDataflow() default false;
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.FIELD)
+    public static @interface Successor {}
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.FIELD)
+    public static @interface Data {}
+
+    /**
+     * Denotes that a parameter of an {@linkplain NodeIntrinsic intrinsic} method
+     * must be a compile time constant at all call sites to the intrinic method.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.PARAMETER)
+    public static @interface ConstantNodeParameter {}
+
+    /**
+     * Annotates a method that can be replaced by a compiler intrinsic.
+     * That is, a (resolved) call to the annotated method can be replaced
+     * with an instance of the node class denoted by {@link #value()}.
+     * For this reason, the signature of the annotated method must match
+     * the signature of a constructor in the node class.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.METHOD)
+    public static @interface NodeIntrinsic {
+        /**
+         * Gets the {@link Node} subclass instantiated when intrinsifying a call to the annotated method.
+         * If not specified, then the class in which the annotated method is declared is used
+         * (and is assumed to be a {@link Node} subclass).
+         */
+        Class value() default NodeIntrinsic.class;
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.METHOD)
+    public static @interface NodePhase {
+        Class value() default NodePhase.class;
+    }
+
+    public interface ValueNumberable {}
+
+    public interface IterableNodeType {}
+
+    private Graph graph;
+    int id;
+
+    // this next pointer is used in Graph to implement fast iteration over NodeClass types, it therefore points to the next Node of the same type.
+    Node typeCacheNext;
+
+    private NodeUsagesList usages;
+    private Node predecessor;
+    private int modCount;
+    private NodeClass nodeClass;
+
+    public Node() {
+        this.graph = null;
+        this.id = INITIAL_ID;
+        nodeClass = NodeClass.get(getClass());
+    }
+
+    protected int id() {
+        return id;
+    }
+
+    public Graph graph() {
+        return graph;
+    }
+
+    /**
+     * Returns an {@link NodeInputsIterable iterable} which can be used to traverse all non-null input edges of this node.
+     * @return an {@link NodeInputsIterable iterable} for all non-null input edges.
+     */
+    public NodeInputsIterable inputs() {
+        return getNodeClass().getInputIterable(this);
+    }
+
+    /**
+     * Returns an {@link NodeSuccessorsIterable iterable} which can be used to traverse all non-null successor edges of this node.
+     * @return an {@link NodeSuccessorsIterable iterable} for all non-null successor edges.
+     */
+    public NodeSuccessorsIterable successors() {
+        return getNodeClass().getSuccessorIterable(this);
+    }
+
+    public final NodeUsagesList usages() {
+        return usages;
+    }
+
+    public final Node predecessor() {
+        return predecessor;
+    }
+
+    final int modCount() {
+        return modCount;
+    }
+
+    final void incModCount() {
+        modCount++;
+    }
+
+    public boolean isDeleted() {
+        return id <= DELETED_ID_START;
+    }
+
+    public boolean isAlive() {
+        return id >= ALIVE_ID_START;
+    }
+
+    /**
+     * Updates the usages sets of the given nodes after an input slot is changed from oldInput to newInput:
+     * removes this node from oldInput's usages and adds this node to newInput's usages.
+     */
+    protected void updateUsages(Node oldInput, Node newInput) {
+        assert assertTrue(usages != null, "usages == null while adding %s to %s", newInput, this);
+        if (oldInput != newInput) {
+            if (oldInput != null) {
+                boolean result = removeThisFromUsages(oldInput);
+                assert assertTrue(result, "not found in usages, old input: %s", oldInput);
+            }
+            if (newInput != null) {
+                NodeWorkList inputChanged = graph.inputChanged;
+                if (inputChanged != null) {
+                    inputChanged.addAgain(this);
+                }
+                newInput.usages.add(this);
+            }
+        }
+    }
+
+    /**
+     * Updates the predecessor sets of the given nodes after a successor slot is changed from oldSuccessor to newSuccessor:
+     * removes this node from oldSuccessor's predecessors and adds this node to newSuccessor's predecessors.
+     */
+    protected void updatePredecessors(Node oldSuccessor, Node newSuccessor) {
+        assert assertTrue(usages != null, "usages == null while adding %s to %s", newSuccessor, this);
+        if (oldSuccessor != newSuccessor) {
+            if (oldSuccessor != null) {
+                assert assertTrue(oldSuccessor.predecessor == this, "wrong predecessor in old successor (%s): %s", oldSuccessor, oldSuccessor.predecessor);
+                oldSuccessor.predecessor = null;
+            }
+            if (newSuccessor != null) {
+                assert assertTrue(newSuccessor.predecessor == null, "unexpected non-null predecessor in new successor (%s): %s", newSuccessor, newSuccessor.predecessor);
+                newSuccessor.predecessor = this;
+            }
+        }
+    }
+
+    void initialize(Graph newGraph) {
+        assert assertTrue(id == INITIAL_ID, "unexpected id: %d", id);
+        this.graph = newGraph;
+        newGraph.register(this);
+        usages = new NodeUsagesList();
+        for (Node input : inputs()) {
+            updateUsages(null, input);
+        }
+        for (Node successor : successors()) {
+            updatePredecessors(null, successor);
+        }
+    }
+
+    public final NodeClass getNodeClass() {
+        return nodeClass;
+    }
+
+    // TODO(tw): Do not allow to replace with null.
+    private boolean checkReplaceWith(Node other) {
+        assert assertFalse(other == this, "cannot replace a node with itself");
+        assert assertFalse(isDeleted(), "cannot replace deleted node");
+//        assert assertTrue(other != null, "cannot replace with null node");
+        assert assertTrue(other == null || !other.isDeleted(), "cannot replace with deleted node %s", other);
+        assert assertTrue(other == null || other.graph() == graph, "cannot replace with node in different graph: %s", other == null ? null : other.graph());
+        return true;
+    }
+
+    public void replaceAtUsages(Node other) {
+        assert checkReplaceWith(other);
+        for (Node usage : usages) {
+            boolean result = usage.getNodeClass().replaceFirstInput(usage, this, other);
+            assert assertTrue(result, "not found in inputs, usage: %s", usage);
+            if (other != null) {
+                other.usages.add(usage);
+            }
+        }
+        usages.clear();
+    }
+
+    public void replaceAtPredecessors(Node other) {
+        assert checkReplaceWith(other);
+        if (predecessor != null) {
+            boolean result = predecessor.getNodeClass().replaceFirstSuccessor(predecessor, this, other);
+            assert assertTrue(result, "not found in successors, predecessor: %s", predecessor);
+            predecessor.updatePredecessors(this, other);
+        }
+    }
+
+    public void replaceAndDelete(Node other) {
+        assert checkReplaceWith(other);
+        if (other != null) {
+            clearSuccessors();
+            replaceAtUsages(other);
+            replaceAtPredecessors(other);
+        }
+        safeDelete();
+    }
+
+    public void replaceFirstSuccessor(Node oldSuccessor, Node newSuccessor) {
+        if (getNodeClass().replaceFirstSuccessor(this, oldSuccessor, newSuccessor)) {
+            updatePredecessors(oldSuccessor, newSuccessor);
+        }
+    }
+
+    public void replaceFirstInput(Node oldInput, Node newInput) {
+        if (getNodeClass().replaceFirstInput(this, oldInput, newInput)) {
+            updateUsages(oldInput, newInput);
+        }
+    }
+
+    public void clearInputs() {
+        assert assertFalse(isDeleted(), "cannot clear inputs of deleted node");
+
+        for (Node input : inputs()) {
+            removeThisFromUsages(input);
+        }
+        getNodeClass().clearInputs(this);
+    }
+
+    private boolean removeThisFromUsages(Node n) {
+        if (n.usages.remove(this)) {
+            if (n.usages.size() == 0) {
+                graph.usagesDropped.add(n);
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public void clearSuccessors() {
+        assert assertFalse(isDeleted(), "cannot clear successors of deleted node");
+
+        for (Node successor : successors()) {
+            assert assertTrue(successor.predecessor == this, "wrong predecessor in old successor (%s): %s", successor, successor.predecessor);
+            successor.predecessor = null;
+        }
+        getNodeClass().clearSuccessors(this);
+    }
+
+    private boolean checkDeletion() {
+        assertTrue(usages.isEmpty(), "cannot delete node %s because of usages: %s", this, usages);
+        assertTrue(predecessor == null, "cannot delete node %s because of predecessor: %s", this, predecessor);
+        return true;
+    }
+
+    public void safeDelete() {
+        assert checkDeletion();
+        clearInputs();
+        clearSuccessors();
+        graph.unregister(this);
+        id = DELETED_ID_START - id;
+        assert isDeleted();
+    }
+
+    public final Node copyWithInputs() {
+        Node newNode = clone(graph);
+        NodeClass clazz = getNodeClass();
+        clazz.copyInputs(this, newNode);
+        for (Node input : inputs()) {
+            input.usages.add(newNode);
+        }
+        return newNode;
+    }
+
+    public Node clone(Graph into) {
+        Node newNode = null;
+        try {
+            newNode = (Node) this.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new GraalInternalError(e).addContext(this);
+        }
+        getNodeClass().clearInputs(newNode);
+        getNodeClass().clearSuccessors(newNode);
+        newNode.graph = into;
+        newNode.typeCacheNext = null;
+        newNode.id = INITIAL_ID;
+        into.register(newNode);
+        newNode.usages = new NodeUsagesList();
+        newNode.predecessor = null;
+        newNode.modCount = 0;
+        return newNode;
+    }
+
+    public boolean verify() {
+        assertTrue(isAlive(), "cannot verify inactive nodes (id=%d)", id);
+        assertTrue(graph() != null, "null graph");
+        for (Node input : inputs()) {
+            assertTrue(input.usages().contains(this), "missing usage in input %s", input);
+            assertTrue(input.graph() == graph(), "mismatching graph in input %s", input);
+        }
+        for (Node successor : successors()) {
+            assertTrue(successor.predecessor() == this, "missing predecessor in %s (actual: %s)", successor, successor.predecessor());
+            assertTrue(successor.graph() == graph(), "mismatching graph in successor %s", successor);
+        }
+        for (Node usage : usages()) {
+            assertFalse(usage.isDeleted(), "usage must never be deleted");
+            assertTrue(usage.inputs().contains(this), "missing input in usage %s", usage);
+        }
+        if (predecessor != null) {
+            assertFalse(predecessor.isDeleted(), "predecessor must never be deleted");
+            assertTrue(predecessor.successors().contains(this), "missing successor in predecessor %s", predecessor);
+        }
+        return true;
+    }
+
+    public boolean assertTrue(boolean condition, String message, Object... args) {
+        if (condition) {
+            return true;
+        } else {
+            throw new VerificationError(message, args).addContext(this);
+        }
+    }
+
+    public boolean assertFalse(boolean condition, String message, Object... args) {
+        if (condition) {
+            throw new VerificationError(message, args).addContext(this);
+        } else {
+            return true;
+        }
+    }
+
+    public Iterable<? extends Node> cfgPredecessors() {
+        if (predecessor == null) {
+            return Collections.emptySet();
+        } else {
+            return Collections.singleton(predecessor);
+        }
+    }
+
+    /**
+     * Returns an iterator that will provide all control-flow successors of this node. Normally this will be the contents of all fields marked as NodeSuccessor,
+     * but some node classes (like EndNode) may return different nodes.
+     * Note that the iterator may generate null values if the fields contain them.
+     */
+    public Iterable<? extends Node> cfgSuccessors() {
+        return successors();
+    }
+
+    /**
+     * hashCode and equals should always rely on object identity alone, thus hashCode and equals are final.
+     */
+    @Override
+    public final int hashCode() {
+        return super.hashCode();
+    }
+
+    /**
+     * hashCode and equals should always rely on object identity alone, thus hashCode and equals are final.
+     */
+    @Override
+    public final boolean equals(Object obj) {
+        return super.equals(obj);
+    }
+
+    /**
+     * Provides a {@link Map} of properties of this node for use in debugging (e.g., to view in the ideal graph
+     * visualizer). Subclasses overriding this method should add to the map returned by their superclass.
+     */
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> map = new HashMap<>();
+        map.put("usageCount", usages.size());
+        map.put("predecessorCount", predecessor == null ? 0 : 1);
+        getNodeClass().getDebugProperties(this, map);
+        return map;
+    }
+
+    /**
+     * This method is a shortcut for {@link #toString(Verbosity)} with {@link Verbosity#Short}.
+     */
+    @Override
+    public final String toString() {
+        return toString(Verbosity.Short);
+    }
+
+    public enum Verbosity {
+        /**
+         * Only the id of the node.
+         */
+        Id,
+        /**
+         * Only the name of the node, which may contain some more information for certain node types (constants, ...).
+         */
+        Name,
+        /**
+         * {@link #Id} + {@link #Name}.
+         */
+        Short,
+        /**
+         * Defaults to {@link #Short} and may be enhanced by subclasses.
+         */
+        Long,
+        /**
+         * For use by a custom formatting facility in an IDE.
+         */
+        Debugger,
+        /**
+         * All the other information plus all debug properties of the node.
+         */
+        All
+    }
+
+    /**
+     * Creates a String representation for this node with a given {@link Verbosity}.
+     */
+    public String toString(Verbosity verbosity) {
+        switch (verbosity) {
+            case Id:
+                return Integer.toString(id);
+            case Name:
+                return getNodeClass().shortName();
+            case Short:
+                return toString(Verbosity.Id) + "|" + toString(Verbosity.Name);
+            case Long:
+                return toString(Verbosity.Short);
+            case Debugger:
+            case All: {
+                StringBuilder str = new StringBuilder();
+                str.append(toString(Verbosity.Short)).append(" { ");
+                for (Map.Entry<Object, Object> entry : getDebugProperties().entrySet()) {
+                    str.append(entry.getKey()).append("=").append(entry.getValue()).append(", ");
+                }
+                str.append(" }");
+                return str.toString();
+            }
+            default:
+                throw new RuntimeException("unknown verbosity: " + verbosity);
+        }
+    }
+
+    @Override
+    public void formatTo(Formatter formatter, int flags, int width, int precision) {
+        if ((flags & FormattableFlags.ALTERNATE) == FormattableFlags.ALTERNATE) {
+            formatter.format("%s", toString(Verbosity.Id));
+        } else if ((flags & FormattableFlags.UPPERCASE) == FormattableFlags.UPPERCASE) {
+            formatter.format("%s", toString(Verbosity.Long));
+        } else {
+            formatter.format("%s", toString(Verbosity.Short));
+        }
+
+        boolean neighborsAlternate = ((flags & FormattableFlags.LEFT_JUSTIFY) == FormattableFlags.LEFT_JUSTIFY);
+        int neighborsFlags = (neighborsAlternate ? FormattableFlags.ALTERNATE | FormattableFlags.LEFT_JUSTIFY : 0);
+        if (width > 0) {
+            if (this.predecessor != null) {
+                formatter.format(" pred={");
+                this.predecessor.formatTo(formatter, neighborsFlags, width - 1, 0);
+                formatter.format("}");
+            }
+
+            NodeClassIterator inputIter = inputs().iterator();
+            while (inputIter.hasNext()) {
+                Position position = inputIter.nextPosition();
+                Node input = getNodeClass().get(this, position);
+                if (input != null) {
+                    formatter.format(" ");
+                    formatter.format(getNodeClass().getName(position));
+                    formatter.format("={");
+                    input.formatTo(formatter, neighborsFlags, width - 1, 0);
+                    formatter.format("}");
+                }
+            }
+        }
+
+        if (precision > 0) {
+            if (this.usages.size() > 0) {
+                formatter.format(" usages={");
+                int z = 0;
+                for (Node usage : this.usages) {
+                    if (z != 0) {
+                        formatter.format(", ");
+                    }
+                    usage.formatTo(formatter, neighborsFlags, 0, precision - 1);
+                    ++z;
+                }
+                formatter.format("}");
+            }
+
+            NodeClassIterator succIter = successors().iterator();
+            while (succIter.hasNext()) {
+                Position position = succIter.nextPosition();
+                Node successor = getNodeClass().get(this, position);
+                if (successor != null) {
+                    formatter.format(" ");
+                    formatter.format(getNodeClass().getName(position));
+                    formatter.format("={");
+                    successor.formatTo(formatter, neighborsFlags, 0, precision - 1);
+                    formatter.format("}");
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeBitMap.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.graph;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+
+
+public final class NodeBitMap implements Iterable<Node>{
+
+    private final BitMap bitMap;
+    private final Graph graph;
+
+    public NodeBitMap(Graph graph) {
+        this.graph = graph;
+        bitMap = new BitMap(graph.nodeIdCount());
+    }
+
+    public Graph graph() {
+        return graph;
+    }
+
+    public boolean setIntersect(NodeBitMap other) {
+        return bitMap.setIntersect(other.bitMap);
+    }
+
+    public void setUnion(NodeBitMap other) {
+        bitMap.setUnion(other.bitMap);
+    }
+
+    public void negate() {
+        grow();
+        bitMap.negate();
+    }
+
+    public boolean isNotNewMarked(Node node) {
+        return !isNew(node) && isMarked(node);
+    }
+
+    public boolean isNotNewNotMarked(Node node) {
+        return !isNew(node) && !isMarked(node);
+    }
+
+    public boolean isMarked(Node node) {
+        check(node);
+        return bitMap.get(node.id());
+    }
+
+    public boolean isNew(Node node) {
+        return node.id() >= bitMap.size();
+    }
+
+    public void mark(Node node) {
+        check(node);
+        bitMap.set(node.id());
+    }
+
+    public void clear(Node node) {
+        check(node);
+        bitMap.clear(node.id());
+    }
+
+    public void clearAll() {
+        bitMap.clearAll();
+    }
+
+    public void grow(Node node) {
+        bitMap.grow(node.id() + 1);
+    }
+
+    public void grow() {
+        bitMap.grow(graph.nodeIdCount());
+    }
+
+    private void check(Node node) {
+        assert node.graph() == graph : "this node is not part of the graph";
+        assert !isNew(node) : "this node (" + node.id() + ") was added to the graph after creating the node bitmap (" + bitMap.length() + ")";
+        assert node.isAlive() : "node " + node + " is deleted!";
+    }
+
+    @Override
+    public String toString() {
+        return bitMap.toBinaryString();
+    }
+
+    public <T extends Node> void markAll(Collection<T> nodes) {
+        for (Node node : nodes) {
+            mark(node);
+        }
+    }
+
+    private static class MarkedNodeIterator implements Iterator<Node> {
+        private final NodeBitMap visited;
+        private Iterator<Node> nodes;
+        private Node nextNode;
+
+        public MarkedNodeIterator(NodeBitMap visited, Iterator<Node> nodes) {
+            this.visited = visited;
+            this.nodes = nodes;
+            forward();
+        }
+
+        private void forward() {
+            do {
+                if (!nodes.hasNext()) {
+                    nextNode = null;
+                    return;
+                }
+                nextNode = nodes.next();
+                if (visited.isNew(nextNode)) {
+                    nextNode = null;
+                    return;
+                }
+            } while (!visited.isMarked(nextNode));
+        }
+
+        @Override
+        public boolean hasNext() {
+            return nextNode != null;
+        }
+
+        @Override
+        public Node next() {
+            try {
+                return nextNode;
+            } finally {
+                forward();
+            }
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+    }
+
+    @Override
+    public Iterator<Node> iterator() {
+        return new MarkedNodeIterator(NodeBitMap.this, graph().getNodes().iterator());
+    }
+
+    public int cardinality() {
+        return bitMap.cardinality();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeClass.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,949 @@
+/*
+ * 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.max.graal.graph;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.*;
+import java.util.Map.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.oracle.max.graal.graph.Node.Data;
+
+import sun.misc.Unsafe;
+
+public class NodeClass {
+
+    public static final int NOT_ITERABLE = -1;
+
+    /**
+     * Interface used by {@link NodeClass#rescanAllFieldOffsets(CalcOffset)} to determine the offset (in bytes) of a field.
+     */
+    public interface CalcOffset {
+        long getOffset(Field field);
+    }
+
+    private static final Class< ? > NODE_CLASS = Node.class;
+    private static final Class< ? > INPUT_LIST_CLASS = NodeInputList.class;
+    private static final Class< ? > SUCCESSOR_LIST_CLASS = NodeSuccessorList.class;
+
+    private static final Unsafe unsafe = getUnsafe();
+
+    private static Unsafe getUnsafe() {
+        try {
+            // this will only fail if graal is not part of the boot class path
+            return Unsafe.getUnsafe();
+        } catch (SecurityException e) {
+            // nothing to do
+        }
+        try {
+            Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
+            theUnsafeInstance.setAccessible(true);
+            return (Unsafe) theUnsafeInstance.get(Unsafe.class);
+        } catch (Exception e) {
+            // currently we rely on being able to use Unsafe...
+            throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e);
+        }
+    }
+
+    private static final Map<Class< ? >, NodeClass> nodeClasses = new ConcurrentHashMap<>();
+    private static int nextIterableId = 0;
+
+    private final Class< ? > clazz;
+    private final int directInputCount;
+    private final long[] inputOffsets;
+    private final Class<?>[] inputTypes;
+    private final String[] inputNames;
+    private final int directSuccessorCount;
+    private final long[] successorOffsets;
+    private final Class<?>[] successorTypes;
+    private final String[] successorNames;
+    private final long[] dataOffsets;
+    private final Class<?>[] dataTypes;
+    private final String[] dataNames;
+    private final boolean canGVN;
+    private final int startGVNNumber;
+    private final String shortName;
+    private final int iterableId;
+    private final boolean hasOutgoingEdges;
+
+    static class DefaultCalcOffset implements CalcOffset {
+        @Override
+        public long getOffset(Field field) {
+            return unsafe.objectFieldOffset(field);
+        }
+    }
+
+    public NodeClass(Class< ? > clazz) {
+        assert NODE_CLASS.isAssignableFrom(clazz);
+        this.clazz = clazz;
+
+        FieldScanner scanner = new FieldScanner(new DefaultCalcOffset());
+        scanner.scan(clazz);
+
+        directInputCount = scanner.inputOffsets.size();
+        inputOffsets = sortedLongCopy(scanner.inputOffsets, scanner.inputListOffsets);
+        directSuccessorCount = scanner.successorOffsets.size();
+        successorOffsets = sortedLongCopy(scanner.successorOffsets, scanner.successorListOffsets);
+        dataOffsets = new long[scanner.dataOffsets.size()];
+        for (int i = 0; i < scanner.dataOffsets.size(); ++i) {
+            dataOffsets[i] = scanner.dataOffsets.get(i);
+        }
+        dataTypes = scanner.dataTypes.toArray(new Class[0]);
+        dataNames = scanner.dataNames.toArray(new String[0]);
+        inputTypes = arrayUsingSortedOffsets(scanner.inputTypesMap, inputOffsets, new Class<?>[inputOffsets.length]);
+        inputNames = arrayUsingSortedOffsets(scanner.inputNamesMap, inputOffsets, new String[inputOffsets.length]);
+        successorTypes = arrayUsingSortedOffsets(scanner.successorTypesMap, successorOffsets, new Class<?>[successorOffsets.length]);
+        successorNames = arrayUsingSortedOffsets(scanner.successorNamesMap, successorOffsets, new String[successorOffsets.length]);
+
+        canGVN = Node.ValueNumberable.class.isAssignableFrom(clazz);
+        startGVNNumber = clazz.hashCode();
+
+        String newShortName = clazz.getSimpleName();
+        if (newShortName.endsWith("Node") && !newShortName.equals("StartNode") && !newShortName.equals("EndNode")) {
+            newShortName = newShortName.substring(0, newShortName.length() - 4);
+        }
+        NodeInfo info = clazz.getAnnotation(NodeInfo.class);
+        if (info != null) {
+            if (!info.shortName().isEmpty()) {
+                newShortName = info.shortName();
+            }
+        }
+        this.shortName = newShortName;
+        if (Node.IterableNodeType.class.isAssignableFrom(clazz)) {
+            this.iterableId = nextIterableId++;
+            // TODO(ls) add type hierarchy - based node iteration
+//            for (NodeClass nodeClass : nodeClasses.values()) {
+//                if (clazz.isAssignableFrom(nodeClass.clazz)) {
+//                    throw new UnsupportedOperationException("iterable non-final Node classes not supported: " + clazz);
+//                }
+//            }
+        } else {
+            this.iterableId = NOT_ITERABLE;
+        }
+        this.hasOutgoingEdges = this.inputOffsets.length > 0 || this.successorOffsets.length > 0;
+    }
+
+    public static void rescanAllFieldOffsets(CalcOffset calc) {
+        for (NodeClass nodeClass : nodeClasses.values()) {
+            nodeClass.rescanFieldOffsets(calc);
+        }
+    }
+
+    private void rescanFieldOffsets(CalcOffset calc) {
+        FieldScanner scanner = new FieldScanner(calc);
+        scanner.scan(clazz);
+        assert directInputCount == scanner.inputOffsets.size();
+        copyInto(inputOffsets, sortedLongCopy(scanner.inputOffsets, scanner.inputListOffsets));
+        assert directSuccessorCount == scanner.successorOffsets.size();
+        copyInto(successorOffsets, sortedLongCopy(scanner.successorOffsets, scanner.successorListOffsets));
+        assert dataOffsets.length == scanner.dataOffsets.size();
+        for (int i = 0; i < scanner.dataOffsets.size(); ++i) {
+            dataOffsets[i] = scanner.dataOffsets.get(i);
+        }
+        copyInto(dataTypes, scanner.dataTypes);
+        copyInto(dataNames, scanner.dataNames);
+
+        copyInto(inputTypes, arrayUsingSortedOffsets(scanner.inputTypesMap, this.inputOffsets, new Class<?>[this.inputOffsets.length]));
+        copyInto(inputNames, arrayUsingSortedOffsets(scanner.inputNamesMap, this.inputOffsets, new String[this.inputOffsets.length]));
+        copyInto(successorTypes, arrayUsingSortedOffsets(scanner.successorTypesMap, this.successorOffsets, new Class<?>[this.successorOffsets.length]));
+        copyInto(successorNames, arrayUsingSortedOffsets(scanner.successorNamesMap, this.successorOffsets, new String[this.successorNames.length]));
+    }
+
+    private static void copyInto(long[] dest, long[] src) {
+        assert dest.length == src.length;
+        for (int i = 0; i < dest.length; i++) {
+            dest[i] = src[i];
+        }
+    }
+
+    private static <T> void copyInto(T[] dest, T[] src) {
+        assert dest.length == src.length;
+        for (int i = 0; i < dest.length; i++) {
+            dest[i] = src[i];
+        }
+    }
+
+    private static <T> void copyInto(T[] dest, List<T> src) {
+        assert dest.length == src.size();
+        for (int i = 0; i < dest.length; i++) {
+            dest[i] = src.get(i);
+        }
+    }
+
+    public boolean hasOutgoingEdges() {
+        return hasOutgoingEdges;
+    }
+
+    public String shortName() {
+        return shortName;
+    }
+
+    public int iterableId() {
+        return iterableId;
+    }
+
+    public boolean valueNumberable() {
+        return canGVN;
+    }
+
+    private static synchronized NodeClass getSynchronized(Class< ? > c) {
+        NodeClass clazz = nodeClasses.get(c);
+        if (clazz == null) {
+            clazz = new NodeClass(c);
+            nodeClasses.put(c, clazz);
+        }
+        return clazz;
+    }
+
+    public static final NodeClass get(Class< ? > c) {
+        NodeClass clazz = nodeClasses.get(c);
+        return clazz == null ? getSynchronized(c) : clazz;
+    }
+
+    public static int cacheSize() {
+        return nextIterableId;
+    }
+
+    private static class FieldScanner {
+        public final ArrayList<Long> inputOffsets = new ArrayList<>();
+        public final ArrayList<Long> inputListOffsets = new ArrayList<>();
+        public final Map<Long, Class< ? >> inputTypesMap = new HashMap<>();
+        public final Map<Long, String> inputNamesMap = new HashMap<>();
+        public final ArrayList<Long> successorOffsets = new ArrayList<>();
+        public final ArrayList<Long> successorListOffsets = new ArrayList<>();
+        public final Map<Long, Class< ? >> successorTypesMap = new HashMap<>();
+        public final Map<Long, String> successorNamesMap = new HashMap<>();
+        public final ArrayList<Long> dataOffsets = new ArrayList<>();
+        public final ArrayList<Class< ? >> dataTypes = new ArrayList<>();
+        public final ArrayList<String> dataNames = new ArrayList<>();
+        public final CalcOffset calc;
+
+        public FieldScanner(CalcOffset calc) {
+            this.calc = calc;
+        }
+
+        public void scan(Class< ? > clazz) {
+            Class< ? > currentClazz = clazz;
+            do {
+                for (Field field : currentClazz.getDeclaredFields()) {
+                    if (!Modifier.isStatic(field.getModifiers())) {
+                        Class< ? > type = field.getType();
+                        long offset = calc.getOffset(field);
+                        String name = field.getName();
+                        if (field.isAnnotationPresent(Node.Input.class)) {
+                            assert !field.isAnnotationPresent(Node.Successor.class) : "field cannot be both input and successor";
+                            if (INPUT_LIST_CLASS.isAssignableFrom(type)) {
+                                inputListOffsets.add(offset);
+                            } else {
+                                assert NODE_CLASS.isAssignableFrom(type) : "invalid input type: " + type;
+                                inputOffsets.add(offset);
+                                inputTypesMap.put(offset, type);
+                            }
+                            if (field.getAnnotation(Node.Input.class).notDataflow()) {
+                                inputNamesMap.put(offset, name + "#NDF");
+                            } else {
+                                inputNamesMap.put(offset, name);
+                            }
+                        } else if (field.isAnnotationPresent(Node.Successor.class)) {
+                            if (SUCCESSOR_LIST_CLASS.isAssignableFrom(type)) {
+                                successorListOffsets.add(offset);
+                            } else {
+                                assert NODE_CLASS.isAssignableFrom(type) : "invalid successor type: " + type;
+                                successorOffsets.add(offset);
+                                successorTypesMap.put(offset, type);
+                            }
+                            successorNamesMap.put(offset, name);
+                        } else if (field.isAnnotationPresent(Node.Data.class)) {
+                            dataOffsets.add(offset);
+                            dataTypes.add(type);
+                            dataNames.add(name);
+                        } else {
+                            assert !NODE_CLASS.isAssignableFrom(type) || name.equals("Null") : "suspicious node field: " + field;
+                            assert !INPUT_LIST_CLASS.isAssignableFrom(type) : "suspicious node input list field: " + field;
+                            assert !SUCCESSOR_LIST_CLASS.isAssignableFrom(type) : "suspicious node successor list field: " + field;
+                        }
+                    }
+                }
+                currentClazz = currentClazz.getSuperclass();
+            } while (currentClazz != Node.class);
+        }
+    }
+
+    private static <T> T[] arrayUsingSortedOffsets(Map<Long, T> map, long[] sortedOffsets, T[] result) {
+        for (int i = 0; i < sortedOffsets.length; i++) {
+            result[i] = map.get(sortedOffsets[i]);
+        }
+        return result;
+    }
+
+    private static long[] sortedLongCopy(ArrayList<Long> list1, ArrayList<Long> list2) {
+        Collections.sort(list1);
+        Collections.sort(list2);
+        long[] result = new long[list1.size() + list2.size()];
+        for (int i = 0; i < list1.size(); i++) {
+            result[i] = list1.get(i);
+        }
+        for (int i = 0; i < list2.size(); i++) {
+            result[list1.size() + i] = list2.get(i);
+        }
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder str = new StringBuilder();
+        str.append("NodeClass ").append(clazz.getSimpleName()).append(" [");
+        for (int i = 0; i < inputOffsets.length; i++) {
+            str.append(i == 0 ? "" : ", ").append(inputOffsets[i]);
+        }
+        str.append("] [");
+        for (int i = 0; i < successorOffsets.length; i++) {
+            str.append(i == 0 ? "" : ", ").append(successorOffsets[i]);
+        }
+        str.append("] [");
+        for (int i = 0; i < dataOffsets.length; i++) {
+            str.append(i == 0 ? "" : ", ").append(dataOffsets[i]);
+        }
+        str.append("]");
+        return str.toString();
+    }
+
+    public static final class Position {
+        public final boolean input;
+        public final int index;
+        public final int subIndex;
+
+        public Position(boolean input, int index, int subIndex) {
+            this.input = input;
+            this.index = index;
+            this.subIndex = subIndex;
+        }
+
+        @Override
+        public String toString() {
+            return (input ? "input " : "successor ") + index + "/" + subIndex;
+        }
+
+        public Node get(Node node) {
+            return node.getNodeClass().get(node, this);
+        }
+
+        public void set(Node node, Node value) {
+            node.getNodeClass().set(node, this, value);
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + index;
+            result = prime * result + (input ? 1231 : 1237);
+            result = prime * result + subIndex;
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            Position other = (Position) obj;
+            if (index != other.index) {
+                return false;
+            }
+            if (input != other.input) {
+                return false;
+            }
+            if (subIndex != other.subIndex) {
+                return false;
+            }
+            return true;
+        }
+    }
+
+    private static Node getNode(Node node, long offset) {
+        return (Node) unsafe.getObject(node, offset);
+    }
+
+    @SuppressWarnings("unchecked")
+    private static NodeList<Node> getNodeList(Node node, long offset) {
+        return (NodeList<Node>) unsafe.getObject(node, offset);
+    }
+
+    private static void putNode(Node node, long offset, Node value) {
+        unsafe.putObject(node, offset, value);
+    }
+
+    private static void putNodeList(Node node, long offset, NodeList value) {
+        unsafe.putObject(node, offset, value);
+    }
+
+    /**
+     * An iterator that will iterate over the fields given in {@link offsets}.
+     * The first {@ directCount} offsets are treated as fields of type {@link Node}, while the rest of the fields are treated as {@link NodeList}s.
+     * All elements of these NodeLists will be visited by the iterator as well.
+     * This iterator can be used to iterate over the inputs or successors of a node.
+     *
+     * An iterator of this type will not return null values, unless the field values are modified concurrently.
+     * Concurrent modifications are detected by an assertion on a best-effort basis.
+     */
+    public static final class NodeClassIterator implements Iterator<Node> {
+
+        private final Node node;
+        private final int modCount;
+        private final int directCount;
+        private final long[] offsets;
+        private int index;
+        private int subIndex;
+
+        /**
+         * Creates an iterator that will iterate over fields in the given node.
+         * @param node the node which contains the fields.
+         * @param offsets the offsets of the fields.
+         * @param directCount the number of fields that should be treated as fields of type {@link Node}, the rest are treated as {@link NodeList}s.
+         */
+        private NodeClassIterator(Node node, long[] offsets, int directCount) {
+            this.node = node;
+            this.modCount = node.modCount();
+            this.offsets = offsets;
+            this.directCount = directCount;
+            index = NOT_ITERABLE;
+            subIndex = 0;
+            forward();
+        }
+
+        private void forward() {
+            if (index < directCount) {
+                index++;
+                while (index < directCount) {
+                    Node element = getNode(node, offsets[index]);
+                    if (element != null) {
+                        return;
+                    }
+                    index++;
+                }
+            } else {
+                subIndex++;
+            }
+            while (index < offsets.length) {
+                NodeList<Node> list = getNodeList(node, offsets[index]);
+                while (subIndex < list.size()) {
+                    if (list.get(subIndex) != null) {
+                        return;
+                    }
+                    subIndex++;
+                }
+                subIndex = 0;
+                index++;
+            }
+        }
+
+        private Node nextElement() {
+            if (index < directCount) {
+                return getNode(node, offsets[index]);
+            } else  if (index < offsets.length) {
+                NodeList<Node> list = getNodeList(node, offsets[index]);
+                return list.get(subIndex);
+            }
+            return null;
+        }
+
+        @Override
+        public boolean hasNext() {
+            try {
+                return index < offsets.length;
+            } finally {
+                assert modCount == node.modCount() : "must not be modified";
+            }
+        }
+
+        @Override
+        public Node next() {
+            try {
+                return nextElement();
+            } finally {
+                forward();
+                assert modCount == node.modCount();
+            }
+        }
+
+        public Position nextPosition() {
+            try {
+                if (index < directCount) {
+                    return new Position(offsets == node.getNodeClass().inputOffsets, index, NOT_ITERABLE);
+                } else {
+                    return new Position(offsets == node.getNodeClass().inputOffsets, index, subIndex);
+                }
+            } finally {
+                forward();
+                assert modCount == node.modCount();
+            }
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    public int valueNumber(Node n) {
+        int number = 0;
+        if (canGVN) {
+            number = startGVNNumber;
+            for (int i = 0; i < dataOffsets.length; ++i) {
+                Class<?> type = dataTypes[i];
+                if (type.isPrimitive()) {
+                    if (type == Integer.TYPE) {
+                        int intValue = unsafe.getInt(n, dataOffsets[i]);
+                        number += intValue;
+                    } else if (type == Boolean.TYPE) {
+                        boolean booleanValue = unsafe.getBoolean(n, dataOffsets[i]);
+                        if (booleanValue) {
+                            number += 7;
+                        }
+                    } else {
+                        assert false;
+                    }
+                } else {
+                    Object o = unsafe.getObject(n, dataOffsets[i]);
+                    if (o != null) {
+                        number += o.hashCode();
+                    }
+                }
+                number *= 13;
+            }
+        }
+        return number;
+    }
+
+    /**
+     * Populates a given map with the names and values of all fields marked with @{@link Data}.
+     * @param node the node from which to take the values.
+     * @param properties a map that will be populated.
+     */
+    public void getDebugProperties(Node node, Map<Object, Object> properties) {
+        for (int i = 0; i < dataOffsets.length; ++i) {
+            Class<?> type = dataTypes[i];
+            Object value = null;
+            if (type.isPrimitive()) {
+                if (type == Integer.TYPE) {
+                    value = unsafe.getInt(node, dataOffsets[i]);
+                } else if (type == Boolean.TYPE) {
+                    value = unsafe.getBoolean(node, dataOffsets[i]);
+                } else {
+                    assert false;
+                }
+            } else {
+                value = unsafe.getObject(node, dataOffsets[i]);
+            }
+            properties.put("data." + dataNames[i], value);
+        }
+    }
+
+    public boolean valueEqual(Node a, Node b) {
+        if (!canGVN || a.getNodeClass() != b.getNodeClass()) {
+            return a == b;
+        }
+        for (int i = 0; i < dataOffsets.length; ++i) {
+            Class<?> type = dataTypes[i];
+            if (type.isPrimitive()) {
+                if (type == Integer.TYPE) {
+                    int aInt = unsafe.getInt(a, dataOffsets[i]);
+                    int bInt = unsafe.getInt(b, dataOffsets[i]);
+                    if (aInt != bInt) {
+                        return false;
+                    }
+                } else if (type == Boolean.TYPE) {
+                    boolean aBoolean = unsafe.getBoolean(a, dataOffsets[i]);
+                    boolean bBoolean = unsafe.getBoolean(b, dataOffsets[i]);
+                    if (aBoolean != bBoolean) {
+                        return false;
+                    }
+                } else {
+                    assert false;
+                }
+            } else {
+                Object objectA = unsafe.getObject(a, dataOffsets[i]);
+                Object objectB = unsafe.getObject(b, dataOffsets[i]);
+                if (objectA != objectB) {
+                    if (objectA != null && objectB != null) {
+                        if (!(objectA.equals(objectB))) {
+                            return false;
+                        }
+                    } else {
+                        return false;
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
+    public Node get(Node node, Position pos) {
+        long offset = pos.input ? inputOffsets[pos.index] : successorOffsets[pos.index];
+        if (pos.subIndex == NOT_ITERABLE) {
+            return getNode(node, offset);
+        } else {
+            return getNodeList(node, offset).get(pos.subIndex);
+        }
+    }
+
+    public String getName(Position pos) {
+        return pos.input ? inputNames[pos.index] : successorNames[pos.index];
+    }
+
+    private void set(Node node, Position pos, Node x) {
+        long offset = pos.input ? inputOffsets[pos.index] : successorOffsets[pos.index];
+        if (pos.subIndex == NOT_ITERABLE) {
+            Node old = getNode(node,  offset);
+            assert x == null || (pos.input ? inputTypes : successorTypes)[pos.index].isAssignableFrom(x.getClass()) : this + ".set(node, pos, " + x + ") while type is " + (pos.input ? inputTypes : successorTypes)[pos.index];
+            putNode(node, offset, x);
+            if (pos.input) {
+                node.updateUsages(old, x);
+            } else {
+                node.updatePredecessors(old, x);
+            }
+        } else {
+            NodeList<Node> list = getNodeList(node, offset);
+            if (pos.subIndex < list.size()) {
+                list.set(pos.subIndex, x);
+            } else {
+                while (pos.subIndex < list.size() - 1) {
+                    list.add(null);
+                }
+                list.add(x);
+            }
+        }
+    }
+
+    public NodeInputsIterable getInputIterable(final Node node) {
+        assert clazz.isInstance(node);
+        return new NodeInputsIterable() {
+
+            @Override
+            public NodeClassIterator iterator() {
+                return new NodeClassIterator(node, inputOffsets, directInputCount);
+            }
+
+            @Override
+            public boolean contains(Node other) {
+                return inputContains(node, other);
+            }
+        };
+    }
+
+    public NodeSuccessorsIterable getSuccessorIterable(final Node node) {
+        assert clazz.isInstance(node);
+        return new NodeSuccessorsIterable() {
+            @Override
+            public NodeClassIterator iterator() {
+                return new NodeClassIterator(node, successorOffsets, directSuccessorCount);
+            }
+
+            @Override
+            public boolean contains(Node other) {
+                return successorContains(node, other);
+            }
+        };
+    }
+
+    public boolean replaceFirstInput(Node node, Node old, Node other) {
+        int index = 0;
+        while (index < directInputCount) {
+            Node input = getNode(node, inputOffsets[index]);
+            if (input == old) {
+                assert other == null || inputTypes[index].isAssignableFrom(other.getClass());
+                putNode(node, inputOffsets[index], other);
+                return true;
+            }
+            index++;
+        }
+        while (index < inputOffsets.length) {
+            NodeList<Node> list = getNodeList(node, inputOffsets[index]);
+            assert list != null : clazz;
+            if (list.replaceFirst(old, other)) {
+                return true;
+            }
+            index++;
+        }
+        return false;
+    }
+
+    public boolean replaceFirstSuccessor(Node node, Node old, Node other) {
+        int index = 0;
+        while (index < directSuccessorCount) {
+            Node successor = getNode(node, successorOffsets[index]);
+            if (successor == old) {
+                assert other == null || successorTypes[index].isAssignableFrom(other.getClass()) : successorTypes[index] + " is not compatible with " + other.getClass();
+                putNode(node, successorOffsets[index], other);
+                return true;
+            }
+            index++;
+        }
+        while (index < successorOffsets.length) {
+            NodeList<Node> list = getNodeList(node, successorOffsets[index]);
+            assert list != null : clazz + " " + successorOffsets[index] + " " + node;
+            if (list.replaceFirst(old, other)) {
+                return true;
+            }
+            index++;
+        }
+        return false;
+    }
+
+    /**
+     * Clear all inputs in the given node. This is accomplished by setting input fields to null and replacing input lists with new lists.
+     * (which is important so that this method can be used to clear the inputs of cloned nodes.)
+     * @param node the node to be cleared
+     */
+    public void clearInputs(Node node) {
+        int index = 0;
+        while (index < directInputCount) {
+            putNode(node, inputOffsets[index++], null);
+        }
+        while (index < inputOffsets.length) {
+            long curOffset = inputOffsets[index++];
+            int size = (getNodeList(node, curOffset)).initialSize;
+            // replacing with a new list object is the expected behavior!
+            putNodeList(node, curOffset, new NodeInputList<>(node, size));
+        }
+    }
+
+    /**
+     * Clear all successors in the given node. This is accomplished by setting successor fields to null and replacing successor lists with new lists.
+     * (which is important so that this method can be used to clear the successors of cloned nodes.)
+     * @param node the node to be cleared
+     */
+    public void clearSuccessors(Node node) {
+        int index = 0;
+        while (index < directSuccessorCount) {
+            putNode(node, successorOffsets[index++], null);
+        }
+        while (index < successorOffsets.length) {
+            long curOffset = successorOffsets[index++];
+            int size = getNodeList(node, curOffset).initialSize;
+            // replacing with a new list object is the expected behavior!
+            putNodeList(node, curOffset, new NodeSuccessorList<>(node, size));
+        }
+    }
+
+    /**
+     * Copies the inputs from node to newNode. The nodes are expected to be of the exact same NodeClass type.
+     * @param node the node from which the inputs should be copied.
+     * @param newNode the node to which the inputs should be copied.
+     */
+    public void copyInputs(Node node, Node newNode) {
+        assert node.getClass() == clazz && newNode.getClass() == clazz;
+
+        int index = 0;
+        while (index < directInputCount) {
+            putNode(newNode, inputOffsets[index], getNode(node, inputOffsets[index]));
+            index++;
+        }
+        while (index < inputOffsets.length) {
+            NodeList<Node> list = getNodeList(newNode, inputOffsets[index]);
+            list.copy(getNodeList(node, inputOffsets[index]));
+            index++;
+        }
+    }
+
+    /**
+     * Copies the successors from node to newNode. The nodes are expected to be of the exact same NodeClass type.
+     * @param node the node from which the successors should be copied.
+     * @param newNode the node to which the successors should be copied.
+     */
+    public void copySuccessors(Node node, Node newNode) {
+        assert node.getClass() == clazz && newNode.getClass() == clazz;
+
+        int index = 0;
+        while (index < directSuccessorCount) {
+            putNode(newNode, successorOffsets[index], getNode(node, successorOffsets[index]));
+            index++;
+        }
+        while (index < successorOffsets.length) {
+            NodeList<Node> list = getNodeList(newNode, successorOffsets[index]);
+            list.copy(getNodeList(node, successorOffsets[index]));
+            index++;
+        }
+    }
+
+    public boolean edgesEqual(Node node, Node other) {
+        assert node.getClass() == clazz && other.getClass() == clazz;
+
+        int index = 0;
+        while (index < directInputCount) {
+            if (getNode(other, inputOffsets[index]) != getNode(node, inputOffsets[index])) {
+                return false;
+            }
+            index++;
+        }
+        while (index < inputOffsets.length) {
+            NodeList<Node> list = getNodeList(other, inputOffsets[index]);
+            if (!list.equals(getNodeList(node, inputOffsets[index]))) {
+                return false;
+            }
+            index++;
+        }
+
+        index = 0;
+        while (index < directSuccessorCount) {
+            if (getNode(other, successorOffsets[index]) != getNode(node, successorOffsets[index])) {
+                return false;
+            }
+            index++;
+        }
+        while (index < successorOffsets.length) {
+            NodeList<Node> list = getNodeList(other, successorOffsets[index]);
+            if (!list.equals(getNodeList(node, successorOffsets[index]))) {
+                return false;
+            }
+            index++;
+        }
+        return true;
+    }
+
+    public boolean inputContains(Node node, Node other) {
+        assert node.getClass() == clazz;
+
+        int index = 0;
+        while (index < directInputCount) {
+            if (getNode(node, inputOffsets[index]) == other) {
+                return true;
+            }
+            index++;
+        }
+        while (index < inputOffsets.length) {
+            NodeList<Node> list = getNodeList(node, inputOffsets[index]);
+            if (list.contains(other)) {
+                return true;
+            }
+            index++;
+        }
+        return false;
+    }
+
+    public boolean successorContains(Node node, Node other) {
+        assert node.getClass() == clazz;
+
+        int index = 0;
+        while (index < directSuccessorCount) {
+            if (getNode(node, successorOffsets[index]) == other) {
+                return true;
+            }
+            index++;
+        }
+        while (index < successorOffsets.length) {
+            NodeList<Node> list = getNodeList(node, successorOffsets[index]);
+            if (list.contains(other)) {
+                return true;
+            }
+            index++;
+        }
+        return false;
+    }
+
+    public int directInputCount() {
+        return directInputCount;
+    }
+
+    public int directSuccessorCount() {
+        return directSuccessorCount;
+    }
+
+    static Map<Node, Node> addGraphDuplicate(Graph graph, Iterable<Node> nodes, Map<Node, Node> replacements) {
+        Map<Node, Node> newNodes = new IdentityHashMap<>();
+        // create node duplicates
+        for (Node node : nodes) {
+            if (node != null && !replacements.containsKey(node)) {
+                assert !node.isDeleted() : "trying to duplicate deleted node";
+                Node newNode = node.clone(graph);
+                assert newNode.getClass() == node.getClass();
+                newNodes.put(node, newNode);
+            }
+        }
+        // re-wire inputs
+        for (Entry<Node, Node> entry : newNodes.entrySet()) {
+            Node oldNode = entry.getKey();
+            Node node = entry.getValue();
+            for (NodeClassIterator iter = oldNode.inputs().iterator(); iter.hasNext();) {
+                Position pos = iter.nextPosition();
+                Node input = oldNode.getNodeClass().get(oldNode, pos);
+                Node target = replacements.get(input);
+                if (target == null) {
+                    target = newNodes.get(input);
+                }
+                node.getNodeClass().set(node, pos, target);
+            }
+        }
+        for (Entry<Node, Node> entry : replacements.entrySet()) {
+            Node oldNode = entry.getKey();
+            Node node = entry.getValue();
+            if (oldNode == node) {
+                continue;
+            }
+            for (NodeClassIterator iter = oldNode.inputs().iterator(); iter.hasNext();) {
+                Position pos = iter.nextPosition();
+                Node input = oldNode.getNodeClass().get(oldNode, pos);
+                if (newNodes.containsKey(input)) {
+                    node.getNodeClass().set(node, pos, newNodes.get(input));
+                }
+            }
+        }
+
+        // re-wire successors
+        for (Entry<Node, Node> entry : newNodes.entrySet()) {
+            Node oldNode = entry.getKey();
+            Node node = entry.getValue();
+            for (NodeClassIterator iter = oldNode.successors().iterator(); iter.hasNext();) {
+                Position pos = iter.nextPosition();
+                Node succ = oldNode.getNodeClass().get(oldNode, pos);
+                Node target = replacements.get(succ);
+                if (target == null) {
+                    target = newNodes.get(succ);
+                }
+                node.getNodeClass().set(node, pos, target);
+            }
+        }
+        for (Entry<Node, Node> entry : replacements.entrySet()) {
+            Node oldNode = entry.getKey();
+            Node node = entry.getValue();
+            if (oldNode == node) {
+                continue;
+            }
+            for (NodeClassIterator iter = oldNode.successors().iterator(); iter.hasNext();) {
+                Position pos = iter.nextPosition();
+                Node succ = oldNode.getNodeClass().get(oldNode, pos);
+                if (newNodes.containsKey(succ)) {
+                    node.getNodeClass().set(node, pos, newNodes.get(succ));
+                }
+            }
+        }
+        return newNodes;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeFlood.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.graph;
+
+import java.util.ArrayDeque;
+import java.util.Iterator;
+import java.util.Queue;
+
+
+public class NodeFlood implements Iterable<Node> {
+    private final NodeBitMap visited;
+    private final Queue<Node> worklist;
+
+    public NodeFlood(Graph graph) {
+        visited = graph.createNodeBitMap();
+        worklist = new ArrayDeque<>();
+    }
+
+    public void add(Node node) {
+        if (node != null && !visited.isMarked(node)) {
+            visited.mark(node);
+            worklist.add(node);
+        }
+    }
+
+    public void addAll(Iterable<Node> nodes) {
+        for (Node node : nodes) {
+            this.add(node);
+        }
+    }
+
+    public boolean isMarked(Node node) {
+        return visited.isMarked(node);
+    }
+
+    public boolean isNew(Node node) {
+        return visited.isNew(node);
+    }
+
+    private static class QueueConsumingIterator implements Iterator<Node> {
+        private final Queue<Node> queue;
+
+        public QueueConsumingIterator(Queue<Node> queue) {
+            this.queue = queue;
+        }
+
+        @Override
+        public boolean hasNext() {
+            return !queue.isEmpty();
+        }
+
+        @Override
+        public Node next() {
+            return queue.remove();
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    @Override
+    public Iterator<Node> iterator() {
+        return new QueueConsumingIterator(worklist);
+    }
+
+    private static class UnmarkedNodeIterator implements Iterator<Node> {
+        private final NodeBitMap visited;
+        private Iterator<Node> nodes;
+        private Node nextNode;
+
+        public UnmarkedNodeIterator(NodeBitMap visited, Iterator<Node> nodes) {
+            this.visited = visited;
+            this.nodes = nodes;
+            forward();
+        }
+
+        private void forward() {
+            do {
+                if (!nodes.hasNext()) {
+                    nextNode = null;
+                    return;
+                }
+                nextNode = nodes.next();
+            } while (visited.isMarked(nextNode));
+        }
+
+        @Override
+        public boolean hasNext() {
+            return nextNode != null;
+        }
+
+        @Override
+        public Node next() {
+            try {
+                return nextNode;
+            } finally {
+                forward();
+            }
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    public Iterable<Node> unmarkedNodes() {
+        return new Iterable<Node>() {
+            @Override
+            public Iterator<Node> iterator() {
+                return new UnmarkedNodeIterator(visited, visited.graph().getNodes().iterator());
+            }
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeInfo.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,35 @@
+/*
+ * 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.max.graal.graph;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface NodeInfo {
+    String shortName() default "";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeInputList.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,94 @@
+/*
+ * 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.max.graal.graph;
+
+import java.util.*;
+
+
+public final class NodeInputList<T extends Node> extends NodeList<T> {
+
+    private final Node self;
+
+    public NodeInputList(Node self, int initialSize) {
+        super(initialSize);
+        this.self = self;
+    }
+
+    public NodeInputList(Node self) {
+        this.self = self;
+    }
+
+    public NodeInputList(Node self, T[] elements) {
+        super(elements);
+        assert self.usages() == null;
+        this.self = self;
+    }
+
+    public NodeInputList(Node self, List<? extends T> elements) {
+        super(elements);
+        assert self.usages() == null;
+        this.self = self;
+    }
+
+    @Override
+    protected void update(T oldNode, T newNode) {
+        self.updateUsages(oldNode, newNode);
+    }
+
+    @Override
+    public boolean add(T node) {
+        assert !node.isDeleted();
+        self.incModCount();
+        return super.add(node);
+    }
+
+    @Override
+    public T remove(int index) {
+        self.incModCount();
+        return super.remove(index);
+    }
+
+    @Override
+    public boolean remove(Object node) {
+        self.incModCount();
+        return super.remove(node);
+    }
+
+    @Override
+    public void clear() {
+        self.incModCount();
+        super.clear();
+    }
+
+    @Override
+    void copy(NodeList<T> other) {
+        self.incModCount();
+        super.copy(other);
+    }
+
+    @Override
+    public void setAll(NodeList<T> values) {
+        self.incModCount();
+        super.setAll(values);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeInputsIterable.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,31 @@
+/*
+ * 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.max.graal.graph;
+
+import com.oracle.max.graal.graph.NodeClass.NodeClassIterator;
+import com.oracle.max.graal.graph.iterators.*;
+
+public abstract class NodeInputsIterable extends NodeIterable<Node> {
+    @Override
+    public abstract NodeClassIterator iterator();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeList.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,368 @@
+/*
+ * 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.max.graal.graph;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import com.oracle.max.graal.graph.iterators.*;
+
+public abstract class NodeList<T extends Node> extends NodeIterable<T> implements List<T> {
+
+    protected static final Node[] EMPTY_NODE_ARRAY = new Node[0];
+
+    protected Node[] nodes;
+    private int size;
+    private int modCount;
+    protected final int initialSize;
+
+    protected NodeList() {
+        this.nodes = EMPTY_NODE_ARRAY;
+        this.initialSize = 0;
+    }
+
+    protected NodeList(int initialSize) {
+        this.size = initialSize;
+        this.initialSize = initialSize;
+        this.nodes = new Node[initialSize];
+    }
+
+    protected NodeList(T[] elements) {
+        if (elements == null) {
+            this.size = 0;
+            this.nodes = EMPTY_NODE_ARRAY;
+            this.initialSize = 0;
+        } else {
+            this.size = elements.length;
+            this.initialSize = elements.length;
+            this.nodes = new Node[elements.length];
+            for (int i = 0; i < elements.length; i++) {
+                this.nodes[i] = elements[i];
+            }
+        }
+    }
+
+    protected NodeList(List<? extends T> elements) {
+        if (elements == null || elements.isEmpty()) {
+            this.size = 0;
+            this.nodes = EMPTY_NODE_ARRAY;
+            this.initialSize = 0;
+        } else {
+            this.size = elements.size();
+            this.initialSize = elements.size();
+            this.nodes = new Node[elements.size()];
+            for (int i = 0; i < elements.size(); i++) {
+                this.nodes[i] = elements.get(i);
+            }
+        }
+    }
+
+    protected abstract void update(T oldNode, T newNode);
+
+    @Override
+    public final int size() {
+        return size;
+    }
+
+    @Override
+    public final boolean isEmpty() {
+        return size == 0;
+    }
+
+    @Override
+    public boolean isNotEmpty() {
+        return size > 0;
+    }
+
+    @Override
+    public int count() {
+        return size;
+    }
+
+    protected final void incModCount() {
+        modCount++;
+    }
+
+    @Override
+    public boolean add(T node) {
+        incModCount();
+        if (size == nodes.length) {
+            nodes = Arrays.copyOf(nodes, nodes.length * 2 + 1);
+        }
+        nodes[size++] = node;
+        update(null, node);
+        return true;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public T get(int index) {
+        assert index < size() : index + " < " + size();
+        return (T) nodes[index];
+    }
+
+    public T last() {
+        return get(size() - 1);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public T set(int index, T node) {
+        incModCount();
+        T oldValue = (T) nodes[index];
+        assert index < size();
+        update((T) nodes[index], node);
+        nodes[index] = node;
+        return oldValue;
+    }
+
+    void copy(NodeList<T> other) {
+        incModCount();
+        nodes = Arrays.copyOf(other.nodes, other.size);
+        size = other.size;
+    }
+
+    public boolean equals(NodeList<T> other) {
+        if (size != other.size) {
+            return false;
+        }
+        for (int i = 0; i < size; i++) {
+            if (nodes[i] != other.nodes[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void clear() {
+        incModCount();
+        for (int i = 0; i < size; i++) {
+            update((T) nodes[i], null);
+        }
+        nodes = EMPTY_NODE_ARRAY;
+        size = 0;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public boolean remove(Object node) {
+        int i = 0;
+        incModCount();
+        while (i < size && nodes[i] != node) {
+            i++;
+        }
+        if (i < size) {
+            T oldValue = (T) nodes[i];
+            i++;
+            while (i < size) {
+                nodes[i - 1] = nodes[i];
+                i++;
+            }
+            nodes[--size] = null;
+            update(oldValue, null);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public T remove(int index) {
+        T oldValue = (T) nodes[index];
+        int i = index + 1;
+        incModCount();
+        while (i < size) {
+            nodes[i - 1] = nodes[i];
+            i++;
+        }
+        nodes[--size] = null;
+        update(oldValue, null);
+        return oldValue;
+    }
+
+    boolean replaceFirst(Node node, Node other) {
+        for (int i = 0; i < size; i++) {
+            if (nodes[i] == node) {
+                nodes[i] = other;
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public Iterator<T> iterator() {
+        return new Iterator<T>() {
+            private final int expectedModCount = NodeList.this.modCount;
+            private int index = 0;
+
+            @Override
+            public boolean hasNext() {
+                assert expectedModCount == NodeList.this.modCount;
+                return index < NodeList.this.size;
+            }
+
+            @SuppressWarnings("unchecked")
+            @Override
+            public T next() {
+                assert expectedModCount == NodeList.this.modCount;
+                return (T) NodeList.this.nodes[index++];
+            }
+
+            @Override
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    @Override
+    public boolean contains(T other) {
+        for (int i = 0; i < size; i++) {
+            if (nodes[i] == other) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public List<T> snapshot() {
+        return (List<T>) Arrays.asList(Arrays.copyOf(this.nodes, this.size));
+    }
+
+    @SuppressWarnings("unchecked")
+    public void setAll(NodeList<T> values) {
+        incModCount();
+        for (int i = 0; i < size(); i++) {
+            update((T) nodes[i], null);
+        }
+        nodes = Arrays.copyOf(values.nodes, values.size());
+        size = values.size();
+
+        for (int i = 0; i < size(); i++) {
+            update(null, (T) nodes[i]);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <A> A[] toArray(A[] template) {
+        return (A[]) Arrays.copyOf(nodes, size, template.getClass());
+    }
+
+    @Override
+    public Object[] toArray() {
+        return Arrays.copyOf(nodes, size);
+    }
+
+    protected void replace(T node, T other) {
+        incModCount();
+        for (int i = 0; i < size(); i++) {
+            if (nodes[i] == node) {
+                nodes[i] = other;
+                update(node, other);
+            }
+        }
+    }
+
+    @Override
+    public int indexOf(Object node) {
+        for (int i = 0; i < size; i++) {
+            if (nodes[i] == node) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+
+    @Override
+    public boolean contains(Object o) {
+        return indexOf(o) != -1;
+    }
+
+    @Override
+    public boolean containsAll(Collection< ? > c) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public boolean addAll(Collection< ? extends T> c) {
+        for (T e : c) {
+            add(e);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean addAll(int index, Collection< ? extends T> c) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public boolean removeAll(Collection< ? > c) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public boolean retainAll(Collection< ? > c) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public void add(int index, T element) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public int lastIndexOf(Object o) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public ListIterator<T> listIterator() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public ListIterator<T> listIterator(int index) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public List<T> subList(int fromIndex, int toIndex) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public String toString() {
+        return Arrays.toString(nodes);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeMap.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.graph;
+
+import java.util.AbstractMap.SimpleEntry;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+
+public final class NodeMap<T> {
+    private final Graph graph;
+    private Object[] values;
+    private int size;
+
+    public NodeMap(Graph graph) {
+        this.graph = graph;
+        values = new Object[graph.nodeIdCount()];
+        size = values.length;
+    }
+
+    @SuppressWarnings("unchecked")
+    public T get(Node node) {
+        check(node);
+        return (T) values[node.id()];
+    }
+
+    public Graph graph() {
+        return graph;
+    }
+
+    public void set(Node node, T value) {
+        check(node);
+        values[node.id()] = value;
+    }
+
+    public int size() {
+        return size;
+    }
+
+    public boolean isNew(Node node) {
+        return node.id() >= size;
+    }
+
+    public void grow(Node upTo) {
+        if (isNew(upTo)) {
+            size = upTo.id() + 1;
+            if (values.length < size) {
+                values = Arrays.copyOf(values, size + 9); // TODO implement a better growth policy
+            }
+        }
+    }
+
+    private void check(Node node) {
+        assert node.graph() == graph : "this node is not part of the graph";
+        assert !isNew(node) : "this node was added to the graph after creating the node map : " + node;
+    }
+
+    public Iterable<Entry<Node, T>> entries() {
+        return new Iterable<Entry<Node, T>>() {
+            @Override
+            public Iterator<Entry<Node, T>> iterator() {
+                return new Iterator<Entry<Node, T>>() {
+                    int i = 0;
+                    @Override
+                    public boolean hasNext() {
+                        forward();
+                        return i < NodeMap.this.values.length;
+                    }
+
+                    @SuppressWarnings("unchecked")
+                    @Override
+                    public Entry<Node, T> next() {
+                        final int pos = i;
+                        Node key = NodeMap.this.graph.getNode(pos);
+                        T value = (T) NodeMap.this.values[pos];
+                        i++;
+                        forward();
+                        return new SimpleEntry<Node, T>(key, value){
+                            private static final long serialVersionUID = 7813842391085737738L;
+                            @Override
+                            public T setValue(T v) {
+                                T oldv = super.setValue(v);
+                                NodeMap.this.values[pos] = v;
+                                return oldv;
+                            }
+                        };
+                    }
+
+                    @Override
+                    public void remove() {
+                        throw new UnsupportedOperationException();
+                    }
+
+                    private void forward() {
+                        while (i < NodeMap.this.values.length && (NodeMap.this.graph.getNode(i) == null || NodeMap.this.values[i] == null)) {
+                            i++;
+                        }
+                    }
+                };
+            }
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeSuccessorList.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * 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.max.graal.graph;
+
+public final class NodeSuccessorList<T extends Node> extends NodeList<T> {
+
+    private final Node self;
+
+    public NodeSuccessorList(Node self, int initialSize) {
+        super(initialSize);
+        this.self = self;
+    }
+
+    protected NodeSuccessorList(Node self) {
+        this.self = self;
+    }
+
+    public NodeSuccessorList(Node self, T[] elements) {
+        super(elements);
+        assert self.usages() == null;
+        this.self = self;
+    }
+
+    @Override
+    protected void update(T oldNode, T newNode) {
+        self.updatePredecessors(oldNode, newNode);
+    }
+
+    @Override
+    public boolean add(T node) {
+        self.incModCount();
+        return super.add(node);
+    }
+
+    @Override
+    public T remove(int index) {
+        self.incModCount();
+        return super.remove(index);
+    }
+
+    @Override
+    public boolean remove(Object node) {
+        self.incModCount();
+        return super.remove(node);
+    }
+
+    @Override
+    public void clear() {
+        self.incModCount();
+        super.clear();
+    }
+
+    @Override
+    void copy(NodeList<T> other) {
+        self.incModCount();
+        super.copy(other);
+    }
+
+    @Override
+    public void setAll(NodeList<T> values) {
+        self.incModCount();
+        super.setAll(values);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeSuccessorsIterable.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,31 @@
+/*
+ * 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.max.graal.graph;
+
+import com.oracle.max.graal.graph.NodeClass.NodeClassIterator;
+import com.oracle.max.graal.graph.iterators.*;
+
+public abstract class NodeSuccessorsIterable extends NodeIterable<Node> {
+    @Override
+    public abstract NodeClassIterator iterator();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeUsagesList.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,176 @@
+/*
+ * 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.max.graal.graph;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.iterators.*;
+
+public final class NodeUsagesList extends NodeIterable<Node> {
+
+    protected static final Node[] EMPTY_NODE_ARRAY = new Node[0];
+
+    protected Node[] nodes = EMPTY_NODE_ARRAY;
+    private int size;
+    private int modCount;
+
+    NodeUsagesList() {
+        this.size = 0;
+        this.nodes = EMPTY_NODE_ARRAY;
+    }
+
+    NodeUsagesList(Node[] nodes) {
+        this.size = nodes.length;
+        this.nodes = nodes;
+    }
+
+    public int size() {
+        return size;
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return size == 0;
+    }
+
+    @Override
+    public boolean isNotEmpty() {
+        return size > 0;
+    }
+
+    @Override
+    public int count() {
+        return size;
+    }
+
+    protected void incModCount() {
+        modCount++;
+    }
+
+    public boolean add(Node node) {
+        incModCount();
+        if (size == nodes.length) {
+            nodes = Arrays.copyOf(nodes, nodes.length * 2 + 1);
+        }
+        nodes[size++] = node;
+        return true;
+    }
+
+    void copyAndClear(NodeUsagesList other) {
+        incModCount();
+        other.incModCount();
+        nodes = other.nodes;
+        size = other.size;
+        nodes = EMPTY_NODE_ARRAY;
+        size = 0;
+    }
+
+    public void clear() {
+        incModCount();
+        nodes = EMPTY_NODE_ARRAY;
+        size = 0;
+    }
+
+    boolean remove(Node node) {
+        int i = 0;
+        incModCount();
+        while (i < size && nodes[i] != node) {
+            i++;
+        }
+        if (i < size) {
+            i++;
+            while (i < size) {
+                nodes[i - 1] = nodes[i];
+                i++;
+            }
+            nodes[--size] = null;
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    boolean replaceFirst(Node node, Node other) {
+        for (int i = 0; i < size; i++) {
+            if (nodes[i] == node) {
+                nodes[i] = other;
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public Iterator<Node> iterator() {
+        return new Iterator<Node>() {
+            private final int expectedModCount = NodeUsagesList.this.modCount;
+            private int index = 0;
+
+            @Override
+            public boolean hasNext() {
+                assert expectedModCount == NodeUsagesList.this.modCount;
+                return index < NodeUsagesList.this.size;
+            }
+
+            @Override
+            public Node next() {
+                assert expectedModCount == NodeUsagesList.this.modCount;
+                return NodeUsagesList.this.nodes[index++];
+            }
+
+            @Override
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    @Override
+    public boolean contains(Node other) {
+        for (int i = 0; i < size; i++) {
+            if (nodes[i] == other) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public List<Node> snapshot() {
+        return Arrays.asList(Arrays.copyOf(NodeUsagesList.this.nodes, NodeUsagesList.this.size));
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder str = new StringBuilder();
+        str.append('[');
+        for (int i = 0; i < size; i++) {
+            if (i > 0) {
+                str.append(", ");
+            }
+            str.append(nodes[i]);
+        }
+        str.append(']');
+        return str.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeWorkList.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.graph;
+
+import java.util.ArrayDeque;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+
+public class NodeWorkList implements Iterable<Node> {
+    private final NodeBitMap visited;
+    private final NodeBitMap inQueue;
+    private final Queue<Node> worklist;
+    private int iterationLimit = Integer.MAX_VALUE;
+    private Node firstNoChange;
+    private Node lastPull;
+    private Node lastChain;
+
+    public NodeWorkList(Graph graph) {
+        this(graph, false, -1);
+    }
+
+    public NodeWorkList(Graph graph, boolean fill, int iterationLimitPerNode) {
+        visited = graph.createNodeBitMap();
+        inQueue = graph.createNodeBitMap();
+        if (fill) {
+            ArrayDeque<Node> deque = new ArrayDeque<>(graph.getNodeCount());
+            for (Node node : graph.getNodes()) {
+                deque.add(node);
+            }
+            worklist = deque;
+        } else {
+            worklist = new ArrayDeque<>();
+        }
+        if (iterationLimitPerNode > 0) {
+            iterationLimit = iterationLimitPerNode * graph.getNodeCount();
+        }
+    }
+
+    public void addAll(Iterable<? extends Node> nodes) {
+        for (Node node : nodes) {
+            this.add(node);
+        }
+    }
+
+    public void add(Node node) {
+        if (node != null) {
+            if (visited.isNew(node)) {
+                visited.grow(node);
+                inQueue.grow(node);
+            }
+            if (!visited.isMarked(node)) {
+                addAgain(node);
+            }
+        }
+    }
+
+    public void addAgain(Node node) {
+        if (visited.isNew(node)) {
+            visited.grow(node);
+            inQueue.grow(node);
+        }
+        if (node != null && !inQueue.isMarked(node)) {
+            if (lastPull == node) {
+                if (firstNoChange == null) {
+                    firstNoChange = node;
+                    lastChain = node;
+                } else if (node == firstNoChange) {
+                    throw new InfiniteWorkException("ReAdded " + node);
+                } else {
+                    lastChain = node;
+                }
+            } else {
+                firstNoChange = null;
+            }
+            visited.mark(node);
+            inQueue.mark(node);
+            worklist.add(node);
+        }
+    }
+
+    public void clearVisited() {
+        visited.clearAll();
+    }
+
+    public void replaced(Node newNode, Node oldNode) {
+        this.replaced(newNode, oldNode, false);
+    }
+
+    public void replaced(Node newNode, Node oldNode, boolean add) {
+        worklist.remove(oldNode);
+        if (newNode == null) {
+            return;
+        }
+        if (add) {
+            this.add(newNode);
+        }
+        for (Node n : newNode.usages()) {
+            addAgain(n);
+        }
+    }
+
+    public boolean isMarked(Node node) {
+        return visited.isMarked(node);
+    }
+
+    public boolean isNew(Node node) {
+        return visited.isNew(node);
+    }
+
+    public boolean isEmpty() {
+        return worklist.isEmpty();
+    }
+
+    public boolean isInQueue(Node node) {
+        return !inQueue.isNew(node) && inQueue.isMarked(node);
+    }
+
+    private class QueueConsumingIterator implements Iterator<Node> {
+        private final Queue<Node> queue;
+
+        public QueueConsumingIterator(Queue<Node> queue) {
+            this.queue = queue;
+        }
+
+        @Override
+        public boolean hasNext() {
+            dropDeleted();
+            return iterationLimit > 0 && !queue.isEmpty();
+        }
+
+        @Override
+        public Node next() {
+            if (iterationLimit-- <= 0) {
+                throw new NoSuchElementException();
+            }
+            dropDeleted();
+            Node node = queue.remove();
+            if (lastPull != lastChain) {
+                firstNoChange = null;
+            }
+            lastPull = node;
+            inQueue.clear(node);
+            return node;
+        }
+
+        private void dropDeleted() {
+            while (!queue.isEmpty() && queue.peek().isDeleted()) {
+                queue.remove();
+            }
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    @Override
+    public Iterator<Node> iterator() {
+        return new QueueConsumingIterator(worklist);
+    }
+
+    private static class UnmarkedNodeIterator implements Iterator<Node> {
+        private final NodeBitMap visited;
+        private Iterator<Node> nodes;
+        private Node nextNode;
+
+        public UnmarkedNodeIterator(NodeBitMap visited, Iterator<Node> nodes) {
+            this.visited = visited;
+            this.nodes = nodes;
+            forward();
+        }
+
+        private void forward() {
+            do {
+                if (!nodes.hasNext()) {
+                    nextNode = null;
+                    return;
+                }
+                nextNode = nodes.next();
+            } while (visited.isMarked(nextNode));
+        }
+
+        @Override
+        public boolean hasNext() {
+            return nextNode != null;
+        }
+
+        @Override
+        public Node next() {
+            try {
+                return nextNode;
+            } finally {
+                forward();
+            }
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+    }
+
+    public Iterable<Node> unmarkedNodes() {
+        return new Iterable<Node>() {
+            @Override
+            public Iterator<Node> iterator() {
+                return new UnmarkedNodeIterator(visited, visited.graph().getNodes().iterator());
+            }
+        };
+    }
+
+    public static class InfiniteWorkException extends RuntimeException {
+        private static final long serialVersionUID = -5319329402219396658L;
+        public InfiniteWorkException() {
+            super();
+        }
+        public InfiniteWorkException(String message) {
+            super(message);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/VerificationError.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * 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.max.graal.graph;
+
+
+/**
+ * This error represents a failed verification of a node . It must only be used for conditions that should never occur during normal operation.
+ */
+public class VerificationError extends GraalInternalError {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 8459607567446819822L;
+
+    /**
+     * This constructor creates a {@link VerificationError} with a message assembled via {@link String#format(String, Object...)}.
+     * It always uses the ENGLISH locale in order to always generate the same output.
+     * @param msg the message that will be associated with the error, in String.format syntax
+     * @param args parameters to String.format - parameters that implement {@link Iterable} will be expanded into a [x, x, ...] representation.
+     */
+    public VerificationError(String msg, Object... args) {
+        super(msg, args);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/iterators/FilteredNodeIterable.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,75 @@
+/*
+ * 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.max.graal.graph.iterators;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+
+public class FilteredNodeIterable<T extends Node> extends NodeIterable<T> {
+    private final NodeIterable<T> nodeIterable;
+    private NodePredicate predicate = NodePredicates.alwaysTrue();
+    private NodePredicate until = NodePredicates.isNull();
+    public FilteredNodeIterable(NodeIterable<T> nodeIterable) {
+        this.nodeIterable = nodeIterable;
+    }
+    public FilteredNodeIterable<T> and(NodePredicate nodePredicate) {
+        this.predicate = this.predicate.and(nodePredicate);
+        return this;
+    }
+    public FilteredNodeIterable<T> or(NodePredicate nodePredicate) {
+        this.predicate = this.predicate.or(nodePredicate);
+        return this;
+    }
+    @Override
+    public NodeIterable<T> until(final T u) {
+        until = until.or(NodePredicates.equals(u));
+        return this;
+    }
+    @Override
+    public NodeIterable<T> until(final Class<? extends T> clazz) {
+        until = until.or(NodePredicates.isA(clazz));
+        return this;
+    }
+    @Override
+    public Iterator<T> iterator() {
+        final Iterator<T> iterator = nodeIterable.iterator();
+        return new PredicatedProxyNodeIterator<>(until, iterator, predicate);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <F extends T> FilteredNodeIterable<F> filter(Class<F> clazz) {
+        return (FilteredNodeIterable<F>) this.and(NodePredicates.isA(clazz));
+    }
+
+    @Override
+    public FilteredNodeIterable<T> filter(NodePredicate p) {
+        return this.and(p);
+    }
+
+    @Override
+    public FilteredNodeIterable<T> filterInterface(Class< ? > iface) {
+        return this.and(NodePredicates.isAInterface(iface));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/iterators/NodeIterable.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,78 @@
+/*
+ * 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.max.graal.graph.iterators;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+
+public abstract class NodeIterable<T extends Node> implements Iterable<T> {
+    public NodeIterable<T> until(final T u) {
+        return new FilteredNodeIterable<>(this).until(u);
+    }
+    public NodeIterable<T> until(final Class<? extends T> clazz) {
+        return new FilteredNodeIterable<>(this).until(clazz);
+    }
+    @SuppressWarnings("unchecked")
+    public <F extends T> FilteredNodeIterable<F> filter(Class<F> clazz) {
+        return (FilteredNodeIterable<F>) new FilteredNodeIterable<>(this).and(NodePredicates.isA(clazz));
+    }
+    public FilteredNodeIterable<T> filterInterface(Class<?> iface) {
+        return new FilteredNodeIterable<>(this).and(NodePredicates.isAInterface(iface));
+    }
+    public FilteredNodeIterable<T> filter(NodePredicate predicate) {
+        return new FilteredNodeIterable<>(this).and(predicate);
+    }
+    public List<T> snapshot() {
+        ArrayList<T> list = new ArrayList<>();
+        for (T n : this) {
+            list.add(n);
+        }
+        return list;
+    }
+    public T first() {
+        Iterator<T> iterator = iterator();
+        if (iterator.hasNext()) {
+            return iterator.next();
+        }
+        return null;
+    }
+    public int count() {
+        int count = 0;
+        Iterator<T> iterator = iterator();
+        while (iterator.hasNext()) {
+            iterator.next();
+            count++;
+        }
+        return count;
+    }
+    public boolean isEmpty() {
+        return count() == 0;
+    }
+    public boolean isNotEmpty() {
+        return iterator().hasNext();
+    }
+    public boolean contains(T node) {
+        return this.filter(NodePredicates.equals(node)).isNotEmpty();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/iterators/NodeIterator.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * 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.max.graal.graph.iterators;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+
+public abstract class NodeIterator<T extends Node> implements Iterator<T>{
+    protected T current;
+    protected abstract void forward();
+    @Override
+    public boolean hasNext() {
+        forward();
+        return current != null;
+    }
+    @Override
+    public T next() {
+        forward();
+        T ret = current;
+        if (current == null) {
+            throw new NoSuchElementException();
+        }
+        current = null;
+        return ret;
+    }
+    @Override
+    public void remove() {
+        throw new UnsupportedOperationException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/iterators/NodePredicate.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,42 @@
+/*
+ * 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.max.graal.graph.iterators;
+
+import com.oracle.max.graal.graph.*;
+
+public abstract class NodePredicate {
+
+    public abstract boolean apply(Node n);
+
+    public NodePredicate and(NodePredicate np) {
+        return NodePredicates.and(this, np);
+    }
+
+    public NodePredicate or(NodePredicate np) {
+        return NodePredicates.or(this, np);
+    }
+
+    public NodePredicate negate() {
+        return NodePredicates.not(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/iterators/NodePredicates.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,266 @@
+/*
+ * 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.max.graal.graph.iterators;
+
+import com.oracle.max.graal.graph.*;
+
+public abstract class NodePredicates {
+    private static final TautologyPredicate TAUTOLOGY = new TautologyPredicate();
+    private static final FalsePredicate FALSE = new FalsePredicate();
+    private static final IsNullPredicate IS_NULL = new IsNullPredicate();
+    private static final IsNotNullPredicate IS_NOT_NULL = new IsNotNullPredicate();
+
+    public static NodePredicate alwaysTrue() {
+        return TAUTOLOGY;
+    }
+
+    public static NodePredicate alwaysFalse() {
+        return FALSE;
+    }
+
+    public static NodePredicate isNull() {
+        return IS_NULL;
+    }
+
+    public static NodePredicate isNotNull() {
+        return IS_NOT_NULL;
+    }
+
+    public static NodePredicate equals(Node n) {
+        return new EqualsPredicate(n);
+    }
+
+    public static NodePredicate not(NodePredicate a) {
+        if (a == TAUTOLOGY) {
+            return FALSE;
+        }
+        if (a == FALSE) {
+            return TAUTOLOGY;
+        }
+        if (a == IS_NULL) {
+            return IS_NOT_NULL;
+        }
+        if (a == IS_NOT_NULL) {
+            return IS_NULL;
+        }
+        if (a instanceof NotPredicate) {
+            return ((NotPredicate) a).a;
+        }
+        if (a instanceof PositiveTypePredicate) {
+            return new NegativeTypePredicate((PositiveTypePredicate) a);
+        }
+        if (a instanceof NegativeTypePredicate) {
+            return new PositiveTypePredicate((NegativeTypePredicate) a);
+        }
+        if (a instanceof EqualsPredicate) {
+            return new NotEqualsPredicate(((EqualsPredicate) a).u);
+        }
+        if (a instanceof NotEqualsPredicate) {
+            return new EqualsPredicate(((NotEqualsPredicate) a).u);
+        }
+        return new NotPredicate(a);
+    }
+
+    public static NodePredicate and(NodePredicate a, NodePredicate b) {
+        if (a == TAUTOLOGY) {
+            return b;
+        }
+        if (b == TAUTOLOGY) {
+            return a;
+        }
+        if (a == FALSE || b == FALSE) {
+            return FALSE;
+        }
+        return new AndPredicate(a, b);
+    }
+
+    public static NodePredicate or(NodePredicate a, NodePredicate b) {
+        if (a == FALSE) {
+            return b;
+        }
+        if (b == FALSE) {
+            return a;
+        }
+        if (a == TAUTOLOGY || b == TAUTOLOGY) {
+            return TAUTOLOGY;
+        }
+        return new OrPredicate(a, b);
+    }
+
+    public static NegativeTypePredicate isNotA(Class<? extends Node> clazz) {
+        return new NegativeTypePredicate(clazz);
+    }
+
+    public static PositiveTypePredicate isA(Class<? extends Node> clazz) {
+        return new PositiveTypePredicate(clazz);
+    }
+
+    public static NodePredicate isAInterface(Class<?> iface) {
+        assert iface.isInterface();
+        return new PositiveTypePredicate(iface);
+    }
+
+    public static NodePredicate isNotAInterface(Class<?> iface) {
+        assert iface.isInterface();
+        return new NegativeTypePredicate(iface);
+    }
+
+    private static final class TautologyPredicate extends NodePredicate {
+        @Override
+        public boolean apply(Node n) {
+            return true;
+        }
+    }
+
+    private static final class FalsePredicate extends NodePredicate {
+        @Override
+        public boolean apply(Node n) {
+            return false;
+        }
+    }
+
+    private static final class AndPredicate extends NodePredicate {
+        private final NodePredicate a;
+        private final NodePredicate b;
+        private AndPredicate(NodePredicate a, NodePredicate b) {
+            this.a = a;
+            this.b = b;
+        }
+        @Override
+        public boolean apply(Node n) {
+            return a.apply(n) && b.apply(n);
+        }
+    }
+
+    private static final class NotPredicate extends NodePredicate {
+        private final NodePredicate a;
+        private NotPredicate(NodePredicate n) {
+            this.a = n;
+        }
+        @Override
+        public boolean apply(Node n) {
+            return !a.apply(n);
+        }
+    }
+
+    private static final class OrPredicate extends NodePredicate {
+        private final NodePredicate a;
+        private final NodePredicate b;
+        private OrPredicate(NodePredicate a, NodePredicate b) {
+            this.a = a;
+            this.b = b;
+        }
+        @Override
+        public boolean apply(Node n) {
+            return a.apply(n) || b.apply(n);
+        }
+    }
+
+    private static final class IsNullPredicate extends NodePredicate {
+        @Override
+        public boolean apply(Node n) {
+            return n == null;
+        }
+    }
+
+    private static final class IsNotNullPredicate extends NodePredicate {
+        @Override
+        public boolean apply(Node n) {
+            return n != null;
+        }
+    }
+
+    private static final class EqualsPredicate extends NodePredicate {
+        private final Node u;
+        public EqualsPredicate(Node u) {
+            this.u = u;
+        }
+        @Override
+        public boolean apply(Node n) {
+            return u == n;
+        }
+    }
+
+    private static final class NotEqualsPredicate extends NodePredicate {
+        private final Node u;
+        public NotEqualsPredicate(Node u) {
+            this.u = u;
+        }
+        @Override
+        public boolean apply(Node n) {
+            return u != n;
+        }
+    }
+
+    public static final class PositiveTypePredicate extends NodePredicate {
+        private final Class<?> type;
+        private PositiveTypePredicate or;
+        public PositiveTypePredicate(Class<?> type) {
+            this.type = type;
+        }
+        public PositiveTypePredicate(NegativeTypePredicate a) {
+            type = a.type;
+            if (a.nor != null) {
+                or = new PositiveTypePredicate(a.nor);
+            }
+        }
+        @Override
+        public boolean apply(Node n) {
+            return type.isInstance(n) || (or != null && or.apply(n));
+        }
+        public PositiveTypePredicate or(Class<? extends Node> clazz) {
+            if (or == null) {
+                or = new PositiveTypePredicate(clazz);
+            } else {
+                or.or(clazz);
+            }
+            return this;
+        }
+    }
+
+    public static final class NegativeTypePredicate extends NodePredicate {
+        private final Class<?> type;
+        private NegativeTypePredicate nor;
+        public NegativeTypePredicate(Class<?> type) {
+            this.type = type;
+        }
+        public NegativeTypePredicate(PositiveTypePredicate a) {
+            type = a.type;
+            if (a.or != null) {
+                nor = new NegativeTypePredicate(a.or);
+            }
+        }
+        @Override
+        public boolean apply(Node n) {
+            return !type.isInstance(n) && (nor == null || nor.apply(n));
+        }
+        public NegativeTypePredicate nor(Class<? extends Node> clazz) {
+            if (nor == null) {
+                nor = new NegativeTypePredicate(clazz);
+            } else {
+                nor.nor(clazz);
+            }
+            return this;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/iterators/PredicatedProxyNodeIterator.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * 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.max.graal.graph.iterators;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+
+public final class PredicatedProxyNodeIterator<T extends Node> extends NodeIterator<T> {
+    private final Iterator<T> iterator;
+    private final NodePredicate predicate;
+    private final NodePredicate until;
+    public PredicatedProxyNodeIterator(NodePredicate until, Iterator<T> iterator, NodePredicate predicate) {
+        this.until = until;
+        this.iterator = iterator;
+        this.predicate = predicate;
+    }
+    @Override
+    protected void forward() {
+        while ((current == null || !current.isAlive() || !predicate.apply(current)) && iterator.hasNext()) {
+            current = iterator.next();
+        }
+        if (current != null && (!current.isAlive() || !predicate.apply(current) || until.apply(current))) {
+            current = null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/package-info.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+/**
+ * This package contains the Node base class and the Graph container class of the Graal IR.
+ */
+package com.oracle.max.graal.graph;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/test/com/oracle/max/graal/graph/test/TestNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,39 @@
+/*
+ * 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.max.graal.graph.test;
+
+import com.oracle.max.graal.graph.*;
+
+
+public class TestNode extends Node implements Node.IterableNodeType {
+    @Data private String name;
+
+    public TestNode(String name) {
+        this.name = name;
+    }
+
+
+    public String getName() {
+        return name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/test/com/oracle/max/graal/graph/test/TypedNodeIteratorTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,156 @@
+/*
+ * 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.max.graal.graph.test;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.max.graal.graph.*;
+
+
+
+public class TypedNodeIteratorTest {
+
+    @Test
+    public void singleNodeTest() {
+        Graph graph = new Graph();
+        graph.add(new TestNode("a"));
+        assertTrue(graph.hasNode(TestNode.class));
+        assertEquals("a", toString(graph.getNodes(TestNode.class)));
+    }
+
+    @Test
+    public void deletingNodeTest() {
+        TestNode testNode = new TestNode("a");
+        Graph graph = new Graph();
+        graph.add(testNode);
+        testNode.delete();
+        assertEquals("", toString(graph.getNodes(TestNode.class)));
+    }
+
+    @Test
+    public void deleteAndAddTest() {
+        TestNode testNode = new TestNode("b");
+        Graph graph = new Graph();
+        graph.add(new TestNode("a"));
+        graph.add(testNode);
+        testNode.delete();
+        assertEquals("a", toString(graph.getNodes(TestNode.class)));
+        graph.add(new TestNode("c"));
+        assertEquals("ac", toString(graph.getNodes(TestNode.class)));
+    }
+
+    @Test
+    public void iteratorBehaviorTest() {
+        Graph graph = new Graph();
+        graph.add(new TestNode("a"));
+        Iterator<TestNode> iterator = graph.getNodes(TestNode.class).iterator();
+        assertTrue(iterator.hasNext());
+        assertEquals("a", iterator.next().getName());
+        assertFalse(iterator.hasNext());
+        graph.add(new TestNode("b"));
+        assertTrue(iterator.hasNext());
+        assertEquals("b", iterator.next().getName());
+        assertFalse(iterator.hasNext());
+        TestNode c = new TestNode("c");
+        graph.add(c);
+        assertTrue(iterator.hasNext());
+        c.delete();
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void complicatedIterationTest() {
+        Graph graph = new Graph();
+        graph.add(new TestNode("a"));
+        for (TestNode tn : graph.getNodes(TestNode.class)) {
+            String name = tn.getName();
+            for (int i = 0; i < name.length(); ++i) {
+                char c = name.charAt(i);
+                if (c == 'a') {
+                    tn.delete();
+                    graph.add(new TestNode("b"));
+                    graph.add(new TestNode("c"));
+                } else if (c == 'b') {
+                    tn.delete();
+                } else if (c == 'c') {
+                    graph.add(new TestNode("d"));
+                    graph.add(new TestNode("e"));
+                    graph.add(new TestNode("d"));
+                    graph.add(new TestNode("e"));
+                    graph.add(new TestNode("e"));
+                    graph.add(new TestNode("d"));
+                    graph.add(new TestNode("e"));
+                    graph.add(new TestNode("d"));
+                } else if (c == 'd') {
+                    for (TestNode tn2 : graph.getNodes(TestNode.class)) {
+                        if (tn2.getName().equals("e")) {
+                            tn2.delete();
+                        } else if (tn2.getName().equals("c")) {
+                            tn2.delete();
+                        }
+                    }
+                } else if (c == 'e') {
+                    fail("All e nodes must have been deleted by visiting the d node");
+                }
+            }
+        }
+        assertEquals("dddd", toString(graph.getNodes(TestNode.class)));
+    }
+
+    @Test
+    public void addingNodeDuringIterationTest() {
+        Graph graph = new Graph();
+        graph.add(new TestNode("a"));
+        StringBuilder sb = new StringBuilder();
+        int z = 0;
+        for (TestNode tn : graph.getNodes(TestNode.class)) {
+            if (z == 0) {
+                graph.add(new TestNode("b"));
+            }
+            sb.append(tn.getName());
+            z++;
+        }
+        assertEquals(2, z);
+        assertEquals("ab", sb.toString());
+        z = 0;
+        for (TestNode tn : graph.getNodes(TestNode.class)) {
+            if (z == 0) {
+                graph.add(new TestNode("c"));
+            }
+            assertNotNull(tn);
+            z++;
+        }
+        assertEquals(3, z);
+    }
+
+    private String toString(Iterable<TestNode> nodes) {
+        StringBuilder sb = new StringBuilder();
+        for (TestNode tn : nodes) {
+            sb.append(tn.getName());
+        }
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/Compiler.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,42 @@
+/*
+ * 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.max.graal.hotspot;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.hotspot.bridge.*;
+import com.oracle.max.graal.hotspot.ri.*;
+
+public interface Compiler {
+
+    CompilerToVM getVMEntries();
+    VMToCompiler getVMExits();
+    GraalCompiler getCompiler();
+    RiType lookupType(String returnType, HotSpotTypeResolved accessingClass, boolean eagerResolve);
+    HotSpotVMConfig getConfig();
+    GraalRuntime getRuntime();
+    CiTarget getTarget();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/CompilerImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.hotspot;
+
+import java.io.*;
+import java.net.*;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.cri.xir.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.target.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.hotspot.bridge.*;
+import com.oracle.max.graal.hotspot.logging.*;
+import com.oracle.max.graal.hotspot.ri.*;
+import com.oracle.max.graal.hotspot.server.*;
+
+/**
+ * Singleton class holding the instance of the GraalCompiler.
+ */
+public final class CompilerImpl implements Compiler, Remote {
+
+    private static Compiler theInstance;
+
+    public static Compiler getInstance() {
+        if (theInstance == null) {
+            initialize();
+        }
+        return theInstance;
+    }
+
+    public static synchronized void initialize() {
+        if (theInstance != null) {
+            return;
+        }
+
+        String remote = System.getProperty("graal.remote");
+        if (remote != null) {
+            // remote compilation (will not create a local Compiler)
+            try {
+                System.out.println("Graal compiler started in client/server mode, server: " + remote);
+                Socket socket = new Socket(remote, 1199);
+                ReplacingStreams streams = new ReplacingStreams(socket.getOutputStream(), socket.getInputStream());
+                streams.getInvocation().sendResult(new CompilerToVMImpl());
+
+                theInstance = (Compiler) streams.getInvocation().waitForResult(false);
+            } catch (IOException e1) {
+                System.out.println("Connection to compilation server FAILED.");
+                throw new RuntimeException(e1);
+            } catch (ClassNotFoundException e2) {
+                System.out.println("Connection to compilation server FAILED.");
+                throw new RuntimeException(e2);
+            }
+        } else {
+            // ordinary local compilation
+            theInstance = new CompilerImpl(null);
+        }
+    }
+
+    public static Compiler initializeServer(CompilerToVM entries) {
+        assert theInstance == null;
+        theInstance = new CompilerImpl(entries);
+        return theInstance;
+    }
+
+    private final CompilerToVM vmEntries;
+    private final VMToCompiler vmExits;
+
+    private HotSpotRuntime runtime;
+    private GraalCompiler compiler;
+    private CiTarget target;
+
+    private final HotSpotVMConfig config;
+
+    public HotSpotVMConfig getConfig() {
+        return config;
+    }
+
+    private CompilerImpl(CompilerToVM initialEntries) {
+
+        CompilerToVM entries = initialEntries;
+        // initialize VMEntries
+        if (entries == null) {
+            entries = new CompilerToVMImpl();
+        }
+
+        // initialize VMExits
+        VMToCompiler exits = new VMToCompilerImpl(this);
+
+        // logging, etc.
+        if (CountingProxy.ENABLED) {
+            exits = CountingProxy.getProxy(VMToCompiler.class, exits);
+            entries = CountingProxy.getProxy(CompilerToVM.class, entries);
+        }
+        if (Logger.ENABLED) {
+            exits = LoggingProxy.getProxy(VMToCompiler.class, exits);
+            entries = LoggingProxy.getProxy(CompilerToVM.class, entries);
+        }
+
+        // set the final fields
+        vmEntries = entries;
+        vmExits = exits;
+
+        // initialize compiler
+        config = vmEntries.getConfiguration();
+        config.check();
+    }
+
+    @Override
+    public CiTarget getTarget() {
+        if (target == null) {
+            final int wordSize = 8;
+            final int stackFrameAlignment = 16;
+            target = new CiTarget(new AMD64(), true, stackFrameAlignment, config.vmPageSize, wordSize, true, true, true);
+        }
+
+        return target;
+    }
+
+    /**
+     * Factory method for getting a Graal compiler instance. This method is called via reflection.
+     */
+    public static GraalRuntime getGraalRuntime() {
+        return getInstance().getRuntime();
+    }
+
+    @Override
+    public GraalCompiler getCompiler() {
+        if (compiler == null) {
+            // these options are important - graal will not generate correct code without them
+            GraalOptions.StackShadowPages = config.stackShadowPages;
+
+            RiXirGenerator generator = new HotSpotXirGenerator(config, getTarget(), getRuntime().getGlobalStubRegisterConfig(), this);
+            if (Logger.ENABLED) {
+                generator = LoggingProxy.getProxy(RiXirGenerator.class, generator);
+            }
+
+            Backend backend = Backend.create(target.arch, runtime, target);
+            generator.initialize(backend.newXirAssembler());
+
+            compiler = new GraalCompiler(getRuntime(), getTarget(), backend, generator);
+        }
+        return compiler;
+    }
+
+    @Override
+    public CompilerToVM getVMEntries() {
+        return vmEntries;
+    }
+
+    @Override
+    public VMToCompiler getVMExits() {
+        return vmExits;
+    }
+
+    @Override
+    public RiType lookupType(String returnType, HotSpotTypeResolved accessingClass, boolean eagerResolve) {
+        if (returnType.length() == 1 && vmExits instanceof VMToCompilerImpl) {
+            VMToCompilerImpl exitsNative = (VMToCompilerImpl) vmExits;
+            CiKind kind = CiKind.fromPrimitiveOrVoidTypeChar(returnType.charAt(0));
+            switch(kind) {
+                case Boolean:
+                    return exitsNative.typeBoolean;
+                case Byte:
+                    return exitsNative.typeByte;
+                case Char:
+                    return exitsNative.typeChar;
+                case Double:
+                    return exitsNative.typeDouble;
+                case Float:
+                    return exitsNative.typeFloat;
+                case Illegal:
+                    break;
+                case Int:
+                    return exitsNative.typeInt;
+                case Jsr:
+                    break;
+                case Long:
+                    return exitsNative.typeLong;
+                case Object:
+                    break;
+                case Short:
+                    return exitsNative.typeShort;
+                case Void:
+                    return exitsNative.typeVoid;
+            }
+        }
+        return vmEntries.RiSignature_lookupType(returnType, accessingClass, eagerResolve);
+    }
+
+    @Override
+    public HotSpotRuntime getRuntime() {
+        if (runtime == null) {
+            if (GraalOptions.PrintCFGToFile) {
+//                context.addCompilationObserver(new CFGPrinterObserver());
+            }
+           // if (GraalOptions.PrintIdealGraphLevel != 0 || GraalOptions.Plot || GraalOptions.PlotOnError) {
+             //   CompilationObserver observer;
+               // if (GraalOptions.PrintIdealGraphFile) {
+              //      observer = new IdealGraphPrinterObserver();
+              //  } else {
+              //      observer = new IdealGraphPrinterObserver(GraalOptions.PrintIdealGraphAddress, GraalOptions.PrintIdealGraphPort);
+              //  }
+//                context.addCompilationObserver(observer);
+                // TODO(tw): Install observer.
+           // }
+            runtime = new HotSpotRuntime(config, this);
+        }
+        return runtime;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/CompilerObject.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,42 @@
+/*
+ * 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.max.graal.hotspot;
+
+import java.io.*;
+
+
+/**
+ * Parent class for all HotSpot Ri... types.
+ */
+public abstract class CompilerObject implements Serializable {
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -4551670987101214877L;
+    protected final Compiler compiler;
+
+    protected CompilerObject(Compiler compiler) {
+        this.compiler = compiler;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotDebugConfig.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,146 @@
+/*
+ * 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.max.graal.hotspot;
+
+import java.util.*;
+import java.util.regex.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.printer.*;
+
+
+public class HotSpotDebugConfig implements DebugConfig {
+
+    private final String logFilter;
+    private final String meterFilter;
+    private final String timerFilter;
+    private final String dumpFilter;
+    private final String methodFilter;
+    private final List<DebugDumpHandler> dumpHandlers = new ArrayList<>();
+
+    public HotSpotDebugConfig(String logFilter, String meterFilter, String timerFilter, String dumpFilter, String methodFilter) {
+        this.logFilter = logFilter;
+        this.meterFilter = meterFilter;
+        this.timerFilter = timerFilter;
+        this.dumpFilter = dumpFilter;
+        this.methodFilter = methodFilter;
+        dumpHandlers.add(new IdealGraphPrinterDumpHandler(GraalOptions.PrintIdealGraphAddress, GraalOptions.PrintIdealGraphPort));
+        dumpHandlers.add(new CFGPrinterObserver());
+    }
+
+    public boolean isLogEnabled() {
+        return isEnabled(logFilter);
+    }
+
+    public boolean isMeterEnabled() {
+        return isEnabled(meterFilter);
+    }
+
+    public boolean isDumpEnabled() {
+        return isEnabled(dumpFilter);
+    }
+
+    public boolean isTimeEnabled() {
+        return isEnabled(timerFilter);
+    }
+
+    private boolean isEnabled(String filter) {
+        return filter != null && checkContains(Debug.currentScope(), filter) && checkMethodFilter();
+    }
+
+    private static boolean checkContains(String currentScope, String filter) {
+        if (filter.contains("*")) {
+            /*filter = filter.replace("*", ".*");
+            filter = filter.replace("[", "\\[");
+            filter = filter.replace("]", "\\]");
+            filter = filter.replace(":", "\\:");*/
+            return Pattern.matches(filter, currentScope);
+        }
+        return currentScope.contains(filter);
+    }
+
+    private boolean checkMethodFilter() {
+        if (methodFilter == null) {
+            return true;
+        } else {
+            for (Object o : Debug.context()) {
+                if (o instanceof RiMethod) {
+                    RiMethod riMethod = (RiMethod) o;
+                    if (CiUtil.format("%H.%n", riMethod).contains(methodFilter)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Debug config:");
+        add(sb, "Log", logFilter);
+        add(sb, "Meter", meterFilter);
+        add(sb, "Time", timerFilter);
+        add(sb, "Dump", dumpFilter);
+        add(sb, "MethodFilter", methodFilter);
+        return sb.toString();
+    }
+
+    private static void add(StringBuilder sb, String name, String filter) {
+        if (filter != null) {
+            sb.append(' ');
+            sb.append(name);
+            sb.append('=');
+            sb.append(filter);
+        }
+    }
+
+    @Override
+    public RuntimeException interceptException(Throwable e) {
+        if (e instanceof CiBailout) {
+            return null;
+        }
+        Debug.setConfig(Debug.fixedConfig(true, true, false, false, dumpHandlers));
+        // sync "Exception occured in scope: " with mx/sanitycheck.py::Test.__init__
+        Debug.log(String.format("Exception occured in scope: %s", Debug.currentScope()));
+        for (Object o : Debug.context()) {
+            Debug.log("Context obj %s", o);
+            if (o instanceof Graph) {
+                Graph graph = (Graph) o;
+                Debug.log("Found graph in context: ", graph);
+                Debug.dump(o, "Exception graph");
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Collection<? extends DebugDumpHandler> dumpHandlers() {
+        return dumpHandlers;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotOptions.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,110 @@
+/*
+ * 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.max.graal.hotspot;
+
+import java.lang.reflect.*;
+
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.hotspot.logging.*;
+
+public class HotSpotOptions {
+
+    public static void setDefaultOptions() {
+        GraalOptions.MethodEndBreakpointGuards = 2;
+        GraalOptions.ResolveClassBeforeStaticInvoke = false;
+    }
+
+    public static boolean setOption(String option) {
+        if (option.length() == 0) {
+            return false;
+        }
+
+        Object value = null;
+        String fieldName = null;
+        String valueString = null;
+
+        char first = option.charAt(0);
+        if (first == '+' || first == '-') {
+            fieldName = option.substring(1);
+            value = (first == '+');
+        } else {
+            int index = option.indexOf('=');
+            if (index == -1) {
+                fieldName = option;
+                valueString = null;
+            } else {
+                fieldName = option.substring(0, index);
+                valueString = option.substring(index + 1);
+            }
+        }
+
+        Field f;
+        try {
+            f = GraalOptions.class.getField(fieldName);
+
+            if (value == null) {
+                if (f.getType() == Float.TYPE) {
+                    value = Float.parseFloat(valueString);
+                } else if (f.getType() == Double.TYPE) {
+                    value = Double.parseDouble(valueString);
+                } else if (f.getType() == Integer.TYPE) {
+                    value = Integer.parseInt(valueString);
+                } else if (f.getType() == Boolean.TYPE) {
+                    if (valueString == null || valueString.length() == 0) {
+                        value = true;
+                    } else {
+                        value = Boolean.parseBoolean(valueString);
+                    }
+                } else if (f.getType() == String.class) {
+                    if (valueString == null) {
+                        value = "";
+                    } else {
+                        value = valueString;
+                    }
+                }
+            }
+            if (value != null) {
+                f.set(null, value);
+                //Logger.info("Set option " + fieldName + " to " + value);
+            } else {
+                Logger.info("Wrong value \"" + valueString + "\" for option " + fieldName);
+                return false;
+            }
+        } catch (SecurityException e) {
+            Logger.info("Security exception when setting option " + option);
+            return false;
+        } catch (NoSuchFieldException e) {
+            Logger.info("Could not find option " + fieldName);
+            return false;
+        } catch (IllegalArgumentException e) {
+            Logger.info("Illegal value for option " + option);
+            return false;
+        } catch (IllegalAccessException e) {
+            Logger.info("Illegal access exception when setting option " + option);
+            return false;
+        }
+
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotProxy.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,92 @@
+/*
+ * 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.max.graal.hotspot;
+
+/**
+ * Provides methods to classify the HotSpot-internal identifiers.
+ */
+public final class HotSpotProxy {
+
+    private HotSpotProxy() {
+    }
+
+    private enum CompilerObjectType {
+        // this enum needs to have the same values as the one in graal_Compiler.hpp
+        STUB(0x100000000000000L),
+        METHOD(0x200000000000000L),
+        CLASS(0x300000000000000L),
+        SYMBOL(0x400000000000000L),
+        CONSTANT_POOL(0x500000000000000L),
+        CONSTANT(0x600000000000000L),
+        TYPE_MASK(0xf00000000000000L),
+        DUMMY_CONSTANT(0x6ffffffffffffffL);
+
+        public final long bits;
+
+        CompilerObjectType(long bits) {
+            this.bits = bits;
+        }
+    }
+
+    public static final Long DUMMY_CONSTANT_OBJ = CompilerObjectType.DUMMY_CONSTANT.bits;
+
+    private static boolean isType(long id, CompilerObjectType type) {
+        return (id & CompilerObjectType.TYPE_MASK.bits) == type.bits;
+    }
+
+    public static boolean isStub(long id) {
+        return isType(id, CompilerObjectType.STUB);
+    }
+
+    public static boolean isMethod(long id) {
+        return isType(id, CompilerObjectType.METHOD);
+    }
+
+    public static boolean isClass(long id) {
+        return isType(id, CompilerObjectType.CLASS);
+    }
+
+    public static boolean isSymbol(long id) {
+        return isType(id, CompilerObjectType.SYMBOL);
+    }
+
+    public static boolean isConstantPool(long id) {
+        return isType(id, CompilerObjectType.CONSTANT_POOL);
+    }
+
+    public static boolean isConstant(long id) {
+        return isType(id, CompilerObjectType.CONSTANT_POOL);
+    }
+
+    public static String toString(long id) {
+        CompilerObjectType type = null;
+        for (CompilerObjectType t : CompilerObjectType.values()) {
+            if ((id & CompilerObjectType.TYPE_MASK.bits) == t.bits) {
+                type = t;
+            }
+        }
+        long num = id & ~CompilerObjectType.TYPE_MASK.bits;
+        return type + " " + num;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotTargetMethod.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,107 @@
+/*
+ * 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.max.graal.hotspot;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiTargetMethod.*;
+import com.oracle.max.graal.hotspot.logging.*;
+import com.oracle.max.graal.hotspot.ri.*;
+
+/**
+ * CiTargetMethod augmented with HotSpot-specific information.
+ */
+public final class HotSpotTargetMethod extends CompilerObject {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 7807321392203253218L;
+    public final CiTargetMethod targetMethod;
+    public final HotSpotMethodResolved method; // used only for methods
+    public final String name; // used only for stubs
+
+    public final Site[] sites;
+    public final ExceptionHandler[] exceptionHandlers;
+
+    public HotSpotTargetMethod(Compiler compiler, HotSpotMethodResolved method, CiTargetMethod targetMethod) {
+        super(compiler);
+        this.method = method;
+        this.targetMethod = targetMethod;
+        this.name = null;
+
+        sites = getSortedSites(targetMethod);
+        if (targetMethod.exceptionHandlers == null) {
+            exceptionHandlers = null;
+        } else {
+            exceptionHandlers = targetMethod.exceptionHandlers.toArray(new ExceptionHandler[targetMethod.exceptionHandlers.size()]);
+        }
+    }
+
+    private HotSpotTargetMethod(Compiler compiler, CiTargetMethod targetMethod, String name) {
+        super(compiler);
+        this.method = null;
+        this.targetMethod = targetMethod;
+        this.name = name;
+
+        sites = getSortedSites(targetMethod);
+        assert targetMethod.exceptionHandlers == null || targetMethod.exceptionHandlers.size() == 0;
+        exceptionHandlers = null;
+    }
+
+    private static Site[] getSortedSites(CiTargetMethod target) {
+        List<?>[] lists = new List<?>[] {target.safepoints, target.dataReferences, target.marks};
+        int count = 0;
+        for (List<?> list : lists) {
+            count += list.size();
+        }
+        Site[] result = new Site[count];
+        int pos = 0;
+        for (List<?> list : lists) {
+            for (Object elem : list) {
+                result[pos++] = (Site) elem;
+            }
+        }
+        Arrays.sort(result, new Comparator<Site>() {
+
+            public int compare(Site s1, Site s2) {
+                if (s1.pcOffset == s2.pcOffset && (s1 instanceof Mark ^ s2 instanceof Mark)) {
+                    return s1 instanceof Mark ? -1 : 1;
+                }
+                return s1.pcOffset - s2.pcOffset;
+            }
+        });
+        if (Logger.ENABLED) {
+            for (Site site : result) {
+                Logger.log(site.pcOffset + ": " + site);
+            }
+        }
+        return result;
+    }
+
+    public static Object installStub(Compiler compiler, CiTargetMethod targetMethod, String name) {
+        return compiler.getVMEntries().installStub(new HotSpotTargetMethod(compiler, targetMethod, name));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotVMConfig.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,141 @@
+/*
+ * 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.max.graal.hotspot;
+
+import com.oracle.max.cri.ci.*;
+
+/**
+ * Used to communicate configuration details, runtime offsets, etc. to graal upon compileMethod.
+ */
+public final class HotSpotVMConfig extends CompilerObject {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -4744897993263044184L;
+
+    private HotSpotVMConfig() {
+        super(null);
+    }
+
+    // os information, register layout, code generation, ...
+    public boolean windowsOs;
+    public int codeEntryAlignment;
+    public boolean verifyPointers;
+    public boolean useFastLocking;
+    public boolean useFastNewObjectArray;
+    public boolean useFastNewTypeArray;
+
+    // offsets, ...
+    public int vmPageSize;
+    public int stackShadowPages;
+    public int hubOffset;
+    public int arrayLengthOffset;
+    public int klassStateOffset;
+    public int klassStateFullyInitialized;
+    public int[] arrayOffsets;
+    public int arrayClassElementOffset;
+    public int threadTlabTopOffset;
+    public int threadTlabEndOffset;
+    public int threadObjectOffset;
+    public int instanceHeaderPrototypeOffset;
+    public int threadExceptionOopOffset;
+    public int threadExceptionPcOffset;
+    public int threadMultiNewArrayStorage;
+    public long cardtableStartAddress;
+    public int cardtableShift;
+    public long safepointPollingAddress;
+    public boolean isPollingPageFar;
+    public int classMirrorOffset;
+    public int runtimeCallStackSize;
+    public int klassModifierFlagsOffset;
+    public int klassOopOffset;
+    public int graalMirrorKlassOffset;
+    public int nmethodEntryOffset;
+
+    // methodData information
+    public int methodDataOopDataOffset;
+    public int dataLayoutHeaderSize;
+    public int dataLayoutTagOffset;
+    public int dataLayoutFlagsOffset;
+    public int dataLayoutBCIOffset;
+    public int dataLayoutCellsOffset;
+    public int dataLayoutCellSize;
+    public int bciProfileWidth;
+    public int typeProfileWidth;
+
+    // runtime stubs
+    public long debugStub;
+    public long instanceofStub;
+    public long newInstanceStub;
+    public long unresolvedNewInstanceStub;
+    public long newTypeArrayStub;
+    public long newObjectArrayStub;
+    public long newMultiArrayStub;
+    public long loadKlassStub;
+    public long accessFieldStub;
+    public long resolveStaticCallStub;
+    public long inlineCacheMissStub;
+    public long unwindExceptionStub;
+    public long handleExceptionStub;
+    public long handleDeoptStub;
+    public long monitorEnterStub;
+    public long monitorExitStub;
+    public long fastMonitorEnterStub;
+    public long fastMonitorExitStub;
+    public long verifyPointerStub;
+
+    public void check() {
+        assert vmPageSize >= 16;
+        assert codeEntryAlignment > 0;
+        assert stackShadowPages > 0;
+    }
+
+    public int getArrayOffset(CiKind kind) {
+        return arrayOffsets[getKindNumber(kind)];
+    }
+
+    private static int getKindNumber(CiKind kind) {
+        if (kind == CiKind.Boolean) {
+            return 0;
+        } else if (kind == CiKind.Byte) {
+            return 1;
+        } else if (kind == CiKind.Short) {
+            return 2;
+        } else if (kind == CiKind.Char) {
+            return 3;
+        } else if (kind == CiKind.Int) {
+            return 4;
+        } else if (kind == CiKind.Float) {
+            return 5;
+        } else if (kind == CiKind.Long) {
+            return 6;
+        } else if (kind == CiKind.Double) {
+            return 7;
+        } else if (kind == CiKind.Object) {
+            return 8;
+        } else {
+            throw new RuntimeException(kind + " is not a Java kind");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVM.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,113 @@
+/*
+ * 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.max.graal.hotspot.bridge;
+
+import java.lang.reflect.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.hotspot.*;
+import com.oracle.max.graal.hotspot.ri.*;
+
+/**
+ * Calls from Java into HotSpot.
+ */
+public interface CompilerToVM {
+
+    // Checkstyle: stop
+
+    byte[] RiMethod_code(HotSpotMethodResolved method);
+
+    String RiMethod_signature(HotSpotMethodResolved method);
+
+    RiExceptionHandler[] RiMethod_exceptionHandlers(HotSpotMethodResolved method);
+
+    boolean RiMethod_hasBalancedMonitors(HotSpotMethodResolved method);
+
+    RiMethod RiMethod_uniqueConcreteMethod(HotSpotMethodResolved method);
+
+    int RiMethod_invocationCount(HotSpotMethodResolved method);
+
+    HotSpotMethodData RiMethod_methodData(HotSpotMethodResolved method);
+
+    RiType RiSignature_lookupType(String returnType, HotSpotTypeResolved accessingClass, boolean eagerResolve);
+
+    Object RiConstantPool_lookupConstant(HotSpotTypeResolved pool, int cpi);
+
+    RiMethod RiConstantPool_lookupMethod(HotSpotTypeResolved pool, int cpi, byte byteCode);
+
+    RiType RiConstantPool_lookupType(HotSpotTypeResolved pool, int cpi);
+
+    RiField RiConstantPool_lookupField(HotSpotTypeResolved pool, int cpi, byte byteCode);
+
+    void RiConstantPool_loadReferencedType(HotSpotTypeResolved pool, int cpi, byte byteCode);
+
+    HotSpotCompiledMethod installMethod(HotSpotTargetMethod targetMethod, boolean installCode);
+
+    long installStub(HotSpotTargetMethod targetMethod);
+
+    HotSpotVMConfig getConfiguration();
+
+    RiMethod RiType_resolveMethodImpl(HotSpotTypeResolved klass, String name, String signature);
+
+    boolean RiType_isSubtypeOf(HotSpotTypeResolved klass, RiType other);
+
+    RiType RiType_leastCommonAncestor(HotSpotTypeResolved thisType, HotSpotTypeResolved otherType);
+
+    RiType getPrimitiveArrayType(CiKind kind);
+
+    RiType RiType_arrayOf(HotSpotTypeResolved klass);
+
+    RiType RiType_componentType(HotSpotTypeResolved klass);
+
+    boolean RiType_isInitialized(HotSpotTypeResolved klass);
+
+    RiType getType(Class<?> javaClass);
+
+    RiType RiType_uniqueConcreteSubtype(HotSpotTypeResolved klass);
+
+    RiType RiType_superType(HotSpotTypeResolved klass);
+
+    int getArrayLength(CiConstant array);
+
+    boolean compareConstantObjects(CiConstant x, CiConstant y);
+
+    RiType getRiType(CiConstant constant);
+
+    RiResolvedField[] RiType_fields(HotSpotTypeResolved klass);
+
+    boolean RiMethod_hasCompiledCode(HotSpotMethodResolved method);
+
+    int RiMethod_getCompiledCodeSize(HotSpotMethodResolved method);
+
+    RiMethod getRiMethod(Method reflectionMethod);
+
+    long getMaxCallTargetOffset(CiRuntimeCall rtcall);
+
+    String disassembleNative(byte[] code, long address);
+
+    String disassembleJava(HotSpotMethodResolved method);
+
+    // Checkstyle: resume
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVMImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,160 @@
+/*
+ * 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.max.graal.hotspot.bridge;
+
+import java.lang.reflect.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.hotspot.*;
+import com.oracle.max.graal.hotspot.ri.*;
+import com.oracle.max.graal.hotspot.server.*;
+
+/**
+ * Entries into the HotSpot VM from Java code.
+ */
+public class CompilerToVMImpl implements CompilerToVM, Remote {
+
+    // Checkstyle: stop
+
+    @Override
+    public native RiMethod getRiMethod(Method reflectionMethod);
+
+    @Override
+    public native byte[] RiMethod_code(HotSpotMethodResolved method);
+
+    @Override
+    public native String RiMethod_signature(HotSpotMethodResolved method);
+
+    @Override
+    public native RiExceptionHandler[] RiMethod_exceptionHandlers(HotSpotMethodResolved method);
+
+    @Override
+    public native boolean RiMethod_hasBalancedMonitors(HotSpotMethodResolved method);
+
+    @Override
+    public native RiMethod RiMethod_uniqueConcreteMethod(HotSpotMethodResolved method);
+
+    @Override
+    public native int RiMethod_invocationCount(HotSpotMethodResolved method);
+
+    @Override
+    public native RiType RiSignature_lookupType(String returnType, HotSpotTypeResolved accessingClass, boolean eagerResolve);
+
+    @Override
+    public native Object RiConstantPool_lookupConstant(HotSpotTypeResolved pool, int cpi);
+
+    @Override
+    public native RiMethod RiConstantPool_lookupMethod(HotSpotTypeResolved pool, int cpi, byte byteCode);
+
+    @Override
+    public native RiType RiConstantPool_lookupType(HotSpotTypeResolved pool, int cpi);
+
+    @Override
+    public native void RiConstantPool_loadReferencedType(HotSpotTypeResolved pool, int cpi, byte byteCode);
+
+    @Override
+    public native RiField RiConstantPool_lookupField(HotSpotTypeResolved pool, int cpi, byte byteCode);
+
+    @Override
+    public native HotSpotCompiledMethod installMethod(HotSpotTargetMethod targetMethod, boolean installCode);
+
+    @Override
+    public native long installStub(HotSpotTargetMethod targetMethod);
+
+    @Override
+    public native HotSpotVMConfig getConfiguration();
+
+    @Override
+    public native RiMethod RiType_resolveMethodImpl(HotSpotTypeResolved klass, String name, String signature);
+
+    @Override
+    public native boolean RiType_isSubtypeOf(HotSpotTypeResolved klass, RiType other);
+
+    @Override
+    public native RiType RiType_leastCommonAncestor(HotSpotTypeResolved thisType, HotSpotTypeResolved otherType);
+
+    @Override
+    public native RiType getPrimitiveArrayType(CiKind kind);
+
+    @Override
+    public native RiType RiType_arrayOf(HotSpotTypeResolved klass);
+
+    @Override
+    public native RiType RiType_componentType(HotSpotTypeResolved klass);
+
+    @Override
+    public native RiType RiType_uniqueConcreteSubtype(HotSpotTypeResolved klass);
+
+    @Override
+    public native RiType RiType_superType(HotSpotTypeResolved klass);
+
+    @Override
+    public native boolean RiType_isInitialized(HotSpotTypeResolved klass);
+
+    @Override
+    public native HotSpotMethodData RiMethod_methodData(HotSpotMethodResolved method);
+
+    @Override
+    public native RiType getType(Class<?> javaClass);
+
+    @Override
+    public int getArrayLength(CiConstant array) {
+        return Array.getLength(array.asObject());
+    }
+
+    @Override
+    public boolean compareConstantObjects(CiConstant x, CiConstant y) {
+        return x.asObject() == y.asObject();
+    }
+
+    @Override
+    public RiType getRiType(CiConstant constant) {
+        Object o = constant.asObject();
+        if (o == null) {
+            return null;
+        }
+        return getType(o.getClass());
+    }
+
+    @Override
+    public native RiResolvedField[] RiType_fields(HotSpotTypeResolved klass);
+
+    @Override
+    public native boolean RiMethod_hasCompiledCode(HotSpotMethodResolved method);
+
+    @Override
+    public native int RiMethod_getCompiledCodeSize(HotSpotMethodResolved method);
+
+    @Override
+    public native long getMaxCallTargetOffset(CiRuntimeCall rtcall);
+
+    @Override
+    public native String disassembleNative(byte[] code, long address);
+
+    @Override
+    public native String disassembleJava(HotSpotMethodResolved method);
+
+    // Checkstyle: resume
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/VMToCompiler.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,62 @@
+/*
+ * 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.max.graal.hotspot.bridge;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.hotspot.ri.*;
+
+/**
+ * Calls from HotSpot into Java.
+ */
+public interface VMToCompiler {
+
+    void compileMethod(HotSpotMethodResolved method, int entryBCI, boolean blocking) throws Throwable;
+
+    void shutdownCompiler() throws Throwable;
+
+    void startCompiler() throws Throwable;
+
+    void bootstrap() throws Throwable;
+
+    RiMethod createRiMethodUnresolved(String name, String signature, RiType holder);
+
+    RiSignature createRiSignature(String signature);
+
+    RiField createRiField(RiType holder, String name, RiType type, int offset, int flags);
+
+    RiType createRiType(HotSpotConstantPool pool, String name);
+
+    RiType createRiTypePrimitive(int basicType);
+
+    RiType createRiTypeUnresolved(String name);
+
+    CiConstant createCiConstant(CiKind kind, long value);
+
+    CiConstant createCiConstantFloat(float value);
+
+    CiConstant createCiConstantDouble(double value);
+
+    CiConstant createCiConstantObject(Object object);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/VMToCompilerImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.hotspot.bridge;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.compiler.phases.PhasePlan.PhasePosition;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.debug.internal.*;
+import com.oracle.max.graal.hotspot.*;
+import com.oracle.max.graal.hotspot.Compiler;
+import com.oracle.max.graal.hotspot.ri.*;
+import com.oracle.max.graal.hotspot.server.*;
+import com.oracle.max.graal.hotspot.snippets.*;
+import com.oracle.max.graal.java.*;
+import com.oracle.max.graal.snippets.*;
+
+/**
+ * Exits from the HotSpot VM into Java code.
+ */
+public class VMToCompilerImpl implements VMToCompiler, Remote {
+
+    private final Compiler compiler;
+    private int compiledMethodCount;
+    private long totalCompilationTime;
+    private IntrinsifyArrayCopyPhase intrinsifyArrayCopy;
+
+    public final HotSpotTypePrimitive typeBoolean;
+    public final HotSpotTypePrimitive typeChar;
+    public final HotSpotTypePrimitive typeFloat;
+    public final HotSpotTypePrimitive typeDouble;
+    public final HotSpotTypePrimitive typeByte;
+    public final HotSpotTypePrimitive typeShort;
+    public final HotSpotTypePrimitive typeInt;
+    public final HotSpotTypePrimitive typeLong;
+    public final HotSpotTypePrimitive typeVoid;
+
+    ThreadFactory compilerThreadFactory = new ThreadFactory() {
+
+        @Override
+        public Thread newThread(Runnable r) {
+            return new CompilerThread(r);
+        }
+    };
+
+    private final class CompilerThread extends Thread {
+
+        public CompilerThread(Runnable r) {
+            super(r);
+            this.setName("GraalCompilerThread-" + this.getId());
+            this.setDaemon(true);
+        }
+
+        @Override
+        public void run() {
+            if (GraalOptions.Debug) {
+                Debug.enable();
+                HotSpotDebugConfig hotspotDebugConfig = new HotSpotDebugConfig(GraalOptions.Log, GraalOptions.Meter, GraalOptions.Time, GraalOptions.Dump, GraalOptions.MethodFilter);
+                Debug.setConfig(hotspotDebugConfig);
+            }
+            super.run();
+        }
+    }
+
+    private ThreadPoolExecutor compileQueue;
+
+    public VMToCompilerImpl(Compiler compiler) {
+        this.compiler = compiler;
+
+        typeBoolean = new HotSpotTypePrimitive(compiler, CiKind.Boolean);
+        typeChar = new HotSpotTypePrimitive(compiler, CiKind.Char);
+        typeFloat = new HotSpotTypePrimitive(compiler, CiKind.Float);
+        typeDouble = new HotSpotTypePrimitive(compiler, CiKind.Double);
+        typeByte = new HotSpotTypePrimitive(compiler, CiKind.Byte);
+        typeShort = new HotSpotTypePrimitive(compiler, CiKind.Short);
+        typeInt = new HotSpotTypePrimitive(compiler, CiKind.Int);
+        typeLong = new HotSpotTypePrimitive(compiler, CiKind.Long);
+        typeVoid = new HotSpotTypePrimitive(compiler, CiKind.Void);
+    }
+
+    public void startCompiler() throws Throwable {
+        // Make sure TTY is initialized here such that the correct System.out is used for TTY.
+        TTY.initialize();
+        if (GraalOptions.Debug) {
+            Debug.enable();
+            HotSpotDebugConfig hotspotDebugConfig = new HotSpotDebugConfig(GraalOptions.Log, GraalOptions.Meter, GraalOptions.Time, GraalOptions.Dump, GraalOptions.MethodFilter);
+            Debug.setConfig(hotspotDebugConfig);
+        }
+
+        // Install intrinsics.
+        final HotSpotRuntime runtime = (HotSpotRuntime) compiler.getCompiler().runtime;
+        if (GraalOptions.Intrinsify) {
+            Debug.scope("InstallSnippets", new DebugDumpScope("InstallSnippets"), new Runnable() {
+                @Override
+                public void run() {
+                    VMToCompilerImpl.this.intrinsifyArrayCopy = new IntrinsifyArrayCopyPhase(runtime);
+                    GraalIntrinsics.installIntrinsics(runtime, runtime.getCompiler().getTarget(), PhasePlan.DEFAULT);
+                    Snippets.install(runtime, runtime.getCompiler().getTarget(), new SystemSnippets(), PhasePlan.DEFAULT);
+                    Snippets.install(runtime, runtime.getCompiler().getTarget(), new UnsafeSnippets(), PhasePlan.DEFAULT);
+                    Snippets.install(runtime, runtime.getCompiler().getTarget(), new ArrayCopySnippets(), PhasePlan.DEFAULT);
+                }
+            });
+
+        }
+
+        // Create compilation queue.
+        compileQueue = new ThreadPoolExecutor(GraalOptions.Threads, GraalOptions.Threads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), compilerThreadFactory);
+
+        // Create queue status printing thread.
+        if (GraalOptions.PrintQueue) {
+            Thread t = new Thread() {
+
+                @Override
+                public void run() {
+                    while (true) {
+                        TTY.println(compileQueue.toString());
+                        try {
+                            Thread.sleep(1000);
+                        } catch (InterruptedException e) {
+                        }
+                    }
+                }
+            };
+            t.setDaemon(true);
+            t.start();
+        }
+    }
+
+    /**
+     * This method is the first method compiled during bootstrapping. Put any code in there that warms up compiler paths
+     * that are otherwise no exercised during bootstrapping and lead to later deoptimization when application code is
+     * compiled.
+     */
+    @SuppressWarnings("unused")
+    @Deprecated
+    private synchronized void compileWarmup() {
+        // Method is synchronized to exercise the synchronization code in the compiler.
+    }
+
+    public void bootstrap() throws Throwable {
+        TTY.print("Bootstrapping Graal");
+        TTY.flush();
+        long startTime = System.currentTimeMillis();
+
+        // Initialize compile queue with a selected set of methods.
+        Class<Object> objectKlass = Object.class;
+        enqueue(getClass().getDeclaredMethod("compileWarmup"));
+        enqueue(objectKlass.getDeclaredMethod("equals", Object.class));
+        enqueue(objectKlass.getDeclaredMethod("toString"));
+
+        // Compile until the queue is empty.
+        int z = 0;
+        while (compileQueue.getCompletedTaskCount() < Math.max(3, compileQueue.getTaskCount())) {
+            Thread.sleep(100);
+            while (z < compileQueue.getCompletedTaskCount() / 100) {
+                ++z;
+                TTY.print(".");
+                TTY.flush();
+            }
+        }
+
+        TTY.println(" in %d ms", System.currentTimeMillis() - startTime);
+        System.gc();
+    }
+
+    private void enqueue(Method m) throws Throwable {
+        RiMethod riMethod = compiler.getRuntime().getRiMethod(m);
+        assert !Modifier.isAbstract(((HotSpotMethodResolved) riMethod).accessFlags()) && !Modifier.isNative(((HotSpotMethodResolved) riMethod).accessFlags()) : riMethod;
+        compileMethod((HotSpotMethodResolved) riMethod, 0, false);
+    }
+
+    public void shutdownCompiler() throws Throwable {
+// compiler.getCompiler().context.print();
+        // TODO(tw): Print context results.
+        compileQueue.shutdown();
+
+        if (Debug.isEnabled()) {
+            List<DebugValueMap> topLevelMaps = DebugValueMap.getTopLevelMaps();
+            List<DebugValue> debugValues = KeyRegistry.getDebugValues();
+            if (debugValues.size() > 0) {
+                if (GraalOptions.SummarizeDebugValues) {
+                    printSummary(topLevelMaps, debugValues);
+                } else {
+                    for (DebugValueMap map : topLevelMaps) {
+                        TTY.println("Showing the results for thread: " + map.getName());
+                        map.group();
+                        map.normalize();
+                        printMap(map, debugValues, 0);
+                    }
+                }
+            }
+        }
+
+        if (GraalOptions.PrintCompilationStatistics) {
+            printCompilationStatistics();
+        }
+    }
+
+    private void printCompilationStatistics() {
+        TTY.println("Accumulated compilation statistics");
+        TTY.println("  Compiled methods         : %d", compiledMethodCount);
+        TTY.println("  Total compilation time   : %6.3f s", totalCompilationTime / Math.pow(10, 9));
+    }
+
+    private static void printSummary(List<DebugValueMap> topLevelMaps, List<DebugValue> debugValues) {
+        DebugValueMap result = new DebugValueMap("Summary");
+        for (int i = debugValues.size() - 1; i >= 0; i--) {
+            DebugValue debugValue = debugValues.get(i);
+            int index = debugValue.getIndex();
+            long total = collectTotal(topLevelMaps, index);
+            result.setCurrentValue(index, total);
+        }
+        printMap(result, debugValues, 0);
+    }
+
+    private static long collectTotal(List<DebugValueMap> maps, int index) {
+        long total = 0;
+        for (int i = 0; i < maps.size(); i++) {
+            DebugValueMap map = maps.get(i);
+            // the top level accumulates some counters -> do not process the children if we find a value
+            long value = map.getCurrentValue(index);
+            if (value == 0) {
+                total += collectTotal(map.getChildren(), index);
+            } else {
+                total += value;
+            }
+        }
+        return total;
+    }
+
+
+    private static void printMap(DebugValueMap map, List<DebugValue> debugValues, int level) {
+
+        printIndent(level);
+        TTY.println(map.getName());
+        for (DebugValue value : debugValues) {
+            long l = map.getCurrentValue(value.getIndex());
+            if (l != 0) {
+                printIndent(level + 1);
+                TTY.println(value.getName() + "=" + l);
+            }
+        }
+
+        for (DebugValueMap child : map.getChildren()) {
+            printMap(child, debugValues, level + 1);
+        }
+    }
+
+    private static void printIndent(int level) {
+        for (int i = 0; i < level; ++i) {
+            TTY.print("    ");
+        }
+        TTY.print("|-> ");
+    }
+
+    @Override
+    public void compileMethod(final HotSpotMethodResolved method, final int entryBCI, boolean blocking) throws Throwable {
+        try {
+            if (Thread.currentThread() instanceof CompilerThread) {
+                if (method.holder().name().contains("java/util/concurrent")) {
+                    // This is required to avoid deadlocking a compiler thread. The issue is that a
+                    // java.util.concurrent.BlockingQueue is used to implement the compilation worker
+                    // queues. If a compiler thread triggers a compilation, then it may be blocked trying
+                    // to add something to its own queue.
+                    return;
+                }
+            }
+
+            Runnable runnable = new Runnable() {
+
+                public void run() {
+                    try {
+                        final PhasePlan plan = getDefaultPhasePlan();
+                        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(compiler.getRuntime());
+                        plan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
+                        long startTime = System.nanoTime();
+                        int index = compiledMethodCount++;
+                        final boolean printCompilation = GraalOptions.PrintCompilation && !TTY.isSuppressed();
+                        if (printCompilation) {
+                            TTY.println(String.format("Graal %4d %-70s %-45s %-50s ...", index, method.holder().name(), method.name(), method.signature().asString()));
+                        }
+
+                        CiTargetMethod result = null;
+                        TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, method);
+                        long nanoTime;
+                        try {
+                            result = Debug.scope("Compiling", method, new Callable<CiTargetMethod>() {
+                                @Override
+                                public CiTargetMethod call() throws Exception {
+                                    return compiler.getCompiler().compileMethod(method, -1, plan);
+                                }
+                            });
+                        } finally {
+                            filter.remove();
+                            nanoTime = System.nanoTime() - startTime;
+                            totalCompilationTime += nanoTime;
+                            if (printCompilation) {
+                                TTY.println(String.format("Graal %4d %-70s %-45s %-50s | %3d.%dms %4dnodes %5dB", index, "", "", "", nanoTime / 1000000, nanoTime % 1000000, 0, (result != null ? result.targetCodeSize()
+                                                : -1)));
+                            }
+                        }
+                        compiler.getRuntime().installMethod(method, result);
+                    } catch (CiBailout bailout) {
+                        Debug.metric("Bailouts").increment();
+                        if (GraalOptions.ExitVMOnBailout) {
+                            bailout.printStackTrace(TTY.cachedOut);
+                            System.exit(-1);
+                        }
+                    } catch (Throwable t) {
+                        if (GraalOptions.ExitVMOnException) {
+                            t.printStackTrace(TTY.cachedOut);
+                            System.exit(-1);
+                        }
+                    }
+                }
+            };
+
+            if (blocking) {
+                runnable.run();
+            } else {
+                compileQueue.execute(runnable);
+            }
+        } catch (RejectedExecutionException e) {
+            // The compile queue was already shut down.
+            return;
+        }
+    }
+
+    @Override
+    public RiMethod createRiMethodUnresolved(String name, String signature, RiType holder) {
+        return new HotSpotMethodUnresolved(compiler, name, signature, holder);
+    }
+
+    @Override
+    public RiSignature createRiSignature(String signature) {
+        return new HotSpotSignature(compiler, signature);
+    }
+
+    @Override
+    public RiField createRiField(RiType holder, String name, RiType type, int offset, int flags) {
+        if (offset != -1) {
+            HotSpotTypeResolved resolved = (HotSpotTypeResolved) holder;
+            return resolved.createRiField(name, type, offset, flags);
+        }
+        return new BaseUnresolvedField(holder, name, type);
+    }
+
+    @Override
+    public RiType createRiType(HotSpotConstantPool pool, String name) {
+        throw new RuntimeException("not implemented");
+    }
+
+    @Override
+    public RiType createRiTypePrimitive(int basicType) {
+        switch (basicType) {
+            case 4:
+                return typeBoolean;
+            case 5:
+                return typeChar;
+            case 6:
+                return typeFloat;
+            case 7:
+                return typeDouble;
+            case 8:
+                return typeByte;
+            case 9:
+                return typeShort;
+            case 10:
+                return typeInt;
+            case 11:
+                return typeLong;
+            case 14:
+                return typeVoid;
+            default:
+                throw new IllegalArgumentException("Unknown basic type: " + basicType);
+        }
+    }
+
+    @Override
+    public RiType createRiTypeUnresolved(String name) {
+        return new HotSpotTypeUnresolved(compiler, name);
+    }
+
+    @Override
+    public CiConstant createCiConstant(CiKind kind, long value) {
+        if (kind == CiKind.Long) {
+            return CiConstant.forLong(value);
+        } else if (kind == CiKind.Int) {
+            return CiConstant.forInt((int) value);
+        } else if (kind == CiKind.Short) {
+            return CiConstant.forShort((short) value);
+        } else if (kind == CiKind.Char) {
+            return CiConstant.forChar((char) value);
+        } else if (kind == CiKind.Byte) {
+            return CiConstant.forByte((byte) value);
+        } else if (kind == CiKind.Boolean) {
+            return (value == 0) ? CiConstant.FALSE : CiConstant.TRUE;
+        } else {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    @Override
+    public CiConstant createCiConstantFloat(float value) {
+        return CiConstant.forFloat(value);
+    }
+
+    @Override
+    public CiConstant createCiConstantDouble(double value) {
+        return CiConstant.forDouble(value);
+    }
+
+    @Override
+    public CiConstant createCiConstantObject(Object object) {
+        return CiConstant.forObject(object);
+    }
+
+    private PhasePlan getDefaultPhasePlan() {
+        PhasePlan phasePlan = new PhasePlan();
+        if (GraalOptions.Intrinsify) {
+            phasePlan.addPhase(PhasePosition.HIGH_LEVEL, intrinsifyArrayCopy);
+        }
+        return phasePlan;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/logging/CountingProxy.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,107 @@
+/*
+ * 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.max.graal.hotspot.logging;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+
+import com.oracle.max.graal.hotspot.server.*;
+
+/**
+ * A java.lang.reflect proxy that hierarchically logs all method invocations along with their parameters and return
+ * values.
+ */
+public class CountingProxy<T> implements InvocationHandler {
+
+    public static final boolean ENABLED = Boolean.valueOf(System.getProperty("graal.countcalls"));
+
+    private T delegate;
+
+    private ConcurrentHashMap<Method, AtomicLong> calls = new ConcurrentHashMap<>();
+
+    public CountingProxy(T delegate) {
+        assert ENABLED;
+        System.out.println("Counting proxy for " + delegate.getClass().getSimpleName() + " created");
+        this.delegate = delegate;
+        proxies.add(this);
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        int argCount = args == null ? 0 : args.length;
+        if (method.getParameterTypes().length != argCount) {
+            throw new RuntimeException("wrong parameter count");
+        }
+        final Object result;
+        if (!calls.containsKey(method)) {
+            calls.putIfAbsent(method, new AtomicLong(0));
+        }
+        AtomicLong count = calls.get(method);
+        count.incrementAndGet();
+        try {
+            if (args == null) {
+                result = method.invoke(delegate);
+            } else {
+                result = method.invoke(delegate, args);
+            }
+        } catch (InvocationTargetException e) {
+            throw e.getCause();
+        }
+        return result;
+    }
+
+    public static <T> T getProxy(Class<T> interf, T delegate) {
+        Class<?>[] interfaces = ReplacingStreams.getAllInterfaces(delegate.getClass());
+        Object obj = Proxy.newProxyInstance(interf.getClassLoader(), interfaces, new CountingProxy<>(delegate));
+        return interf.cast(obj);
+    }
+
+    private static ArrayList<CountingProxy> proxies = new ArrayList<>();
+
+    static {
+        if (ENABLED) {
+            Runtime.getRuntime().addShutdownHook(new Thread() {
+
+                @Override
+                public void run() {
+                    for (CountingProxy proxy : proxies) {
+                        proxy.print();
+                    }
+                }
+            });
+        }
+    }
+
+    protected void print() {
+        long sum = 0;
+        for (Map.Entry<Method, AtomicLong> entry : calls.entrySet()) {
+            Method method = entry.getKey();
+            long count = entry.getValue().get();
+            sum += count;
+            System.out.println(delegate.getClass().getSimpleName() + "." + method.getName() + ": " + count);
+        }
+        System.out.println(delegate.getClass().getSimpleName() + " calls: " + sum);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/logging/Logger.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,170 @@
+/*
+ * 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.max.graal.hotspot.logging;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+/**
+ * Scoped logging class used to display the call hierarchy of VMEntries/VMExits calls.
+ */
+public class Logger {
+
+    public static final boolean ENABLED = Boolean.valueOf(System.getProperty("graal.debug"));
+    private static final int SPACING = 4;
+    private static Deque<Boolean> openStack = new LinkedList<>();
+    private static boolean open = false;
+    private static int level = 0;
+
+    private static final PrintStream out;
+
+    static {
+        PrintStream ps = null;
+        String filename = System.getProperty("graal.info_file");
+        if (filename != null && !"".equals(filename)) {
+            try {
+                ps = new PrintStream(new FileOutputStream(filename));
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+                ps = null;
+            }
+        }
+        out = ps;
+        if (out != null) {
+            out.println("start: " + new Date());
+        }
+    }
+
+    public static void info(String message) {
+        if (ENABLED) {
+            log(message);
+        } else {
+            System.out.println(message);
+        }
+        if (out != null) {
+            out.println(message);
+            out.flush();
+        }
+    }
+
+    public static void log(String message) {
+        if (ENABLED) {
+            for (String line : message.split("\n")) {
+                if (open) {
+                    System.out.println("...");
+                    open = false;
+                }
+                System.out.print(space(level));
+                System.out.println(line);
+            }
+        }
+    }
+
+    public static void startScope(String message) {
+        if (ENABLED) {
+            if (open) {
+                System.out.println("...");
+                open = false;
+            }
+            System.out.print(space(level));
+            System.out.print(message);
+            openStack.push(open);
+            open = true;
+            level++;
+        }
+    }
+
+    public static void endScope(String message) {
+        if (ENABLED) {
+            level--;
+            if (open) {
+                System.out.println(message);
+            } else {
+                System.out.println(space(level) + "..." + message);
+            }
+            open = openStack.pop();
+        }
+    }
+
+    private static String[] spaces = new String[50];
+
+    private static String space(int count) {
+        assert count >= 0;
+        String result;
+        if (count >= spaces.length || spaces[count] == null) {
+            StringBuilder str = new StringBuilder();
+            for (int i = 0; i < count * SPACING; i++) {
+                str.append(' ');
+            }
+            result = str.toString();
+            if (count < spaces.length) {
+                spaces[count] = result;
+            }
+        } else {
+            result = spaces[count];
+        }
+        return result;
+    }
+
+    public static String pretty(Object value) {
+        if (value == null) {
+            return "null";
+        }
+
+        Class<?> klass = value.getClass();
+        if (value instanceof Void) {
+            return "void";
+        } else if (value instanceof String) {
+            return "\"" + value + "\"";
+        } else if (value instanceof Method) {
+            return "method \"" + ((Method) value).getName() + "\"";
+        } else if (value instanceof Class<?>) {
+            return "class \"" + ((Class<?>) value).getSimpleName() + "\"";
+        } else if (value instanceof Integer) {
+            if ((Integer) value < 10) {
+                return value.toString();
+            }
+            return value + " (0x" + Integer.toHexString((Integer) value) + ")";
+        } else if (value instanceof Long) {
+            if ((Long) value < 10) {
+                return value + "l";
+            }
+            return value + "l (0x" + Long.toHexString((Long) value) + "l)";
+        } else if (klass.isArray()) {
+            StringBuilder str = new StringBuilder();
+            int dimensions = 0;
+            while (klass.isArray()) {
+                dimensions++;
+                klass = klass.getComponentType();
+            }
+            str.append(klass.getSimpleName()).append('[').append(Array.getLength(value)).append(']');
+            for (int i = 1; i < dimensions; i++) {
+                str.append("[]");
+            }
+            return str.toString();
+        }
+
+        return value.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/logging/LoggingProxy.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,77 @@
+/*
+ * 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.max.graal.hotspot.logging;
+
+import java.lang.reflect.*;
+
+import com.oracle.max.graal.hotspot.server.*;
+
+/**
+ * A java.lang.reflect proxy that hierarchically logs all method invocations along with their parameters and return values.
+ */
+public class LoggingProxy<T> implements InvocationHandler {
+
+    private T delegate;
+
+    public LoggingProxy(T delegate) {
+        this.delegate = delegate;
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        int argCount = args == null ? 0 : args.length;
+        if (method.getParameterTypes().length != argCount) {
+            throw new RuntimeException("wrong parameter count");
+        }
+        StringBuilder str = new StringBuilder();
+        str.append(method.getReturnType().getSimpleName() + " " + method.getDeclaringClass().getSimpleName() + "." + method.getName() + "(");
+        for (int i = 0; i < argCount; i++) {
+            str.append(i == 0 ? "" : ", ");
+            str.append(Logger.pretty(args[i]));
+        }
+        str.append(")");
+        Logger.startScope(str.toString());
+        final Object result;
+        try {
+            if (args == null) {
+                result = method.invoke(delegate);
+            } else {
+                result = method.invoke(delegate, args);
+            }
+        } catch (InvocationTargetException e) {
+            Logger.endScope(" = Exception " + e.getMessage());
+            throw e.getCause();
+        }
+        Logger.endScope(" = " + Logger.pretty(result));
+        return result;
+    }
+
+    /**
+     * The object returned by this method will implement all interfaces that are implemented by delegate.
+     */
+    public static <T> T getProxy(Class<T> interf, T delegate) {
+        Class<?>[] interfaces = ReplacingStreams.getAllInterfaces(delegate.getClass());
+        Object obj = Proxy.newProxyInstance(interf.getClassLoader(), interfaces, new LoggingProxy<>(delegate));
+        return interf.cast(obj);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/logging/package-info.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/**
+ * Logging framework for the HotSpot CRI implementation.
+ */
+package com.oracle.max.graal.hotspot.logging;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/nodes/ArrayWriteBarrier.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * 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.max.graal.hotspot.nodes;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+public final class ArrayWriteBarrier extends WriteBarrier implements LIRLowerable {
+
+    @Input private ValueNode object;
+    @Input private LocationNode location;
+
+    public ValueNode object() {
+        return object;
+    }
+
+    public LocationNode location() {
+        return location;
+    }
+
+    public ArrayWriteBarrier(ValueNode object, LocationNode location) {
+        this.object = object;
+        this.location = location;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        CiValue obj = gen.emitLea(gen.makeAddress(location(), object()));
+        generateBarrier(obj, gen);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/nodes/CurrentThread.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.hotspot.nodes;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public final class CurrentThread extends FloatingNode implements LIRLowerable {
+
+    private int threadObjectOffset;
+
+    public CurrentThread(int threadObjectOffset) {
+        super(StampFactory.forKind(CiKind.Object));
+        this.threadObjectOffset = threadObjectOffset;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool generator) {
+        generator.setResult(this, generator.emitLoad(new CiAddress(CiKind.Object, AMD64.r15.asValue(generator.target().wordKind), threadObjectOffset), false));
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static Object get(int threadObjectOffset) {
+        throw new UnsupportedOperationException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/nodes/FieldWriteBarrier.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * 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.max.graal.hotspot.nodes;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+public final class FieldWriteBarrier extends WriteBarrier implements LIRLowerable {
+
+    @Input private ValueNode object;
+
+    public ValueNode object() {
+        return object;
+    }
+
+    public FieldWriteBarrier(ValueNode object) {
+        this.object = object;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool generator) {
+        CiValue obj = generator.newVariable(generator.target().wordKind);
+        generator.emitMove(generator.operand(object()), obj);
+        generateBarrier(obj, generator);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/nodes/TailcallNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,77 @@
+/*
+ * 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.max.graal.hotspot.nodes;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.compiler.gen.*;
+import com.oracle.max.graal.hotspot.*;
+import com.oracle.max.graal.hotspot.target.amd64.*;
+import com.oracle.max.graal.java.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * Performs a tail call to the specified target compiled method, with the parameter taken from the supplied FrameState.
+ */
+public class TailcallNode extends FixedWithNextNode implements LIRLowerable {
+
+    @Input private final FrameState frameState;
+    @Input private final ValueNode target;
+
+    /**
+     * Creates a TailcallNode.
+     * @param target points to the start of an nmethod
+     * @param frameState the parameters will be taken from this FrameState
+     */
+    public TailcallNode(ValueNode target, FrameState frameState) {
+        super(StampFactory.illegal());
+        this.target = target;
+        this.frameState = frameState;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool generator) {
+        LIRGenerator gen = (LIRGenerator) generator;
+        HotSpotVMConfig config = CompilerImpl.getInstance().getConfig();
+        RiResolvedMethod method = frameState.method();
+        boolean isStatic = Modifier.isStatic(method.accessFlags());
+
+        CiKind[] signature = CiUtil.signatureToKinds(method.signature(), isStatic ? null : method.holder().kind(true));
+        CiCallingConvention cc = gen.frameMap().registerConfig.getCallingConvention(CiCallingConvention.Type.JavaCall, signature, gen.target(), false);
+        gen.frameMap().callsMethod(cc, CiCallingConvention.Type.JavaCall); // TODO (aw): I think this is unnecessary for a tail call.
+        List<ValueNode> parameters = new ArrayList<>();
+        for (int i = 0, slot = 0; i < cc.locations.length; i++, slot += FrameStateBuilder.stackSlots(frameState.localAt(slot).kind())) {
+            parameters.add(frameState.localAt(slot));
+        }
+        List<CiValue> argList = gen.visitInvokeArguments(cc, parameters);
+
+        CiValue entry = gen.emitLoad(new CiAddress(CiKind.Long, gen.operand(target), config.nmethodEntryOffset), false);
+
+        gen.append(new AMD64TailcallOp(argList, entry, cc.locations));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/nodes/WriteBarrier.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.hotspot.nodes;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.hotspot.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public abstract class WriteBarrier extends FixedWithNextNode {
+
+    public WriteBarrier() {
+        super(StampFactory.illegal());
+    }
+
+    protected void generateBarrier(CiValue obj, LIRGeneratorTool gen) {
+        HotSpotVMConfig config = CompilerImpl.getInstance().getConfig();
+        CiValue base = gen.emitUShr(obj, CiConstant.forInt(config.cardtableShift));
+
+        long startAddress = config.cardtableStartAddress;
+        int displacement = 0;
+        if (((int) startAddress) == startAddress) {
+            displacement = (int) startAddress;
+        } else {
+            base = gen.emitAdd(base, CiConstant.forLong(config.cardtableStartAddress));
+        }
+        gen.emitStore(new CiAddress(CiKind.Boolean, base, displacement), CiConstant.FALSE, false);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/package-info.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,28 @@
+/*
+ * 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 containing the runtime interface (defined in the CRI project) implementation for HotSpot.
+ * There is a class that bridges from the C++ to the Java side (VMExitsNative.java) and one that bridges
+ * from the Java to the C++ side (VMEntriesNative.java).
+ */
+package com.oracle.max.graal.hotspot;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotCompiledMethod.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+import com.oracle.max.cri.ri.*;
+
+/**
+ * Implementation of RiCompiledMethod for HotSpot. Stores a reference to the nmethod which contains the compiled code.
+ */
+public class HotSpotCompiledMethod implements RiCompiledMethod {
+
+    private final RiResolvedMethod method;
+    private long nmethod;
+
+    public HotSpotCompiledMethod(RiResolvedMethod method) {
+        this.method = method;
+    }
+
+    @Override
+    public RiResolvedMethod method() {
+        return method;
+    }
+
+    @Override
+    public boolean isValid() {
+        return nmethod != 0;
+    }
+
+    @Override
+    public String toString() {
+        return "compiled method " + method + " @" + nmethod;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotConstantPool.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.hotspot.*;
+import com.oracle.max.graal.hotspot.Compiler;
+
+/**
+ * Implementation of RiConstantPool for HotSpot.
+ */
+public class HotSpotConstantPool extends CompilerObject implements RiConstantPool {
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -5443206401485234850L;
+    private final HotSpotTypeResolvedImpl type;
+
+    public HotSpotConstantPool(Compiler compiler, HotSpotTypeResolvedImpl type) {
+        super(compiler);
+        this.type = type;
+    }
+
+    @Override
+    public Object lookupConstant(int cpi) {
+        Object constant = compiler.getVMEntries().RiConstantPool_lookupConstant(type, cpi);
+        return constant;
+    }
+
+    @Override
+    public RiSignature lookupSignature(int cpi) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public RiMethod lookupMethod(int cpi, int byteCode) {
+        return compiler.getVMEntries().RiConstantPool_lookupMethod(type, cpi, (byte) byteCode);
+    }
+
+    @Override
+    public RiType lookupType(int cpi, int opcode) {
+        return compiler.getVMEntries().RiConstantPool_lookupType(type, cpi);
+    }
+
+    @Override
+    public RiField lookupField(int cpi, int opcode) {
+        return compiler.getVMEntries().RiConstantPool_lookupField(type, cpi, (byte) opcode);
+    }
+
+    @Override
+    public void loadReferencedType(int cpi, int bytecode) {
+        compiler.getVMEntries().RiConstantPool_loadReferencedType(type, cpi, (byte) bytecode);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotExceptionHandler.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,78 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.hotspot.*;
+
+
+public class HotSpotExceptionHandler extends CompilerObject implements RiExceptionHandler {
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 7110038548061733686L;
+    private int startBci;
+    private int endBci;
+    private int handlerBci;
+    private int catchClassIndex;
+    private RiType catchClass;
+
+    public HotSpotExceptionHandler() {
+        super(null);
+    }
+
+    @Override
+    public int startBCI() {
+        return startBci;
+    }
+
+    @Override
+    public int endBCI() {
+        return endBci;
+    }
+
+    @Override
+    public int handlerBCI() {
+        return handlerBci;
+    }
+
+    @Override
+    public int catchTypeCPI() {
+        return catchClassIndex;
+    }
+
+    @Override
+    public boolean isCatchAll() {
+        return catchClassIndex == 0;
+    }
+
+    @Override
+    public RiType catchType() {
+        return catchClass;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("HotSpotExceptionHandler[startBci=%d, endBci=%d, handlerBci=%d, catchClassIndex=%d, catchClass=%s", startBci, endBci, handlerBci, catchClassIndex, catchClass);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotField.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,138 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.cri.ri.RiType.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.hotspot.*;
+import com.oracle.max.graal.hotspot.Compiler;
+
+/**
+ * Represents a field in a HotSpot type.
+ */
+public class HotSpotField extends CompilerObject implements RiResolvedField {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 7692985878836955683L;
+    private final RiResolvedType holder;
+    private final String name;
+    private final RiType type;
+    private final int offset;
+    private final int accessFlags;
+    private CiConstant constant;                // Constant part only valid for static fields.
+
+    public HotSpotField(Compiler compiler, RiResolvedType holder, String name, RiType type, int offset, int accessFlags) {
+        super(compiler);
+        this.holder = holder;
+        this.name = name;
+        this.type = type;
+        assert offset != -1;
+        this.offset = offset;
+        this.accessFlags = accessFlags;
+    }
+
+    @Override
+    public int accessFlags() {
+        return accessFlags;
+    }
+
+    @Override
+    public CiConstant constantValue(CiConstant receiver) {
+        if (receiver == null) {
+            assert Modifier.isStatic(accessFlags);
+            if (constant == null) {
+                if (holder.isInitialized() && holder.toJava() != System.class) {
+                    if (Modifier.isFinal(accessFlags()) || assumeStaticFieldsFinal(holder.toJava())) {
+                        CiConstant encoding = holder.getEncoding(Representation.StaticFields);
+                        constant = this.kind(false).readUnsafeConstant(encoding.asObject(), offset);
+                    }
+                }
+            }
+            return constant;
+        } else {
+            assert !Modifier.isStatic(accessFlags);
+            if (Modifier.isFinal(accessFlags())) {
+                return this.kind(false).readUnsafeConstant(receiver.asObject(), offset);
+            }
+        }
+        return null;
+    }
+
+    private static boolean assumeStaticFieldsFinal(Class< ? > clazz) {
+        return clazz == GraalOptions.class;
+    }
+
+    @Override
+    public RiResolvedType holder() {
+        return holder;
+    }
+
+    @Override
+    public CiKind kind(boolean architecture) {
+        return type().kind(architecture);
+    }
+
+    @Override
+    public String name() {
+        return name;
+    }
+
+    @Override
+    public RiType type() {
+        return type;
+    }
+
+    public int offset() {
+        return offset;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotField<" + CiUtil.format("%h.%n", this) + ":" + offset + ">";
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        Field javaField = toJava();
+        if (javaField != null) {
+            return javaField.getAnnotation(annotationClass);
+        }
+        return null;
+    }
+
+    private Field toJava() {
+        try {
+            return holder.toJava().getDeclaredField(name);
+        } catch (NoSuchFieldException e) {
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethod.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.hotspot.*;
+import com.oracle.max.graal.hotspot.Compiler;
+
+public abstract class HotSpotMethod extends CompilerObject implements RiMethod {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 7167491397941960839L;
+    protected String name;
+
+    protected HotSpotMethod(Compiler compiler) {
+        super(compiler);
+    }
+
+    @Override
+    public final String name() {
+        return name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodData.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,577 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+import java.util.*;
+
+import sun.misc.*;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.hotspot.*;
+import com.oracle.max.graal.hotspot.Compiler;
+
+
+public final class HotSpotMethodData extends CompilerObject {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -8873133496591225071L;
+
+    static {
+        config = CompilerImpl.getInstance().getConfig();
+    }
+
+    // TODO (ch) use same logic as in NodeClass?
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+    private static final HotSpotMethodDataAccessor NO_DATA_NO_EXCEPTION_ACCESSOR = new NoMethodData(RiExceptionSeen.FALSE);
+    private static final HotSpotMethodDataAccessor NO_DATA_EXCEPTION_POSSIBLY_NOT_RECORDED_ACCESSOR = new NoMethodData(RiExceptionSeen.NOT_SUPPORTED);
+    private static final HotSpotVMConfig config;
+    // sorted by tag
+    private static final HotSpotMethodDataAccessor[] PROFILE_DATA_ACCESSORS = {
+        null, new BitData(), new CounterData(), new JumpData(),
+        new TypeCheckData(), new VirtualCallData(), new RetData(),
+        new BranchData(), new MultiBranchData(), new ArgInfoData()
+    };
+
+    private Object hotspotMirror;
+    private int normalDataSize;
+    private int extraDataSize;
+
+    private HotSpotMethodData(Compiler compiler) {
+        super(compiler);
+        throw new IllegalStateException("this constructor is never actually called, because the objects are allocated from within the VM");
+    }
+
+    public boolean hasNormalData() {
+        return normalDataSize > 0;
+    }
+
+    public boolean hasExtraData() {
+        return extraDataSize > 0;
+    }
+
+    public int getExtraDataBeginOffset() {
+        return normalDataSize;
+    }
+
+    public boolean isWithin(int position) {
+        return position >= 0 && position < normalDataSize + extraDataSize;
+    }
+
+    public HotSpotMethodDataAccessor getNormalData(int position) {
+        if (position >= normalDataSize) {
+            return null;
+        }
+
+        HotSpotMethodDataAccessor result = getData(position);
+        assert result != null : "NO_DATA tag is not allowed";
+        return result;
+    }
+
+    public HotSpotMethodDataAccessor getExtraData(int position) {
+        if (position >= normalDataSize + extraDataSize) {
+            return null;
+        }
+        return getData(position);
+    }
+
+    public static HotSpotMethodDataAccessor getNoDataAccessor(boolean exceptionPossiblyNotRecorded) {
+        if (exceptionPossiblyNotRecorded) {
+            return NO_DATA_EXCEPTION_POSSIBLY_NOT_RECORDED_ACCESSOR;
+        } else {
+            return NO_DATA_NO_EXCEPTION_ACCESSOR;
+        }
+    }
+
+    private HotSpotMethodDataAccessor getData(int position) {
+        assert position >= 0 : "out of bounds";
+        int tag = AbstractMethodData.readTag(this, position);
+        assert tag >= 0 && tag < PROFILE_DATA_ACCESSORS.length : "illegal tag";
+        return PROFILE_DATA_ACCESSORS[tag];
+    }
+
+    private int readUnsignedByte(int position, int offsetInBytes) {
+        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
+        return unsafe.getByte(hotspotMirror, fullOffsetInBytes) & 0xFF;
+    }
+
+    private int readUnsignedShort(int position, int offsetInBytes) {
+        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
+        return unsafe.getShort(hotspotMirror, fullOffsetInBytes) & 0xFFFF;
+    }
+
+    private long readUnsignedInt(int position, int offsetInBytes) {
+        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
+        return unsafe.getInt(hotspotMirror, fullOffsetInBytes) & 0xFFFFFFFFL;
+    }
+
+    private int readUnsignedIntAsSignedInt(int position, int offsetInBytes) {
+        long value = readUnsignedInt(position, offsetInBytes);
+        return truncateLongToInt(value);
+    }
+
+    private int readInt(int position, int offsetInBytes) {
+        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
+        return unsafe.getInt(hotspotMirror, fullOffsetInBytes);
+    }
+
+    private Object readObject(int position, int offsetInBytes) {
+        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
+        return unsafe.getObject(hotspotMirror, fullOffsetInBytes);
+    }
+
+    private static int truncateLongToInt(long value) {
+        return value > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) value;
+    }
+
+    private static int computeFullOffset(int position, int offsetInBytes) {
+        return config.methodDataOopDataOffset + position + offsetInBytes;
+    }
+
+    private static int cellIndexToOffset(int cells) {
+        return config.dataLayoutHeaderSize + cellsToBytes(cells);
+    }
+
+    private static int cellsToBytes(int cells) {
+        return cells * config.dataLayoutCellSize;
+    }
+
+    private abstract static class AbstractMethodData implements HotSpotMethodDataAccessor {
+        private static final int EXCEPTIONS_MASK = 0x80;
+
+        private final int tag;
+        private final int staticSize;
+
+        protected AbstractMethodData(int tag, int staticSize) {
+            this.tag = tag;
+            this.staticSize = staticSize;
+        }
+
+        public int getTag() {
+            return tag;
+        }
+
+        public static int readTag(HotSpotMethodData data, int position) {
+            return data.readUnsignedByte(position, config.dataLayoutTagOffset);
+        }
+
+        @Override
+        public int getBCI(HotSpotMethodData data, int position) {
+            return data.readUnsignedShort(position, config.dataLayoutBCIOffset);
+        }
+
+        @Override
+        public int getSize(HotSpotMethodData data, int position) {
+            return staticSize + getDynamicSize(data, position);
+        }
+
+        @Override
+        public RiExceptionSeen getExceptionSeen(HotSpotMethodData data, int position) {
+            return RiExceptionSeen.get((getFlags(data, position) & EXCEPTIONS_MASK) != 0);
+        }
+
+        @Override
+        public RiTypeProfile getTypeProfile(HotSpotMethodData data, int position) {
+            return null;
+        }
+
+        @Override
+        public double getBranchTakenProbability(HotSpotMethodData data, int position) {
+            return -1;
+        }
+
+        @Override
+        public double[] getSwitchProbabilities(HotSpotMethodData data, int position) {
+            return null;
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            return -1;
+        }
+
+        protected int getFlags(HotSpotMethodData data, int position) {
+            return data.readUnsignedByte(position, config.dataLayoutFlagsOffset);
+        }
+
+        protected int getDynamicSize(@SuppressWarnings("unused") HotSpotMethodData data, @SuppressWarnings("unused") int position) {
+            return 0;
+        }
+    }
+
+    private static class NoMethodData extends AbstractMethodData {
+        private static final int NO_DATA_TAG = 0;
+        private static final int NO_DATA_SIZE = cellIndexToOffset(0);
+
+        private final RiExceptionSeen exceptionSeen;
+
+        protected NoMethodData(RiExceptionSeen exceptionSeen) {
+            super(NO_DATA_TAG, NO_DATA_SIZE);
+            this.exceptionSeen = exceptionSeen;
+        }
+
+        @Override
+        public int getBCI(HotSpotMethodData data, int position) {
+            return -1;
+        }
+
+
+        @Override
+        public RiExceptionSeen getExceptionSeen(HotSpotMethodData data, int position) {
+            return exceptionSeen;
+        }
+    }
+
+    private static class BitData extends AbstractMethodData {
+        private static final int BIT_DATA_TAG = 1;
+        private static final int BIT_DATA_SIZE = cellIndexToOffset(0);
+        private static final int BIT_DATA_NULL_SEEN_FLAG = 0x01;
+
+        private BitData() {
+            super(BIT_DATA_TAG, BIT_DATA_SIZE);
+        }
+
+        protected BitData(int tag, int staticSize) {
+            super(tag, staticSize);
+        }
+
+        @SuppressWarnings("unused")
+        public boolean getNullSeen(HotSpotMethodData data, int position) {
+            return (getFlags(data, position) & BIT_DATA_NULL_SEEN_FLAG) != 0;
+        }
+    }
+
+    private static class CounterData extends BitData {
+        private static final int COUNTER_DATA_TAG = 2;
+        private static final int COUNTER_DATA_SIZE = cellIndexToOffset(1);
+        private static final int COUNTER_DATA_COUNT_OFFSET = cellIndexToOffset(0);
+
+        public CounterData() {
+            super(COUNTER_DATA_TAG, COUNTER_DATA_SIZE);
+        }
+
+        protected CounterData(int tag, int staticSize) {
+            super(tag, staticSize);
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            return getCounterValue(data, position);
+        }
+
+        protected int getCounterValue(HotSpotMethodData data, int position) {
+            return data.readUnsignedIntAsSignedInt(position, COUNTER_DATA_COUNT_OFFSET);
+        }
+    }
+
+    private static class JumpData extends AbstractMethodData {
+        private static final int JUMP_DATA_TAG = 3;
+        private static final int JUMP_DATA_SIZE = cellIndexToOffset(2);
+        protected static final int TAKEN_COUNT_OFFSET = cellIndexToOffset(0);
+        protected static final int TAKEN_DISPLACEMENT_OFFSET = cellIndexToOffset(1);
+
+        public JumpData() {
+            super(JUMP_DATA_TAG, JUMP_DATA_SIZE);
+        }
+
+        protected JumpData(int tag, int staticSize) {
+            super(tag, staticSize);
+        }
+
+        @Override
+        public double getBranchTakenProbability(HotSpotMethodData data, int position) {
+            return 1;
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            return data.readUnsignedIntAsSignedInt(position, TAKEN_COUNT_OFFSET);
+        }
+
+        @SuppressWarnings("unused")
+        public int getTakenDisplacement(HotSpotMethodData data, int position) {
+            return data.readInt(position, TAKEN_DISPLACEMENT_OFFSET);
+        }
+    }
+
+    private abstract static class AbstractTypeData extends CounterData {
+        private static final int RECEIVER_TYPE_DATA_ROW_SIZE = cellsToBytes(2);
+        private static final int RECEIVER_TYPE_DATA_SIZE = cellIndexToOffset(1) + RECEIVER_TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
+        private static final int RECEIVER_TYPE_DATA_FIRST_RECEIVER_OFFSET = cellIndexToOffset(1);
+        private static final int RECEIVER_TYPE_DATA_FIRST_COUNT_OFFSET = cellIndexToOffset(2);
+
+        protected AbstractTypeData(int tag) {
+            super(tag, RECEIVER_TYPE_DATA_SIZE);
+        }
+
+        @Override
+        public RiTypeProfile getTypeProfile(HotSpotMethodData data, int position) {
+            int typeProfileWidth = config.typeProfileWidth;
+
+            RiResolvedType[] sparseTypes = new RiResolvedType[typeProfileWidth];
+            double[] counts = new double[typeProfileWidth];
+            long totalCount = 0;
+            int entries = 0;
+
+            for (int i = 0; i < typeProfileWidth; i++) {
+                Object receiverKlassOop = data.readObject(position, getReceiverOffset(i));
+                if (receiverKlassOop != null) {
+                    Object graalMirror = unsafe.getObject(receiverKlassOop, (long) config.graalMirrorKlassOffset);
+                    if (graalMirror == null) {
+                        Class<?> javaClass = (Class<?>) unsafe.getObject(receiverKlassOop, (long) config.classMirrorOffset);
+                        graalMirror = CompilerImpl.getInstance().getVMEntries().getType(javaClass);
+                        assert graalMirror != null : "must not return null";
+                    }
+                    sparseTypes[entries] = (RiResolvedType) graalMirror;
+
+                    long count = data.readUnsignedInt(position, getCountOffset(i));
+                    totalCount += count;
+                    counts[entries] = count;
+
+                    entries++;
+                }
+            }
+
+            totalCount += getTypesNotRecordedExecutionCount(data, position);
+            return createRiTypeProfile(sparseTypes, counts, totalCount, entries);
+        }
+
+        protected long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position) {
+            // checkcast/aastore/instanceof profiling in the HotSpot template-based interpreter was adjusted so that the counter
+            // is incremented to indicate the polymorphic case instead of decrementing it for failed type checks
+            return getCounterValue(data, position);
+        }
+
+        private static RiTypeProfile createRiTypeProfile(RiResolvedType[] sparseTypes, double[] counts, long totalCount, int entries) {
+            RiResolvedType[] types;
+            double[] probabilities;
+
+            if (entries <= 0 || totalCount < GraalOptions.MatureExecutionsTypeProfile) {
+                return null;
+            } else if (entries < sparseTypes.length) {
+                types = Arrays.copyOf(sparseTypes, entries);
+                probabilities = new double[entries];
+            } else {
+                types = sparseTypes;
+                probabilities = counts;
+            }
+
+            double totalProbability = 0.0;
+            for (int i = 0; i < entries; i++) {
+                double p = counts[i] / totalCount;
+                probabilities[i] = p;
+                totalProbability += p;
+            }
+
+            double notRecordedTypeProbability = entries < config.typeProfileWidth ? 0.0 : Math.min(1.0, Math.max(0.0, 1.0 - totalProbability));
+            return new RiTypeProfile(types, notRecordedTypeProbability, probabilities);
+        }
+
+        private static int getReceiverOffset(int row) {
+            return RECEIVER_TYPE_DATA_FIRST_RECEIVER_OFFSET + row * RECEIVER_TYPE_DATA_ROW_SIZE;
+        }
+
+        protected static int getCountOffset(int row) {
+            return RECEIVER_TYPE_DATA_FIRST_COUNT_OFFSET + row * RECEIVER_TYPE_DATA_ROW_SIZE;
+        }
+    }
+
+    private static class TypeCheckData extends AbstractTypeData {
+        private static final int RECEIVER_TYPE_DATA_TAG = 4;
+
+        public TypeCheckData() {
+            super(RECEIVER_TYPE_DATA_TAG);
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            return -1;
+        }
+    }
+
+    private static class VirtualCallData extends AbstractTypeData {
+        private static final int VIRTUAL_CALL_DATA_TAG = 5;
+
+        public VirtualCallData() {
+            super(VIRTUAL_CALL_DATA_TAG);
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            int typeProfileWidth = config.typeProfileWidth;
+
+            long total = 0;
+            for (int i = 0; i < typeProfileWidth; i++) {
+                total += data.readUnsignedInt(position, getCountOffset(i));
+            }
+
+            total += getCounterValue(data, position);
+            return truncateLongToInt(total);
+        }
+    }
+
+    private static class RetData extends CounterData {
+        private static final int RET_DATA_TAG = 6;
+        private static final int RET_DATA_ROW_SIZE = cellsToBytes(3);
+        private static final int RET_DATA_SIZE = cellIndexToOffset(1) + RET_DATA_ROW_SIZE * config.bciProfileWidth;
+
+        public RetData() {
+            super(RET_DATA_TAG, RET_DATA_SIZE);
+        }
+    }
+
+    private static class BranchData extends JumpData {
+        private static final int BRANCH_DATA_TAG = 7;
+        private static final int BRANCH_DATA_SIZE = cellIndexToOffset(3);
+        private static final int NOT_TAKEN_COUNT_OFFSET = cellIndexToOffset(2);
+
+        public BranchData() {
+            super(BRANCH_DATA_TAG, BRANCH_DATA_SIZE);
+        }
+
+        @Override
+        public double getBranchTakenProbability(HotSpotMethodData data, int position) {
+            long takenCount = data.readUnsignedInt(position, TAKEN_COUNT_OFFSET);
+            long notTakenCount = data.readUnsignedInt(position, NOT_TAKEN_COUNT_OFFSET);
+            long total = takenCount + notTakenCount;
+
+            if (total < GraalOptions.MatureExecutionsBranch) {
+                return -1;
+            } else {
+                return takenCount / (double) total;
+            }
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            long count = data.readUnsignedInt(position, TAKEN_COUNT_OFFSET) + data.readUnsignedInt(position, NOT_TAKEN_COUNT_OFFSET);
+            return truncateLongToInt(count);
+        }
+    }
+
+    private static class ArrayData extends AbstractMethodData {
+        private static final int ARRAY_DATA_LENGTH_OFFSET = cellIndexToOffset(0);
+        protected static final int ARRAY_DATA_START_OFFSET = cellIndexToOffset(1);
+
+        public ArrayData(int tag, int staticSize) {
+            super(tag, staticSize);
+        }
+
+        @Override
+        protected int getDynamicSize(HotSpotMethodData data, int position) {
+            return cellsToBytes(getLength(data, position));
+        }
+
+        protected static int getLength(HotSpotMethodData data, int position) {
+            return data.readInt(position, ARRAY_DATA_LENGTH_OFFSET);
+        }
+    }
+
+    private static class MultiBranchData extends ArrayData {
+        private static final int MULTI_BRANCH_DATA_TAG = 8;
+        private static final int MULTI_BRANCH_DATA_SIZE = cellIndexToOffset(1);
+        private static final int MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS = 2;
+        private static final int MULTI_BRANCH_DATA_ROW_SIZE = cellsToBytes(MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS);
+        private static final int MULTI_BRANCH_DATA_FIRST_COUNT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(0);
+        private static final int MULTI_BRANCH_DATA_FIRST_DISPLACEMENT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(1);
+
+        public MultiBranchData() {
+            super(MULTI_BRANCH_DATA_TAG, MULTI_BRANCH_DATA_SIZE);
+        }
+
+        @Override
+        public double[] getSwitchProbabilities(HotSpotMethodData data, int position) {
+            int arrayLength = getLength(data, position);
+            assert arrayLength > 0 : "switch must have at least the default case";
+            assert arrayLength % MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS == 0 : "array must have full rows";
+
+            int length = arrayLength / MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS;
+            long totalCount = 0;
+            double[] result = new double[length];
+
+            // default case is first in HotSpot but last for the compiler
+            long count = readCount(data, position, 0);
+            totalCount += count;
+            result[length - 1] = count;
+
+            for (int i = 1; i < length; i++) {
+                count = readCount(data, position, i);
+                totalCount += count;
+                result[i - 1] = count;
+            }
+
+            if (totalCount < GraalOptions.MatureExecutionsPerSwitchCase * length) {
+                return null;
+            } else {
+                for (int i = 0; i < length; i++) {
+                    result[i] = result[i] / totalCount;
+                }
+                return result;
+            }
+        }
+
+        private static long readCount(HotSpotMethodData data, int position, int i) {
+            int offset;
+            long count;
+            offset = getCountOffset(i);
+            count = data.readUnsignedInt(position, offset);
+            return count;
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            int arrayLength = getLength(data, position);
+            assert arrayLength > 0 : "switch must have at least the default case";
+            assert arrayLength % MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS == 0 : "array must have full rows";
+
+            int length = arrayLength / MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS;
+            long totalCount = 0;
+            for (int i = 0; i < length; i++) {
+                int offset = getCountOffset(i);
+                totalCount += data.readUnsignedInt(position, offset);
+            }
+
+            return truncateLongToInt(totalCount);
+        }
+
+        private static int getCountOffset(int index) {
+            return MULTI_BRANCH_DATA_FIRST_COUNT_OFFSET + index * MULTI_BRANCH_DATA_ROW_SIZE;
+        }
+
+        @SuppressWarnings("unused")
+        private static int getDisplacementOffset(int index) {
+            return MULTI_BRANCH_DATA_FIRST_DISPLACEMENT_OFFSET + index * MULTI_BRANCH_DATA_ROW_SIZE;
+        }
+    }
+
+    private static class ArgInfoData extends ArrayData {
+        private static final int ARG_INFO_DATA_TAG = 9;
+        private static final int ARG_INFO_DATA_SIZE = cellIndexToOffset(1);
+
+        public ArgInfoData() {
+            super(ARG_INFO_DATA_TAG, ARG_INFO_DATA_SIZE);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodDataAccessor.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+import com.oracle.max.cri.ri.*;
+
+/**
+ * Interface for accessor objects that encapsulate the logic for accessing the different kinds of data in a HotSpot methodDataOop.
+ * This interface is similar to the interface {@link RiProfilingInfo}, but most methods require a MethodDataObject and the
+ * exact position within the methodData.
+ */
+public interface HotSpotMethodDataAccessor {
+    /**
+     * Returns the tag stored in the LayoutData header.
+     * @return An integer >= 0 or -1 if not supported.
+     */
+    int getTag();
+
+    /**
+     * Returns the BCI stored in the LayoutData header.
+     * @return An integer >= 0 and <= Short.MAX_VALUE, or -1 if not supported.
+     */
+    int getBCI(HotSpotMethodData data, int position);
+
+    /**
+     * Computes the size for the specific data at the given position.
+     * @return An integer > 0.
+     */
+    int getSize(HotSpotMethodData data, int position);
+
+    RiTypeProfile getTypeProfile(HotSpotMethodData data, int position);
+    double getBranchTakenProbability(HotSpotMethodData data, int position);
+    double[] getSwitchProbabilities(HotSpotMethodData data, int position);
+    RiExceptionSeen getExceptionSeen(HotSpotMethodData data, int position);
+    int getExecutionCount(HotSpotMethodData data, int position);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodResolved.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,32 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.hotspot.server.*;
+
+public interface HotSpotMethodResolved extends RiResolvedMethod, Remote {
+
+    RiResolvedMethod uniqueConcreteMethod();
+    void dumpProfile();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodResolvedImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,356 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.java.*;
+
+/**
+ * Implementation of RiMethod for resolved HotSpot methods.
+ */
+public final class HotSpotMethodResolvedImpl extends HotSpotMethod implements HotSpotMethodResolved {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -5486975070147586588L;
+
+    /** DO NOT USE IN JAVA CODE! */
+    @SuppressWarnings("unused")
+    @Deprecated
+    private Object javaMirror;
+
+    // cached values
+    private final int codeSize;
+    private final int accessFlags;
+    private final int maxLocals;
+    private final int maxStackSize;
+    private RiSignature signature;
+    private Boolean hasBalancedMonitors;
+    private Map<Object, Object> compilerStorage;
+    private RiResolvedType holder;
+    private HotSpotMethodData methodData;
+    private byte[] code;
+    private boolean canBeInlined;
+    private CiGenericCallback callback;
+    private int compilationComplexity;
+
+    private HotSpotMethodResolvedImpl() {
+        super(null);
+        throw new IllegalStateException("this constructor is never actually called, because the objects are allocated from within the VM");
+    }
+
+    @Override
+    public RiResolvedType holder() {
+        return holder;
+    }
+
+    @Override
+    public int accessFlags() {
+        return accessFlags;
+    }
+
+    @Override
+    public boolean canBeStaticallyBound() {
+        return isLeafMethod() || Modifier.isStatic(accessFlags());
+    }
+
+    @Override
+    public byte[] code() {
+        if (code == null) {
+            code = compiler.getVMEntries().RiMethod_code(this);
+            assert code.length == codeSize : "expected: " + codeSize + ", actual: " + code.length;
+        }
+        return code;
+    }
+
+    @Override
+    public int codeSize() {
+        return codeSize;
+    }
+
+    @Override
+    public RiExceptionHandler[] exceptionHandlers() {
+        return compiler.getVMEntries().RiMethod_exceptionHandlers(this);
+    }
+
+    @Override
+    public boolean hasBalancedMonitors() {
+        if (hasBalancedMonitors == null) {
+            hasBalancedMonitors = compiler.getVMEntries().RiMethod_hasBalancedMonitors(this);
+        }
+        return hasBalancedMonitors;
+    }
+
+    @Override
+    public boolean isClassInitializer() {
+        return "<clinit>".equals(name) && Modifier.isStatic(accessFlags());
+    }
+
+    @Override
+    public boolean isConstructor() {
+        return "<init>".equals(name) && !Modifier.isStatic(accessFlags());
+    }
+
+    @Override
+    public boolean isLeafMethod() {
+        return Modifier.isFinal(accessFlags()) || Modifier.isPrivate(accessFlags());
+    }
+
+    @Override
+    public boolean isOverridden() {
+        throw new UnsupportedOperationException("isOverridden");
+    }
+
+    @Override
+    public boolean noSafepointPolls() {
+        return false;
+    }
+
+    @Override
+    public String jniSymbol() {
+        throw new UnsupportedOperationException("jniSymbol");
+    }
+
+    public CiBitMap[] livenessMap() {
+        return null;
+    }
+
+    @Override
+    public int maxLocals() {
+        return maxLocals;
+    }
+
+    @Override
+    public int maxStackSize() {
+        return maxStackSize;
+    }
+
+    @Override
+    public StackTraceElement toStackTraceElement(int bci) {
+        return CiUtil.toStackTraceElement(this, bci);
+    }
+
+    @Override
+    public RiResolvedMethod uniqueConcreteMethod() {
+        return (RiResolvedMethod) compiler.getVMEntries().RiMethod_uniqueConcreteMethod(this);
+    }
+
+    @Override
+    public RiSignature signature() {
+        if (signature == null) {
+            signature = new HotSpotSignature(compiler, compiler.getVMEntries().RiMethod_signature(this));
+        }
+        return signature;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotMethod<" + CiUtil.format("%h.%n", this) + ">";
+    }
+
+    public boolean hasCompiledCode() {
+        return compiler.getVMEntries().RiMethod_hasCompiledCode(this);
+    }
+
+    public int compiledCodeSize() {
+        return compiler.getVMEntries().RiMethod_getCompiledCodeSize(this);
+    }
+
+    @Override
+    public RiResolvedType accessor() {
+        return null;
+    }
+
+    @Override
+    public String intrinsic() {
+        return null;
+    }
+
+    @Override
+    public int invocationCount() {
+        return compiler.getVMEntries().RiMethod_invocationCount(this);
+    }
+
+    @Override
+    public int compilationComplexity() {
+        if (compilationComplexity <= 0 && codeSize() > 0) {
+            BytecodeStream s = new BytecodeStream(code());
+            int result = 0;
+            int currentBC;
+            while ((currentBC = s.currentBC()) != Bytecodes.END) {
+                result += Bytecodes.compilationComplexity(currentBC);
+                s.next();
+            }
+            assert result > 0;
+            compilationComplexity = result;
+        }
+        return compilationComplexity;
+    }
+
+    @Override
+    public RiProfilingInfo profilingInfo() {
+        if (methodData == null) {
+            methodData = compiler.getVMEntries().RiMethod_methodData(this);
+        }
+
+        if (methodData == null) {
+            return new HotSpotNoProfilingInfo(compiler);
+        } else {
+            return new HotSpotProfilingInfo(compiler, methodData);
+        }
+    }
+
+    @Override
+    public Map<Object, Object> compilerStorage() {
+        if (compilerStorage == null) {
+            compilerStorage = new ConcurrentHashMap<>();
+        }
+        return compilerStorage;
+    }
+
+    @Override
+    public RiConstantPool getConstantPool() {
+        return ((HotSpotTypeResolvedImpl) holder()).constantPool();
+    }
+
+    public void dumpProfile() {
+        TTY.println("profile info for %s", this);
+        TTY.println("canBeStaticallyBound: " + canBeStaticallyBound());
+        TTY.println("invocationCount: " + invocationCount());
+        RiProfilingInfo profilingInfo = this.profilingInfo();
+        for (int i = 0; i < codeSize(); i++) {
+            if (profilingInfo.getExecutionCount(i) != -1) {
+                TTY.println("  executionCount@%d: %d", i, profilingInfo.getExecutionCount(i));
+            }
+
+            if (profilingInfo.getBranchTakenProbability(i) != -1) {
+                TTY.println("  branchProbability@%d: %f", i, profilingInfo.getBranchTakenProbability(i));
+            }
+
+            double[] switchProbabilities = profilingInfo.getSwitchProbabilities(i);
+            if (switchProbabilities != null) {
+                TTY.print("  switchProbabilities@%d:", i);
+                for (int j = 0; j < switchProbabilities.length; j++) {
+                    TTY.print(" %f", switchProbabilities[j]);
+                }
+                TTY.println();
+            }
+
+            if (profilingInfo.getExceptionSeen(i) != RiExceptionSeen.FALSE) {
+                TTY.println("  exceptionSeen@%d: %s", i, profilingInfo.getExceptionSeen(i).name());
+            }
+
+            RiTypeProfile typeProfile = profilingInfo.getTypeProfile(i);
+            if (typeProfile != null) {
+                RiResolvedType[] types = typeProfile.getTypes();
+                double[] probabilities = typeProfile.getProbabilities();
+                if (types != null && probabilities != null) {
+                    assert types.length == probabilities.length : "length must match";
+                    TTY.print("  types@%d:", i);
+                    for (int j = 0; j < types.length; j++) {
+                        TTY.print(" %s (%f)", types[j], probabilities[j]);
+                    }
+                    TTY.println(" not recorded (%f)", typeProfile.getNotRecordedProbability());
+                }
+            }
+        }
+    }
+
+    @Override
+    public Annotation[][] getParameterAnnotations() {
+        if (isConstructor()) {
+            Constructor javaConstructor = toJavaConstructor();
+            return javaConstructor == null ? null : javaConstructor.getParameterAnnotations();
+        }
+        Method javaMethod = toJava();
+        return javaMethod == null ? null : javaMethod.getParameterAnnotations();
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        if (isConstructor()) {
+            Constructor<?> javaConstructor = toJavaConstructor();
+            return javaConstructor == null ? null : javaConstructor.getAnnotation(annotationClass);
+        }
+        Method javaMethod = toJava();
+        return javaMethod == null ? null : javaMethod.getAnnotation(annotationClass);
+    }
+
+    @Override
+    public Type getGenericReturnType() {
+        if (isConstructor()) {
+            return void.class;
+        }
+        Method javaMethod = toJava();
+        return javaMethod == null ? null : javaMethod.getGenericReturnType();
+    }
+
+    @Override
+    public Type[] getGenericParameterTypes() {
+        if (isConstructor()) {
+            Constructor javaConstructor = toJavaConstructor();
+            return javaConstructor == null ? null : javaConstructor.getGenericParameterTypes();
+        }
+        Method javaMethod = toJava();
+        return javaMethod == null ? null : javaMethod.getGenericParameterTypes();
+    }
+
+    private Method toJava() {
+        try {
+            return holder.toJava().getDeclaredMethod(name, CiUtil.signatureToTypes(signature(), holder));
+        } catch (NoSuchMethodException e) {
+            return null;
+        }
+    }
+
+    private Constructor toJavaConstructor() {
+        try {
+            return holder.toJava().getDeclaredConstructor(CiUtil.signatureToTypes(signature(), holder));
+        } catch (NoSuchMethodException e) {
+            return null;
+        }
+    }
+
+    @Override
+    public boolean canBeInlined() {
+        return canBeInlined && callback == null;
+    }
+    public void neverInline() {
+        this.canBeInlined = false;
+    }
+
+    public CiGenericCallback callback() {
+        return callback;
+    }
+    public void setCallback(CiGenericCallback callback) {
+        this.callback = callback;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodUnresolved.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.hotspot.Compiler;
+
+/**
+ * Implementation of RiMethod for unresolved HotSpot methods.
+ */
+public final class HotSpotMethodUnresolved extends HotSpotMethod {
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 5610263481791970079L;
+    private final RiSignature signature;
+    protected RiType holder;
+
+    public HotSpotMethodUnresolved(Compiler compiler, String name, String signature, RiType holder) {
+        super(compiler);
+        this.name = name;
+        this.holder = holder;
+        this.signature = new HotSpotSignature(compiler, signature);
+    }
+
+    @Override
+    public RiSignature signature() {
+        return signature;
+    }
+
+    @Override
+    public RiType holder() {
+        return holder;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotMethod<" + holder.name() + ". " + name + ", unresolved>";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotNoProfilingInfo.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,69 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.hotspot.*;
+import com.oracle.max.graal.hotspot.Compiler;
+
+/**
+ * Dummy profiling information in case that a method was not executed frequently enough so that
+ * no profiling information does exist yet.
+ */
+public final class HotSpotNoProfilingInfo extends CompilerObject implements RiProfilingInfo {
+    /**
+     *
+     */
+    private static final long serialVersionUID = 4357945025049704109L;
+    // Be optimistic and return false for exceptionSeen. A methodDataOop is allocated in case of a deoptimization.
+    private static final HotSpotMethodDataAccessor noData = HotSpotMethodData.getNoDataAccessor(false);
+
+    public HotSpotNoProfilingInfo(Compiler compiler) {
+        super(compiler);
+    }
+
+    @Override
+    public RiTypeProfile getTypeProfile(int bci) {
+        return noData.getTypeProfile(null, -1);
+    }
+
+    @Override
+    public double getBranchTakenProbability(int bci) {
+        return noData.getBranchTakenProbability(null, -1);
+    }
+
+    @Override
+    public double[] getSwitchProbabilities(int bci) {
+        return noData.getSwitchProbabilities(null, -1);
+    }
+
+    @Override
+    public RiExceptionSeen getExceptionSeen(int bci) {
+        return noData.getExceptionSeen(null, -1);
+    }
+
+    @Override
+    public int getExecutionCount(int bci) {
+        return noData.getExecutionCount(null, -1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotProfilingInfo.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,141 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.hotspot.*;
+import com.oracle.max.graal.hotspot.Compiler;
+
+
+public final class HotSpotProfilingInfo extends CompilerObject implements RiProfilingInfo {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -8307682725047864875L;
+    private static final DebugMetric metricInsufficentSpace = Debug.metric("InsufficientSpaceForProfilingData");
+
+    private int position;
+    private int hintPosition;
+    private int hintBCI;
+    private HotSpotMethodDataAccessor dataAccessor;
+    private HotSpotMethodData methodData;
+
+    public HotSpotProfilingInfo(Compiler compiler, HotSpotMethodData methodData) {
+        super(compiler);
+        this.methodData = methodData;
+        hintPosition = 0;
+        hintBCI = -1;
+    }
+
+    @Override
+    public RiTypeProfile getTypeProfile(int bci) {
+        findBCI(bci, false);
+        return dataAccessor.getTypeProfile(methodData, position);
+    }
+
+    @Override
+    public double getBranchTakenProbability(int bci) {
+        findBCI(bci, false);
+        return dataAccessor.getBranchTakenProbability(methodData, position);
+    }
+
+    @Override
+    public double[] getSwitchProbabilities(int bci) {
+        findBCI(bci, false);
+        return dataAccessor.getSwitchProbabilities(methodData, position);
+    }
+
+    @Override
+    public RiExceptionSeen getExceptionSeen(int bci) {
+        findBCI(bci, true);
+        return dataAccessor.getExceptionSeen(methodData, position);
+    }
+
+    @Override
+    public int getExecutionCount(int bci) {
+        findBCI(bci, false);
+        return dataAccessor.getExecutionCount(methodData, position);
+    }
+
+    private void findBCI(int targetBCI, boolean searchExtraData) {
+        assert targetBCI >= 0 : "invalid BCI";
+
+        if (methodData.hasNormalData()) {
+            int currentPosition = targetBCI < hintBCI ? 0 : hintPosition;
+            HotSpotMethodDataAccessor currentAccessor;
+            while ((currentAccessor = methodData.getNormalData(currentPosition)) != null) {
+                int currentBCI = currentAccessor.getBCI(methodData, currentPosition);
+                if (currentBCI == targetBCI) {
+                    normalDataFound(currentAccessor, currentPosition, currentBCI);
+                    return;
+                } else if (currentBCI > targetBCI) {
+                    break;
+                }
+                currentPosition = currentPosition + currentAccessor.getSize(methodData, currentPosition);
+            }
+        }
+
+        boolean exceptionPossiblyNotRecorded = false;
+        if (searchExtraData && methodData.hasExtraData()) {
+            int currentPosition = methodData.getExtraDataBeginOffset();
+            HotSpotMethodDataAccessor currentAccessor;
+            while ((currentAccessor = methodData.getExtraData(currentPosition)) != null) {
+                int currentBCI = currentAccessor.getBCI(methodData, currentPosition);
+                if (currentBCI == targetBCI) {
+                    extraDataFound(currentAccessor, currentPosition);
+                    return;
+                }
+                currentPosition = currentPosition + currentAccessor.getSize(methodData, currentPosition);
+            }
+
+            if (!methodData.isWithin(currentPosition)) {
+                exceptionPossiblyNotRecorded = true;
+                metricInsufficentSpace.increment();
+            }
+        }
+
+        noDataFound(exceptionPossiblyNotRecorded);
+    }
+
+    private void normalDataFound(HotSpotMethodDataAccessor data, int pos, int bci) {
+        setCurrentData(data, pos);
+        this.hintPosition = position;
+        this.hintBCI = bci;
+    }
+
+    private void extraDataFound(HotSpotMethodDataAccessor data, int pos) {
+        setCurrentData(data, pos);
+    }
+
+    private void noDataFound(boolean exceptionPossiblyNotRecorded) {
+        HotSpotMethodDataAccessor accessor = HotSpotMethodData.getNoDataAccessor(exceptionPossiblyNotRecorded);
+        setCurrentData(accessor, -1);
+    }
+
+    private void setCurrentData(HotSpotMethodDataAccessor dataAccessor, int position) {
+        this.dataAccessor = dataAccessor;
+        this.position = position;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotRegisterConfig.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.hotspot.ri;
+
+import static com.oracle.max.asm.target.amd64.AMD64.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiCallingConvention.Type;
+import com.oracle.max.cri.ci.CiRegister.RegisterFlag;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.hotspot.*;
+
+public class HotSpotRegisterConfig implements RiRegisterConfig {
+
+    // be careful - the contents of this array are duplicated in graal_CodeInstaller.cpp
+    private final CiRegister[] allocatable = {
+        rax, rbx, rcx, rdx, rsi, rdi, r8, r9, /* r10, */r11, r12, r13, r14, /*r15*/
+        xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
+        xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
+    };
+
+    private final EnumMap<RegisterFlag, CiRegister[]> categorized = CiRegister.categorize(allocatable);
+
+    private final RiRegisterAttributes[] attributesMap;
+
+    @Override
+    public CiRegister[] getAllocatableRegisters() {
+        return allocatable;
+    }
+
+    @Override
+    public EnumMap<RegisterFlag, CiRegister[]> getCategorizedAllocatableRegisters() {
+        return categorized;
+    }
+
+    @Override
+    public RiRegisterAttributes[] getAttributesMap() {
+        return attributesMap;
+    }
+
+    private final CiRegister[] generalParameterRegisters;
+    private final CiRegister[] xmmParameterRegisters = {xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7};
+    private final CiRegister[] allParameterRegisters;
+
+    private final CiRegister[] rsaRegs = {
+        rax,  rcx,  rdx,   rbx,   rsp,   rbp,   rsi,   rdi,
+        r8,   r9,   r10,   r11,   r12,   r13,   r14,   r15,
+        xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
+        xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
+    };
+
+    private final CiCalleeSaveLayout registerSaveArea;
+
+    public HotSpotRegisterConfig(HotSpotVMConfig config, boolean globalStubConfig) {
+        if (config.windowsOs) {
+            generalParameterRegisters = new CiRegister[] {rdx, r8, r9, rdi, rsi, rcx};
+        } else {
+            generalParameterRegisters = new CiRegister[] {rsi, rdx, rcx, r8, r9, rdi};
+        }
+
+        if (globalStubConfig) {
+            registerSaveArea = new CiCalleeSaveLayout(0, -1, 8, rsaRegs);
+        } else {
+            registerSaveArea = new CiCalleeSaveLayout(0, 8, 8, new CiRegister[0]);
+        }
+
+        attributesMap = RiRegisterAttributes.createMap(this, AMD64.allRegisters);
+        allParameterRegisters = Arrays.copyOf(generalParameterRegisters, generalParameterRegisters.length + xmmParameterRegisters.length);
+        System.arraycopy(xmmParameterRegisters, 0, allParameterRegisters, generalParameterRegisters.length, xmmParameterRegisters.length);
+    }
+
+    @Override
+    public CiRegister[] getCallerSaveRegisters() {
+        return getAllocatableRegisters();
+    }
+
+    @Override
+    public CiRegister getRegisterForRole(int index) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public CiCallingConvention getCallingConvention(Type type, CiKind[] parameters, CiTarget target, boolean stackOnly) {
+        if (type == Type.NativeCall) {
+            throw new UnsupportedOperationException();
+        }
+        return callingConvention(parameters, type, target, stackOnly);
+    }
+
+    public CiRegister[] getCallingConventionRegisters(Type type, RegisterFlag flag) {
+        return allParameterRegisters;
+    }
+
+    private CiCallingConvention callingConvention(CiKind[] types, Type type, CiTarget target, boolean stackOnly) {
+        CiValue[] locations = new CiValue[types.length];
+
+        int currentGeneral = 0;
+        int currentXMM = 0;
+        int currentStackOffset = 0;
+
+        for (int i = 0; i < types.length; i++) {
+            final CiKind kind = types[i];
+
+            switch (kind) {
+                case Byte:
+                case Boolean:
+                case Short:
+                case Char:
+                case Int:
+                case Long:
+                case Object:
+                    if (!stackOnly && currentGeneral < generalParameterRegisters.length) {
+                        CiRegister register = generalParameterRegisters[currentGeneral++];
+                        locations[i] = register.asValue(kind);
+                    }
+                    break;
+                case Float:
+                case Double:
+                    if (!stackOnly && currentXMM < xmmParameterRegisters.length) {
+                        CiRegister register = xmmParameterRegisters[currentXMM++];
+                        locations[i] = register.asValue(kind);
+                    }
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+
+            if (locations[i] == null) {
+                locations[i] = CiStackSlot.get(kind.stackKind(), currentStackOffset, !type.out);
+                currentStackOffset += Math.max(target.sizeInBytes(kind), target.wordSize);
+            }
+        }
+
+        return new CiCallingConvention(locations, currentStackOffset);
+    }
+
+    @Override
+    public CiRegister getReturnRegister(CiKind kind) {
+        switch (kind) {
+            case Boolean:
+            case Byte:
+            case Char:
+            case Short:
+            case Int:
+            case Long:
+            case Object:
+                return rax;
+            case Float:
+            case Double:
+                return xmm0;
+            case Void:
+            case Illegal:
+                return null;
+            default:
+                throw new UnsupportedOperationException("no return register for type " + kind);
+        }
+    }
+
+    @Override
+    public CiRegister getScratchRegister() {
+        return r10;
+    }
+
+    @Override
+    public CiRegister getFrameRegister() {
+        return rsp;
+    }
+
+    public CiCalleeSaveLayout getCalleeSaveLayout() {
+        return registerSaveArea;
+    }
+
+    @Override
+    public String toString() {
+        String res = String.format(
+             "Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" +
+             "CallerSave:  " + Arrays.toString(getCallerSaveRegisters()) + "%n" +
+             "CalleeSave:  " + getCalleeSaveLayout() + "%n" +
+             "Scratch:     " + getScratchRegister() + "%n");
+        return res;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotRuntime.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.hotspot.ri;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiTargetMethod.Call;
+import com.oracle.max.cri.ci.CiTargetMethod.DataPatch;
+import com.oracle.max.cri.ci.CiTargetMethod.Safepoint;
+import com.oracle.max.cri.ci.CiUtil.RefMapFormatter;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.cri.ri.RiType.Representation;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.hotspot.*;
+import com.oracle.max.graal.hotspot.Compiler;
+import com.oracle.max.graal.hotspot.nodes.*;
+import com.oracle.max.graal.java.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.java.*;
+import com.oracle.max.graal.snippets.nodes.*;
+
+/**
+ * CRI runtime implementation for the HotSpot VM.
+ */
+public class HotSpotRuntime implements GraalRuntime {
+    final HotSpotVMConfig config;
+    final HotSpotRegisterConfig regConfig;
+    private final HotSpotRegisterConfig globalStubRegConfig;
+    private final Compiler compiler;
+
+    public HotSpotRuntime(HotSpotVMConfig config, Compiler compiler) {
+        this.config = config;
+        this.compiler = compiler;
+        regConfig = new HotSpotRegisterConfig(config, false);
+        globalStubRegConfig = new HotSpotRegisterConfig(config, true);
+    }
+
+    @Override
+    public int codeOffset() {
+        return 0;
+    }
+
+
+    public Compiler getCompiler() {
+        return compiler;
+    }
+
+    @Override
+    public String disassemble(byte[] code, long address) {
+        return compiler.getVMEntries().disassembleNative(code, address);
+    }
+
+    @Override
+    public String disassemble(CiTargetMethod tm) {
+        byte[] code = Arrays.copyOf(tm.targetCode(), tm.targetCodeSize());
+        CiTarget target = compiler.getTarget();
+        HexCodeFile hcf = new HexCodeFile(code, 0L, target.arch.name, target.wordSize * 8);
+        HexCodeFile.addAnnotations(hcf, tm.annotations());
+        addExceptionHandlersComment(tm, hcf);
+        CiRegister fp = regConfig.getFrameRegister();
+        RefMapFormatter slotFormatter = new RefMapFormatter(target.arch, target.wordSize, fp, 0);
+        for (Safepoint safepoint : tm.safepoints) {
+            if (safepoint instanceof Call) {
+                Call call = (Call) safepoint;
+                if (call.debugInfo != null) {
+                    hcf.addComment(call.pcOffset + call.size, CiUtil.append(new StringBuilder(100), call.debugInfo, slotFormatter).toString());
+                }
+                addOperandComment(hcf, call.pcOffset, "{" + call.target + "}");
+            } else {
+                if (safepoint.debugInfo != null) {
+                    hcf.addComment(safepoint.pcOffset, CiUtil.append(new StringBuilder(100), safepoint.debugInfo, slotFormatter).toString());
+                }
+                addOperandComment(hcf, safepoint.pcOffset, "{safepoint}");
+            }
+        }
+        for (DataPatch site : tm.dataReferences) {
+            hcf.addOperandComment(site.pcOffset, "{" + site.constant + "}");
+        }
+        return hcf.toEmbeddedString();
+    }
+
+    private static void addExceptionHandlersComment(CiTargetMethod tm, HexCodeFile hcf) {
+        if (!tm.exceptionHandlers.isEmpty()) {
+            String nl = HexCodeFile.NEW_LINE;
+            StringBuilder buf = new StringBuilder("------ Exception Handlers ------").append(nl);
+            for (CiTargetMethod.ExceptionHandler e : tm.exceptionHandlers) {
+                buf.append("    ").
+                    append(e.pcOffset).append(" -> ").
+                    append(e.handlerPos).
+                    append(nl);
+            }
+            hcf.addComment(0, buf.toString());
+        }
+    }
+
+    private static void addOperandComment(HexCodeFile hcf, int pos, String comment) {
+        String oldValue = hcf.addOperandComment(pos, comment);
+        assert oldValue == null : "multiple comments for operand of instruction at " + pos + ": " + comment + ", " + oldValue;
+    }
+
+    @Override
+    public String disassemble(RiResolvedMethod method) {
+        return compiler.getVMEntries().disassembleJava((HotSpotMethodResolved) method);
+    }
+
+    @Override
+    public RiResolvedType asRiType(CiKind kind) {
+        return (RiResolvedType) compiler.getVMEntries().getType(kind.toJavaClass());
+    }
+
+    @Override
+    public RiResolvedType getTypeOf(CiConstant constant) {
+        return (RiResolvedType) compiler.getVMEntries().getRiType(constant);
+    }
+
+    @Override
+    public boolean isExceptionType(RiResolvedType type) {
+        return type.isSubtypeOf((RiResolvedType) compiler.getVMEntries().getType(Throwable.class));
+    }
+
+    @Override
+    public Object registerCompilerStub(CiTargetMethod targetMethod, String name) {
+        return HotSpotTargetMethod.installStub(compiler, targetMethod, name);
+    }
+
+    @Override
+    public int sizeOfLockData() {
+        // TODO shouldn't be hard coded
+        return 8;
+    }
+
+    @Override
+    public int sizeOfBasicObjectLock() {
+        // TODO shouldn't be hard coded
+        return 2 * 8;
+    }
+
+    @Override
+    public int basicObjectLockOffsetInBytes() {
+        return 8;
+    }
+
+    @Override
+    public boolean areConstantObjectsEqual(CiConstant x, CiConstant y) {
+        return compiler.getVMEntries().compareConstantObjects(x, y);
+    }
+
+    @Override
+    public RiRegisterConfig getRegisterConfig(RiMethod method) {
+        return regConfig;
+    }
+
+    /**
+     * HotSpots needs an area suitable for storing a program counter for temporary use during the deoptimization process.
+     */
+    @Override
+    public int getCustomStackAreaSize() {
+        // TODO shouldn't be hard coded
+        return 8;
+    }
+
+    @Override
+    public int getMinimumOutgoingSize() {
+        return config.runtimeCallStackSize;
+    }
+
+    @Override
+    public int getArrayLength(CiConstant array) {
+        return compiler.getVMEntries().getArrayLength(array);
+    }
+
+    @Override
+    public Class<?> asJavaClass(CiConstant c) {
+        return (Class<?>) c.asObject();
+    }
+
+    @Override
+    public Object asJavaObject(CiConstant c) {
+        return c.asObject();
+    }
+
+    @Override
+    public void lower(Node n, CiLoweringTool tool) {
+        if (!GraalOptions.Lower) {
+            return;
+        }
+        StructuredGraph graph = (StructuredGraph) n.graph();
+
+        if (n instanceof ArrayLengthNode) {
+            ArrayLengthNode arrayLengthNode = (ArrayLengthNode) n;
+            SafeReadNode safeReadArrayLength = safeReadArrayLength(arrayLengthNode.graph(), arrayLengthNode.array());
+            graph.replaceFixedWithFixed(arrayLengthNode, safeReadArrayLength);
+            safeReadArrayLength.lower(tool);
+        } else if (n instanceof LoadFieldNode) {
+            LoadFieldNode field = (LoadFieldNode) n;
+            if (field.isVolatile()) {
+                return;
+            }
+            int displacement = ((HotSpotField) field.field()).offset();
+            assert field.kind() != CiKind.Illegal;
+            ReadNode memoryRead = graph.add(new ReadNode(field.field().kind(true).stackKind(), field.object(), LocationNode.create(field.field(), field.field().kind(true), displacement, graph)));
+            memoryRead.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(field.object(), false))));
+            graph.replaceFixedWithFixed(field, memoryRead);
+        } else if (n instanceof StoreFieldNode) {
+            StoreFieldNode storeField = (StoreFieldNode) n;
+            if (storeField.isVolatile()) {
+                return;
+            }
+            HotSpotField field = (HotSpotField) storeField.field();
+            WriteNode memoryWrite = graph.add(new WriteNode(storeField.object(), storeField.value(), LocationNode.create(storeField.field(), storeField.field().kind(true), field.offset(), graph)));
+            memoryWrite.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(storeField.object(), false))));
+            memoryWrite.setStateAfter(storeField.stateAfter());
+            graph.replaceFixedWithFixed(storeField, memoryWrite);
+
+            if (field.kind(true) == CiKind.Object && !memoryWrite.value().isNullConstant()) {
+                graph.addAfterFixed(memoryWrite, graph.add(new FieldWriteBarrier(memoryWrite.object())));
+            }
+        } else if (n instanceof LoadIndexedNode) {
+            LoadIndexedNode loadIndexed = (LoadIndexedNode) n;
+            GuardNode boundsCheck = createBoundsCheck(loadIndexed, tool);
+
+            CiKind elementKind = loadIndexed.elementKind();
+            LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index());
+            ReadNode memoryRead = graph.add(new ReadNode(elementKind.stackKind(), loadIndexed.array(), arrayLocation));
+            memoryRead.setGuard(boundsCheck);
+            graph.replaceFixedWithFixed(loadIndexed, memoryRead);
+        } else if (n instanceof StoreIndexedNode) {
+            StoreIndexedNode storeIndexed = (StoreIndexedNode) n;
+            GuardNode boundsCheck = createBoundsCheck(storeIndexed, tool);
+
+            CiKind elementKind = storeIndexed.elementKind();
+            LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index());
+            ValueNode value = storeIndexed.value();
+            ValueNode array = storeIndexed.array();
+            if (elementKind == CiKind.Object && !value.isNullConstant()) {
+                // Store check!
+                if (array.exactType() != null) {
+                    RiResolvedType elementType = array.exactType().componentType();
+                    if (elementType.superType() != null) {
+                        AnchorNode anchor = graph.add(new AnchorNode());
+                        graph.addBeforeFixed(storeIndexed, anchor);
+                        ConstantNode type = ConstantNode.forCiConstant(elementType.getEncoding(Representation.ObjectHub), this, graph);
+                        value = graph.unique(new CheckCastNode(anchor, type, elementType, value));
+                    } else {
+                        assert elementType.name().equals("Ljava/lang/Object;") : elementType.name();
+                    }
+                } else {
+                    AnchorNode anchor = graph.add(new AnchorNode());
+                    graph.addBeforeFixed(storeIndexed, anchor);
+                    GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(array, false)));
+                    ReadNode arrayClass = graph.add(new ReadNode(CiKind.Object, array, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.hubOffset, graph)));
+                    arrayClass.setGuard(guard);
+                    graph.addBeforeFixed(storeIndexed, arrayClass);
+                    ReadNode arrayElementKlass = graph.add(new ReadNode(CiKind.Object, arrayClass, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.arrayClassElementOffset, graph)));
+                    value = graph.unique(new CheckCastNode(anchor, arrayElementKlass, null, value));
+                }
+            }
+            WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation));
+            memoryWrite.setGuard(boundsCheck);
+            memoryWrite.setStateAfter(storeIndexed.stateAfter());
+
+            graph.replaceFixedWithFixed(storeIndexed, memoryWrite);
+
+            if (elementKind == CiKind.Object && !value.isNullConstant()) {
+                graph.addAfterFixed(memoryWrite, graph.add(new ArrayWriteBarrier(array, arrayLocation)));
+            }
+        } else if (n instanceof UnsafeLoadNode) {
+            UnsafeLoadNode load = (UnsafeLoadNode) n;
+            assert load.kind() != CiKind.Illegal;
+            IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, load.loadKind(), load.displacement(), load.offset(), graph);
+            location.setIndexScalingEnabled(false);
+            ReadNode memoryRead = graph.add(new ReadNode(load.kind(), load.object(), location));
+            memoryRead.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(load.object(), false))));
+            graph.replaceFixedWithFixed(load, memoryRead);
+        } else if (n instanceof UnsafeStoreNode) {
+            UnsafeStoreNode store = (UnsafeStoreNode) n;
+            IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, store.storeKind(), store.displacement(), store.offset(), graph);
+            location.setIndexScalingEnabled(false);
+            WriteNode write = graph.add(new WriteNode(store.object(), store.value(), location));
+            FieldWriteBarrier barrier = graph.add(new FieldWriteBarrier(store.object()));
+            write.setStateAfter(store.stateAfter());
+            graph.replaceFixedWithFixed(store, write);
+            graph.addBeforeFixed(write, barrier);
+        } else if (n instanceof ArrayHeaderSizeNode) {
+            ArrayHeaderSizeNode arrayHeaderSize = (ArrayHeaderSizeNode) n;
+            graph.replaceFloating(arrayHeaderSize, ConstantNode.forLong(config.getArrayOffset(arrayHeaderSize.elementKind()), n.graph()));
+        } else if (n instanceof ReadHubNode) {
+            ReadHubNode objectClassNode = (ReadHubNode) n;
+            LocationNode location = LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.hubOffset, graph);
+            ReadNode memoryRead = graph.add(new ReadNode(CiKind.Object, objectClassNode.object(), location));
+            memoryRead.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(objectClassNode.object(), false))));
+            graph.replaceFixed(objectClassNode, memoryRead);
+        }
+    }
+
+    private IndexedLocationNode createArrayLocation(Graph graph, CiKind elementKind, ValueNode index) {
+        return IndexedLocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, config.getArrayOffset(elementKind), index, graph);
+    }
+
+    private static GuardNode createBoundsCheck(AccessIndexedNode n, CiLoweringTool tool) {
+        return (GuardNode) tool.createGuard(n.graph().unique(new CompareNode(n.index(), Condition.BT, n.length())));
+    }
+
+    @Override
+    public StructuredGraph intrinsicGraph(RiResolvedMethod caller, int bci, RiResolvedMethod method, List<? extends Node> parameters) {
+        RiType holder = method.holder();
+        String fullName = method.name() + method.signature().asString();
+        String holderName = holder.name();
+        if (holderName.equals("Ljava/lang/Object;")) {
+            if (fullName.equals("getClass()Ljava/lang/Class;")) {
+                ValueNode obj = (ValueNode) parameters.get(0);
+                if (obj.stamp().nonNull() && obj.stamp().exactType() != null) {
+                    StructuredGraph graph = new StructuredGraph();
+                    ValueNode result = ConstantNode.forObject(obj.stamp().exactType().toJava(), this, graph);
+                    ReturnNode ret = graph.add(new ReturnNode(result));
+                    graph.start().setNext(ret);
+                    return graph;
+                }
+                StructuredGraph graph = new StructuredGraph();
+                LocalNode receiver = graph.unique(new LocalNode(CiKind.Object, 0));
+                SafeReadNode klassOop = safeReadHub(graph, receiver);
+                ReadNode result = graph.add(new ReadNode(CiKind.Object, klassOop, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.classMirrorOffset, graph)));
+                ReturnNode ret = graph.add(new ReturnNode(result));
+                graph.start().setNext(klassOop);
+                klassOop.setNext(ret);
+                return graph;
+            }
+        } else if (holderName.equals("Ljava/lang/Class;")) {
+            if (fullName.equals("getModifiers()I")) {
+                StructuredGraph graph = new StructuredGraph();
+                LocalNode receiver = graph.unique(new LocalNode(CiKind.Object, 0));
+                SafeReadNode klassOop = safeRead(graph, CiKind.Object, receiver, config.klassOopOffset);
+                graph.start().setNext(klassOop);
+                // TODO(tw): Care about primitive classes! Crashes for primitive classes at the moment (klassOop == null)
+                ReadNode result = graph.add(new ReadNode(CiKind.Int, klassOop, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Int, config.klassModifierFlagsOffset, graph)));
+                ReturnNode ret = graph.add(new ReturnNode(result));
+                klassOop.setNext(ret);
+                return graph;
+            }
+        } else if (holderName.equals("Ljava/lang/Thread;")) {
+            if (fullName.equals("currentThread()Ljava/lang/Thread;")) {
+                StructuredGraph graph = new StructuredGraph();
+                ReturnNode ret = graph.add(new ReturnNode(graph.unique(new CurrentThread(config.threadObjectOffset))));
+                graph.start().setNext(ret);
+                return graph;
+            }
+        }
+        return null;
+    }
+
+    private SafeReadNode safeReadHub(Graph graph, ValueNode value) {
+        return safeRead(graph, CiKind.Object, value, config.hubOffset);
+    }
+
+    private SafeReadNode safeReadArrayLength(Graph graph, ValueNode value) {
+        return safeRead(graph, CiKind.Int, value, config.arrayLengthOffset);
+    }
+
+    private static SafeReadNode safeRead(Graph graph, CiKind kind, ValueNode value, int offset) {
+        return graph.add(new SafeReadNode(kind, value, LocationNode.create(LocationNode.FINAL_LOCATION, kind, offset, graph)));
+    }
+
+    public RiResolvedType getType(Class<?> clazz) {
+        return (RiResolvedType) compiler.getVMEntries().getType(clazz);
+    }
+
+    public Object asCallTarget(Object target) {
+        return target;
+    }
+
+    public long getMaxCallTargetOffset(CiRuntimeCall rtcall) {
+        return compiler.getVMEntries().getMaxCallTargetOffset(rtcall);
+    }
+
+    public RiResolvedMethod getRiMethod(Method reflectionMethod) {
+        return (RiResolvedMethod) compiler.getVMEntries().getRiMethod(reflectionMethod);
+    }
+
+    @Override
+    public void installMethod(RiResolvedMethod method, CiTargetMethod code) {
+        synchronized (method) {
+            if (((HotSpotMethodResolvedImpl) method).callback() == null) {
+                compiler.getVMEntries().installMethod(new HotSpotTargetMethod(compiler, (HotSpotMethodResolved) method, code), true);
+            } else {
+                // callback stub is installed.
+            }
+        }
+    }
+
+    @Override
+    public RiCompiledMethod addMethod(RiResolvedMethod method, CiTargetMethod code) {
+        return compiler.getVMEntries().installMethod(new HotSpotTargetMethod(compiler, (HotSpotMethodResolved) method, code), false);
+    }
+
+    public void installMethodCallback(RiResolvedMethod method, CiGenericCallback callback) {
+        synchronized (method) {
+            ((HotSpotMethodResolvedImpl) method).setCallback(callback);
+            CiTargetMethod callbackStub = createCallbackStub(method, callback);
+            compiler.getVMEntries().installMethod(new HotSpotTargetMethod(compiler, (HotSpotMethodResolved) method, callbackStub), true);
+        }
+    }
+
+    @Override
+    public RiRegisterConfig getGlobalStubRegisterConfig() {
+        return globalStubRegConfig;
+    }
+
+    private CiTargetMethod createCallbackStub(RiResolvedMethod method, CiGenericCallback callback) {
+        StructuredGraph graph = new StructuredGraph();
+        FrameStateBuilder frameState = new FrameStateBuilder(method, method.maxLocals(), method.maxStackSize(), graph, false);
+        ValueNode local0 = frameState.loadLocal(0);
+
+        FrameState initialFrameState = frameState.create(0);
+        graph.start().setStateAfter(initialFrameState);
+
+        ConstantNode callbackNode = ConstantNode.forObject(callback, this, graph);
+
+        RuntimeCallNode runtimeCall = graph.add(new RuntimeCallNode(CiRuntimeCall.GenericCallback, new ValueNode[] {callbackNode, local0}));
+        runtimeCall.setStateAfter(initialFrameState.duplicateModified(0, false, CiKind.Void, runtimeCall));
+
+        @SuppressWarnings("unused")
+        HotSpotCompiledMethod hotSpotCompiledMethod = new HotSpotCompiledMethod(null); // initialize class...
+        RiResolvedType compiledMethodClass = getType(HotSpotCompiledMethod.class);
+        RiResolvedField nmethodField = null;
+        for (RiResolvedField field : compiledMethodClass.declaredFields()) {
+            if (field.name().equals("nmethod")) {
+                nmethodField = field;
+                break;
+            }
+        }
+        assert nmethodField != null;
+        LoadFieldNode loadField = graph.add(new LoadFieldNode(runtimeCall, nmethodField));
+
+        CompareNode compare = graph.unique(new CompareNode(loadField, Condition.EQ, ConstantNode.forLong(0, graph)));
+
+        IfNode ifNull = graph.add(new IfNode(compare, 0.01));
+
+        BeginNode beginInvalidated = graph.add(new BeginNode());
+        DeoptimizeNode deoptInvalidated = graph.add(new DeoptimizeNode(DeoptAction.None));
+
+        BeginNode beginTailcall = graph.add(new BeginNode());
+        TailcallNode tailcall = graph.add(new TailcallNode(loadField, initialFrameState));
+        DeoptimizeNode deoptEnd = graph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile));
+
+        graph.start().setNext(runtimeCall);
+        runtimeCall.setNext(loadField);
+        loadField.setNext(ifNull);
+        ifNull.setTrueSuccessor(beginInvalidated);
+        ifNull.setFalseSuccessor(beginTailcall);
+        beginInvalidated.setNext(deoptInvalidated);
+        beginTailcall.setNext(tailcall);
+        tailcall.setNext(deoptEnd);
+
+        CiTargetMethod result = compiler.getCompiler().compileMethod(method, graph, -1, PhasePlan.DEFAULT);
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotSignature.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,155 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.hotspot.*;
+import com.oracle.max.graal.hotspot.Compiler;
+import com.oracle.max.graal.java.*;
+
+/**
+ * Represents a method signature.
+ */
+public class HotSpotSignature extends CompilerObject implements RiSignature {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -2890917956072366116L;
+    private final List<String> arguments = new ArrayList<>();
+    private final String returnType;
+    private final String originalString;
+    private RiType[] argumentTypes;
+    private RiType returnTypeCache;
+
+    public HotSpotSignature(Compiler compiler, String signature) {
+        super(compiler);
+        assert signature.length() > 0;
+        this.originalString = signature;
+
+        if (signature.charAt(0) == '(') {
+            int cur = 1;
+            while (cur < signature.length() && signature.charAt(cur) != ')') {
+                int nextCur = parseSignature(signature, cur);
+                arguments.add(signature.substring(cur, nextCur));
+                cur = nextCur;
+            }
+
+            cur++;
+            int nextCur = parseSignature(signature, cur);
+            returnType = signature.substring(cur, nextCur);
+            assert nextCur == signature.length();
+        } else {
+            returnType = null;
+        }
+    }
+
+    private static int parseSignature(String signature, int start) {
+        int cur = start;
+        char first;
+        do {
+            first = signature.charAt(cur++);
+        } while (first == '[');
+
+        switch (first) {
+            case 'L':
+                while (signature.charAt(cur) != ';') {
+                    cur++;
+                }
+                cur++;
+                break;
+            case 'V':
+            case 'I':
+            case 'B':
+            case 'C':
+            case 'D':
+            case 'F':
+            case 'J':
+            case 'S':
+            case 'Z':
+                break;
+            default:
+                assert false;
+        }
+        return cur;
+    }
+
+    @Override
+    public int argumentCount(boolean withReceiver) {
+        return arguments.size() + (withReceiver ? 1 : 0);
+    }
+
+    @Override
+    public CiKind argumentKindAt(int index, boolean architecture) {
+        return CiKind.fromTypeString(arguments.get(index));
+    }
+
+    @Override
+    public int argumentSlots(boolean withReceiver) {
+        int argSlots = 0;
+        for (int i = 0; i < argumentCount(false); i++) {
+            argSlots += FrameStateBuilder.stackSlots(argumentKindAt(i, false));
+        }
+        return argSlots + (withReceiver ? 1 : 0);
+    }
+
+    @Override
+    public RiType argumentTypeAt(int index, RiResolvedType accessingClass) {
+        if (argumentTypes == null) {
+            argumentTypes = new RiType[arguments.size()];
+        }
+        RiType type = argumentTypes[index];
+        if (type == null || !(type instanceof RiResolvedType)) {
+            type = compiler.lookupType(arguments.get(index), (HotSpotTypeResolved) accessingClass, true);
+            argumentTypes[index] = type;
+        }
+        return type;
+    }
+
+    @Override
+    public String asString() {
+        return originalString;
+    }
+
+    @Override
+    public CiKind returnKind(boolean architecture) {
+        return CiKind.fromTypeString(returnType);
+    }
+
+    @Override
+    public RiType returnType(RiType accessingClass) {
+        if (returnTypeCache == null) {
+            returnTypeCache = compiler.lookupType(returnType, (HotSpotTypeResolved) accessingClass, false);
+        }
+        return returnTypeCache;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotSignature<" + originalString + ">";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotType.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.hotspot.*;
+import com.oracle.max.graal.hotspot.Compiler;
+
+/**
+ * Common interface for all HotSpot RiType-implementations.
+ */
+public abstract class HotSpotType extends CompilerObject implements RiType {
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -4252886265301910771L;
+    protected String name;
+
+    protected HotSpotType(Compiler compiler) {
+        super(compiler);
+    }
+
+    @Override
+    public final String name() {
+        return name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypePrimitive.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,181 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.hotspot.Compiler;
+
+/**
+ * Implementation of RiType for primitive HotSpot types.
+ */
+public final class HotSpotTypePrimitive extends HotSpotType implements RiResolvedType {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -6208552348908071473L;
+    private CiKind kind;
+
+
+    public HotSpotTypePrimitive(Compiler compiler, CiKind kind) {
+        super(compiler);
+        this.kind = kind;
+        this.name = kind.toString();
+    }
+
+    @Override
+    public int accessFlags() {
+        assert kind != null && kind.toJavaClass() != null;
+        return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC;
+    }
+
+    @Override
+    public RiResolvedType arrayOf() {
+        return (RiResolvedType) compiler.getVMEntries().getPrimitiveArrayType(kind);
+    }
+
+    @Override
+    public RiResolvedType componentType() {
+        return null;
+    }
+
+    @Override
+    public RiResolvedType exactType() {
+        return this;
+    }
+
+    @Override
+    public RiResolvedType superType() {
+        return null;
+    }
+
+    @Override
+    public RiResolvedType leastCommonAncestor(RiResolvedType otherType) {
+        return null;
+    }
+
+    @Override
+    public CiConstant getEncoding(Representation r) {
+        throw GraalInternalError.unimplemented("HotSpotTypePrimitive.getEncoding");
+    }
+
+    @Override
+    public CiKind getRepresentationKind(Representation r) {
+        return kind;
+    }
+
+    @Override
+    public boolean hasFinalizableSubclass() {
+        return false;
+    }
+
+    @Override
+    public boolean hasFinalizer() {
+        return false;
+    }
+
+    @Override
+    public boolean hasSubclass() {
+        return false;
+    }
+
+    @Override
+    public boolean isArrayClass() {
+        return false;
+    }
+
+    @Override
+    public boolean isInitialized() {
+        return true;
+    }
+
+    @Override
+    public boolean isInstance(CiConstant obj) {
+        return false;
+    }
+
+    @Override
+    public boolean isInstanceClass() {
+        return false;
+    }
+
+    @Override
+    public boolean isInterface() {
+        return false;
+    }
+
+    @Override
+    public boolean isSubtypeOf(RiResolvedType other) {
+        return false;
+    }
+
+    @Override
+    public CiKind kind(boolean architecture) {
+        return kind;
+    }
+
+    @Override
+    public RiResolvedMethod resolveMethodImpl(RiResolvedMethod method) {
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotTypePrimitive<" + kind + ">";
+    }
+
+    @Override
+    public RiResolvedType uniqueConcreteSubtype() {
+        return this;
+    }
+
+    @Override
+    public RiResolvedMethod uniqueConcreteMethod(RiResolvedMethod method) {
+        return null;
+    }
+
+    @Override
+    public RiResolvedField[] declaredFields() {
+        return null;
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        return toJava().getAnnotation(annotationClass);
+    }
+
+    @Override
+    public Class< ? > toJava() {
+        return kind.toJavaClass();
+    }
+
+    @Override
+    public RiResolvedType resolve(RiResolvedType accessingClass) {
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypeResolved.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,38 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.hotspot.server.*;
+
+public interface HotSpotTypeResolved extends RiResolvedType, Remote {
+
+    String toString();
+
+    RiConstantPool constantPool();
+
+    int instanceSize();
+
+    RiField createRiField(String name, RiType type, int offset, int flags);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypeResolvedImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,270 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+
+/**
+ * Implementation of RiType for resolved non-primitive HotSpot classes.
+ */
+public final class HotSpotTypeResolvedImpl extends HotSpotType implements HotSpotTypeResolved {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 3481514353553840471L;
+    private Class javaMirror;
+    private String simpleName;
+    private int accessFlags;
+    private boolean hasFinalizer;
+    private boolean hasSubclass;
+    private boolean hasFinalizableSubclass;
+    private boolean isArrayClass;
+    private boolean isInstanceClass;
+    private boolean isInterface;
+    private int instanceSize;
+    private HashMap<Long, RiResolvedField> fieldCache;
+    private RiResolvedType superType;
+    private boolean superTypeSet;
+    private RiResolvedField[] fields;
+    private RiConstantPool constantPool;
+    private boolean isInitialized;
+    private RiResolvedType arrayOfType;
+
+    private HotSpotTypeResolvedImpl() {
+        super(null);
+    }
+
+    @Override
+    public int accessFlags() {
+        return accessFlags;
+    }
+
+    @Override
+    public RiResolvedType arrayOf() {
+        if (arrayOfType == null) {
+           arrayOfType = (RiResolvedType) compiler.getVMEntries().RiType_arrayOf(this);
+        }
+        return arrayOfType;
+    }
+
+    @Override
+    public RiResolvedType componentType() {
+        assert isArrayClass();
+        return (RiResolvedType) compiler.getVMEntries().RiType_componentType(this);
+    }
+
+    @Override
+    public RiResolvedType uniqueConcreteSubtype() {
+        if (isArrayClass()) {
+            return Modifier.isFinal(componentType().accessFlags()) ? this : null;
+        } else {
+            return (RiResolvedType) compiler.getVMEntries().RiType_uniqueConcreteSubtype(this);
+        }
+    }
+
+    @Override
+    public RiResolvedType superType() {
+        if (!superTypeSet) {
+            superType = (RiResolvedType) compiler.getVMEntries().RiType_superType(this);
+            superTypeSet = true;
+        }
+        return superType;
+    }
+
+    @Override
+    public RiResolvedType leastCommonAncestor(RiResolvedType otherType) {
+        if (otherType instanceof HotSpotTypePrimitive) {
+            return null;
+        } else {
+            return (RiResolvedType) compiler.getVMEntries().RiType_leastCommonAncestor(this, (HotSpotTypeResolved) otherType);
+        }
+    }
+
+    @Override
+    public RiResolvedType exactType() {
+        if (Modifier.isFinal(accessFlags)) {
+            return this;
+        }
+        return null;
+    }
+
+    @Override
+    public CiConstant getEncoding(Representation r) {
+        switch (r) {
+            case JavaClass:
+                return CiConstant.forObject(javaMirror);
+            case ObjectHub:
+                return CiConstant.forObject(this);
+            case StaticFields:
+                return CiConstant.forObject(javaMirror);
+            case TypeInfo:
+                return CiConstant.forObject(this);
+            default:
+                return null;
+        }
+    }
+
+    @Override
+    public CiKind getRepresentationKind(Representation r) {
+        return CiKind.Object;
+    }
+
+    @Override
+    public boolean hasFinalizableSubclass() {
+        return hasFinalizableSubclass;
+    }
+
+    @Override
+    public boolean hasFinalizer() {
+        return hasFinalizer;
+    }
+
+    @Override
+    public boolean hasSubclass() {
+        return hasSubclass;
+    }
+
+    @Override
+    public boolean isArrayClass() {
+        return isArrayClass;
+    }
+
+    @Override
+    public boolean isInitialized() {
+        if (!isInitialized) {
+            isInitialized = compiler.getVMEntries().RiType_isInitialized(this);
+        }
+        return isInitialized;
+    }
+
+    @Override
+    public boolean isInstance(CiConstant obj) {
+        return javaMirror.isInstance(obj);
+    }
+
+    @Override
+    public boolean isInstanceClass() {
+        return isInstanceClass;
+    }
+
+    @Override
+    public boolean isInterface() {
+        return isInterface;
+    }
+
+    @Override
+    public boolean isSubtypeOf(RiResolvedType other) {
+        if (other instanceof HotSpotTypeResolved) {
+            return compiler.getVMEntries().RiType_isSubtypeOf(this, other);
+        }
+        // No resolved type is a subtype of an unresolved type.
+        return false;
+    }
+
+    @Override
+    public CiKind kind(boolean architecture) {
+        return CiKind.Object;
+    }
+
+    @Override
+    public RiResolvedMethod resolveMethodImpl(RiResolvedMethod method) {
+        assert method instanceof HotSpotMethod;
+        return (RiResolvedMethod) compiler.getVMEntries().RiType_resolveMethodImpl(this, method.name(), method.signature().asString());
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotType<" + simpleName + ", resolved>";
+    }
+
+    @Override
+    public RiConstantPool constantPool() {
+        if (constantPool == null) {
+            constantPool = new HotSpotConstantPool(compiler, this);
+        }
+        return constantPool;
+    }
+
+    @Override
+    public int instanceSize() {
+        return instanceSize;
+    }
+
+    @Override
+    public synchronized RiResolvedField createRiField(String fieldName, RiType type, int offset, int flags) {
+        RiResolvedField result = null;
+
+        long id = offset + ((long) flags << 32);
+
+        // (tw) Must cache the fields, because the local load elimination only works if the objects from two field lookups are equal.
+        if (fieldCache == null) {
+            fieldCache = new HashMap<>(8);
+        } else {
+            result = fieldCache.get(id);
+        }
+
+        if (result == null) {
+            result = new HotSpotField(compiler, this, fieldName, type, offset, flags);
+            fieldCache.put(id, result);
+        } else {
+            assert result.name().equals(fieldName);
+            assert result.accessFlags() == flags;
+        }
+
+        return result;
+    }
+
+    @Override
+    public RiResolvedMethod uniqueConcreteMethod(RiResolvedMethod method) {
+        return ((HotSpotMethodResolved) method).uniqueConcreteMethod();
+    }
+
+    @Override
+    public RiResolvedField[] declaredFields() {
+        if (fields == null) {
+            fields = compiler.getVMEntries().RiType_fields(this);
+        }
+        return fields;
+    }
+
+    @Override
+    public Class< ? > toJava() {
+        return javaMirror;
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        return toJava().getAnnotation(annotationClass);
+    }
+
+    @Override
+    public RiResolvedType resolve(RiResolvedType accessingClass) {
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypeUnresolved.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,122 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.hotspot.Compiler;
+
+/**
+ * Implementation of RiType for unresolved HotSpot classes.
+ */
+public class HotSpotTypeUnresolved extends HotSpotType {
+
+    private static final long serialVersionUID = -2320936267633521314L;
+    public final String simpleName;
+    public final int dimensions;
+
+    /**
+     * Creates a new unresolved type for a specified type descriptor.
+     */
+    public HotSpotTypeUnresolved(Compiler compiler, String name) {
+        super(compiler);
+        assert name.length() > 0 : "name cannot be empty";
+
+        int dims = 0;
+        int startIndex = 0;
+        while (name.charAt(startIndex) == '[') {
+            startIndex++;
+            dims++;
+        }
+
+        // Decode name if necessary.
+        if (name.charAt(name.length() - 1) == ';') {
+            assert name.charAt(startIndex) == 'L';
+            this.simpleName = name.substring(startIndex + 1, name.length() - 1);
+            this.name = name;
+        } else {
+            this.simpleName = name;
+            this.name = getFullName(name, dims);
+        }
+
+        this.dimensions = dims;
+    }
+
+    public HotSpotTypeUnresolved(Compiler compiler, String name, int dimensions) {
+        super(compiler);
+        assert dimensions >= 0;
+        this.simpleName = name;
+        this.dimensions = dimensions;
+        this.name = getFullName(name, dimensions);
+    }
+
+    private static String getFullName(String name, int dimensions) {
+        StringBuilder str = new StringBuilder(name.length() + dimensions + 2);
+        for (int i = 0; i < dimensions; i++) {
+            str.append('[');
+        }
+        str.append('L').append(name).append(';');
+        return str.toString();
+    }
+
+    @Override
+    public RiType componentType() {
+        assert dimensions > 0 : "no array class" + name();
+        return new HotSpotTypeUnresolved(compiler, simpleName, dimensions - 1);
+    }
+
+    @Override
+    public RiType arrayOf() {
+        return new HotSpotTypeUnresolved(compiler, simpleName, dimensions + 1);
+    }
+
+    @Override
+    public CiKind kind(boolean architecture) {
+        return CiKind.Object;
+    }
+
+    @Override
+    public int hashCode() {
+        return simpleName.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return o == this;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotType<" + simpleName + ", unresolved>";
+    }
+
+    @Override
+    public CiKind getRepresentationKind(RiType.Representation r) {
+        return CiKind.Object;
+    }
+
+    @Override
+    public RiResolvedType resolve(RiResolvedType accessingClass) {
+        return (RiResolvedType) compiler.lookupType(name, (HotSpotTypeResolved) accessingClass, true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotXirGenerator.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1541 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.hotspot.ri;
+
+import static com.oracle.max.cri.ci.CiCallingConvention.Type.*;
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.max.graal.hotspot.ri.TemplateFlag.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiAddress.*;
+import com.oracle.max.cri.ci.CiRegister.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.cri.ri.RiType.*;
+import com.oracle.max.cri.xir.*;
+import com.oracle.max.cri.xir.CiXirAssembler.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.hotspot.*;
+import com.oracle.max.graal.hotspot.Compiler;
+
+public class HotSpotXirGenerator implements RiXirGenerator {
+
+    // this needs to correspond to graal_CodeInstaller.hpp
+    // @formatter:off
+    private static final Integer MARK_VERIFIED_ENTRY            = 0x0001;
+    private static final Integer MARK_UNVERIFIED_ENTRY          = 0x0002;
+    private static final Integer MARK_OSR_ENTRY                 = 0x0003;
+    private static final Integer MARK_UNWIND_ENTRY              = 0x0004;
+    private static final Integer MARK_EXCEPTION_HANDLER_ENTRY   = 0x0005;
+    private static final Integer MARK_DEOPT_HANDLER_ENTRY       = 0x0006;
+
+    private static final Integer MARK_STATIC_CALL_STUB          = 0x1000;
+
+    private static final Integer MARK_INVOKEINTERFACE           = 0x2001;
+    private static final Integer MARK_INVOKESTATIC              = 0x2002;
+    private static final Integer MARK_INVOKESPECIAL             = 0x2003;
+    private static final Integer MARK_INVOKEVIRTUAL             = 0x2004;
+
+    private static final Integer MARK_IMPLICIT_NULL             = 0x3000;
+    private static final Integer MARK_POLL_NEAR                 = 0x3001;
+    private static final Integer MARK_POLL_RETURN_NEAR          = 0x3002;
+    private static final Integer MARK_POLL_FAR                  = 0x3003;
+    private static final Integer MARK_POLL_RETURN_FAR           = 0x3004;
+
+    // @formatter:on
+
+    private final HotSpotVMConfig config;
+    private final CiTarget target;
+    private final RiRegisterConfig registerConfig;
+    private final Compiler compiler;
+
+    private CiXirAssembler globalAsm;
+
+    public HotSpotXirGenerator(HotSpotVMConfig config, CiTarget target, RiRegisterConfig registerConfig, Compiler compiler) {
+        this.config = config;
+        this.target = target;
+        this.registerConfig = registerConfig;
+        this.compiler = compiler;
+    }
+
+    private XirConstant wordConst(CiXirAssembler asm, long value) {
+        if (target.wordKind == CiKind.Long) {
+            return asm.createConstant(CiConstant.forLong(value));
+        } else {
+            assert target.wordKind == CiKind.Int;
+            return asm.createConstant(CiConstant.forInt((int) value));
+        }
+    }
+
+    private XirArgument wordArg(long value) {
+        if (target.wordKind == CiKind.Long) {
+            return XirArgument.forLong(value);
+        } else {
+            assert target.wordKind == CiKind.Int;
+            return XirArgument.forInt((int) value);
+        }
+    }
+
+    private SimpleTemplates prologueTemplates = new SimpleTemplates(STATIC_METHOD) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            asm.restart(CiKind.Void);
+            XirOperand framePointer = asm.createRegisterTemp("frame pointer", target.wordKind, AMD64.rbp);
+            XirOperand stackPointer = asm.createRegisterTemp("stack pointer", target.wordKind, AMD64.rsp);
+            XirLabel unverifiedStub = null;
+
+            asm.mark(MARK_OSR_ENTRY);
+            asm.mark(MARK_UNVERIFIED_ENTRY);
+            if (!is(STATIC_METHOD, flags)) {
+                unverifiedStub = asm.createOutOfLineLabel("unverified");
+
+                XirOperand temp = asm.createRegisterTemp("temp (r10)", target.wordKind, AMD64.r10);
+                XirOperand cache = asm.createRegisterTemp("cache (rax)", target.wordKind, AMD64.rax);
+
+                CiCallingConvention conventions = registerConfig.getCallingConvention(JavaCallee, new CiKind[] {CiKind.Object}, target, false);
+                XirOperand receiver = asm.createRegister("receiver", target.wordKind, asRegister(conventions.locations[0]));
+
+                asm.pload(target.wordKind, temp, receiver, asm.i(config.hubOffset), false);
+                asm.jneq(unverifiedStub, cache, temp);
+            }
+            asm.align(config.codeEntryAlignment);
+            asm.mark(MARK_VERIFIED_ENTRY);
+            asm.stackOverflowCheck();
+            asm.push(framePointer);
+            asm.mov(framePointer, stackPointer);
+            // Compensate for the push of framePointer (the XIR instruction pushFrame is not flexible enough to reduce the frame size, wait until XIR goes away to fix this).
+            asm.add(stackPointer, stackPointer,  asm.i(8));
+            asm.pushFrame();
+
+            // -- out of line -------------------------------------------------------
+            XirOperand thread = asm.createRegisterTemp("thread", target.wordKind, AMD64.r15);
+            XirOperand exceptionOop = asm.createTemp("exception oop", CiKind.Object);
+            XirLabel unwind = asm.createOutOfLineLabel("unwind");
+            asm.bindOutOfLine(unwind);
+
+            asm.mark(MARK_UNWIND_ENTRY);
+
+            asm.pload(CiKind.Object, exceptionOop, thread, asm.i(config.threadExceptionOopOffset), false);
+            asm.pstore(CiKind.Object, thread, asm.i(config.threadExceptionOopOffset), asm.createConstant(CiConstant.NULL_OBJECT), false);
+            asm.pstore(CiKind.Long, thread, asm.i(config.threadExceptionPcOffset), asm.l(0), false);
+
+            asm.callRuntime(config.unwindExceptionStub, null, exceptionOop);
+            asm.shouldNotReachHere();
+
+            asm.mark(MARK_EXCEPTION_HANDLER_ENTRY);
+            asm.callRuntime(config.handleExceptionStub, null);
+            asm.shouldNotReachHere();
+
+            asm.mark(MARK_DEOPT_HANDLER_ENTRY);
+            asm.callRuntime(config.handleDeoptStub, null);
+            asm.shouldNotReachHere();
+
+            if (!is(STATIC_METHOD, flags)) {
+                asm.bindOutOfLine(unverifiedStub);
+                asm.jmpRuntime(config.inlineCacheMissStub);
+            }
+
+            return asm.finishTemplate(is(STATIC_METHOD, flags) ? "static prologue" : "prologue");
+        }
+    };
+
+    private SimpleTemplates epilogueTemplates = new SimpleTemplates(STATIC_METHOD, SYNCHRONIZED) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            asm.restart(CiKind.Void);
+            XirOperand framePointer = asm.createRegisterTemp("frame pointer", target.wordKind, AMD64.rbp);
+            XirOperand stackPointer = asm.createRegisterTemp("stack pointer", target.wordKind, AMD64.rsp);
+
+            asm.popFrame();
+            asm.pload(CiKind.Long, framePointer, stackPointer, asm.i(-8), false);
+
+            if (GraalOptions.GenSafepoints) {
+                XirOperand temp = asm.createRegisterTemp("temp", target.wordKind, AMD64.r10);
+                if (config.isPollingPageFar) {
+                    asm.mov(temp, wordConst(asm, config.safepointPollingAddress));
+                    asm.mark(MARK_POLL_RETURN_FAR);
+                    asm.pload(target.wordKind, temp, temp, true);
+                } else {
+                    XirOperand rip = asm.createRegister("rip", target.wordKind, AMD64.rip);
+                    asm.mark(MARK_POLL_RETURN_NEAR);
+                    asm.pload(target.wordKind, temp, rip, asm.i(0xEFBEADDE), true);
+                }
+            }
+
+            return asm.finishTemplate("epilogue");
+        }
+    };
+
+    private SimpleTemplates safepointTemplates = new SimpleTemplates() {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            asm.restart(CiKind.Void);
+
+            XirOperand temp = asm.createRegisterTemp("temp", target.wordKind, AMD64.r10);
+            if (config.isPollingPageFar) {
+                asm.mov(temp, wordConst(asm, config.safepointPollingAddress));
+                asm.mark(MARK_POLL_FAR);
+                asm.pload(target.wordKind, temp, temp, true);
+            } else {
+                XirOperand rip = asm.createRegister("rip", target.wordKind, AMD64.rip);
+                asm.mark(MARK_POLL_NEAR);
+                asm.pload(target.wordKind, temp, rip, asm.i(0xEFBEADDE), true);
+            }
+
+            return asm.finishTemplate("safepoint");
+        }
+    };
+
+    private SimpleTemplates exceptionObjectTemplates = new SimpleTemplates() {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            XirOperand result = asm.restart(CiKind.Object);
+            XirOperand thread = asm.createRegisterTemp("thread", target.wordKind, AMD64.r15);
+
+            asm.pload(CiKind.Object, result, thread, asm.i(config.threadExceptionOopOffset), false);
+            asm.pstore(CiKind.Object, thread, asm.i(config.threadExceptionOopOffset), asm.o(null), false);
+            asm.pstore(CiKind.Long, thread, asm.i(config.threadExceptionPcOffset), asm.l(0), false);
+
+            return asm.finishTemplate("exception object");
+        }
+    };
+
+    private SimpleTemplates invokeInterfaceTemplates = new SimpleTemplates(NULL_CHECK) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            asm.restart();
+            XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object);
+            XirParameter addr = asm.createConstantInputParameter("addr", target.wordKind);
+            XirOperand temp = asm.createRegisterTemp("temp", target.wordKind, AMD64.rax);
+            XirOperand tempO = asm.createRegister("tempO", CiKind.Object, AMD64.rax);
+
+            if (is(NULL_CHECK, flags)) {
+                asm.mark(MARK_IMPLICIT_NULL);
+                asm.pload(target.wordKind, temp, receiver, true);
+            }
+            asm.mark(MARK_INVOKEINTERFACE);
+            asm.mov(tempO, asm.createConstant(CiConstant.forObject(HotSpotProxy.DUMMY_CONSTANT_OBJ)));
+
+            return asm.finishTemplate(addr, "invokeinterface");
+        }
+    };
+
+    private SimpleTemplates invokeVirtualTemplates = new SimpleTemplates(NULL_CHECK) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            asm.restart();
+            XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object);
+            XirParameter addr = asm.createConstantInputParameter("addr", target.wordKind);
+            XirOperand temp = asm.createRegisterTemp("temp", target.wordKind, AMD64.rax);
+            XirOperand tempO = asm.createRegister("tempO", CiKind.Object, AMD64.rax);
+
+            if (is(NULL_CHECK, flags)) {
+                asm.mark(MARK_IMPLICIT_NULL);
+                asm.pload(target.wordKind, temp, receiver, true);
+            }
+            asm.mark(MARK_INVOKEVIRTUAL);
+            asm.mov(tempO, asm.createConstant(CiConstant.forObject(HotSpotProxy.DUMMY_CONSTANT_OBJ)));
+
+            return asm.finishTemplate(addr, "invokevirtual");
+        }
+    };
+
+    private SimpleTemplates invokeSpecialTemplates = new SimpleTemplates(NULL_CHECK) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            asm.restart();
+            XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object);
+            XirParameter addr = asm.createConstantInputParameter("addr", target.wordKind);
+            XirOperand temp = asm.createRegisterTemp("temp", target.wordKind, AMD64.rax);
+            XirLabel stub = asm.createOutOfLineLabel("call stub");
+
+            if (is(NULL_CHECK, flags)) {
+                asm.mark(MARK_IMPLICIT_NULL);
+                asm.pload(target.wordKind, temp, receiver, true);
+            }
+            asm.mark(MARK_INVOKESPECIAL);
+
+            // -- out of line -------------------------------------------------------
+            asm.bindOutOfLine(stub);
+            XirOperand method = asm.createRegisterTemp("method", target.wordKind, AMD64.rbx);
+            asm.mark(MARK_STATIC_CALL_STUB, XirMark.CALLSITE);
+            asm.mov(method, wordConst(asm, 0));
+            XirLabel dummy = asm.createOutOfLineLabel("dummy");
+            asm.jmp(dummy);
+            asm.bindOutOfLine(dummy);
+
+            return asm.finishTemplate(addr, "invokespecial");
+        }
+    };
+
+    private SimpleTemplates invokeStaticTemplates = new SimpleTemplates() {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            asm.restart();
+            XirParameter addr = asm.createConstantInputParameter("addr", target.wordKind);
+
+            XirLabel stub = asm.createOutOfLineLabel("call stub");
+            asm.mark(MARK_INVOKESTATIC);
+
+            // -- out of line -------------------------------------------------------
+            asm.bindOutOfLine(stub);
+            XirOperand method = asm.createRegisterTemp("method", target.wordKind, AMD64.rbx);
+            asm.mark(MARK_STATIC_CALL_STUB, XirMark.CALLSITE);
+            asm.mov(method, wordConst(asm, 0));
+            XirLabel dummy = asm.createOutOfLineLabel("dummy");
+            asm.jmp(dummy);
+            asm.bindOutOfLine(dummy);
+
+            return asm.finishTemplate(addr, "invokestatic");
+        }
+    };
+
+    private SimpleTemplates monitorEnterTemplates = new SimpleTemplates(NULL_CHECK) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            asm.restart(CiKind.Void);
+            XirParameter object = asm.createInputParameter("object", CiKind.Object);
+            XirParameter lock = asm.createInputParameter("lock", target.wordKind);
+
+            if (is(NULL_CHECK, flags)) {
+                asm.mark(MARK_IMPLICIT_NULL);
+                asm.pload(target.wordKind, asm.createTemp("temp", target.wordKind), object, true);
+            }
+
+
+            // (tw) It is important to use for this runtime call the debug info AFTER the monitor enter. Otherwise the monitor object
+            // is not correctly garbage collected.
+            final boolean useInfoAfter = true;
+
+            if (config.useFastLocking) {
+                useRegisters(asm, AMD64.rax, AMD64.rbx);
+                useRegisters(asm, getGeneralParameterRegister(0));
+                useRegisters(asm, getGeneralParameterRegister(1));
+                asm.callRuntime(config.fastMonitorEnterStub, null, useInfoAfter, object, lock);
+            } else {
+                asm.reserveOutgoingStack(target.wordSize * 2);
+                XirOperand rsp = asm.createRegister("rsp", target.wordKind, asRegister(AMD64.RSP));
+                asm.pstore(CiKind.Object, rsp, asm.i(target.wordSize), object, false);
+                asm.pstore(target.wordKind, rsp, asm.i(0), lock, false);
+                asm.callRuntime(config.monitorEnterStub, null, useInfoAfter);
+            }
+
+            return asm.finishTemplate("monitorEnter");
+        }
+    };
+
+    private CiRegister getGeneralParameterRegister(int index) {
+        return registerConfig.getCallingConventionRegisters(CiCallingConvention.Type.RuntimeCall, RegisterFlag.CPU)[index];
+    }
+
+    private SimpleTemplates monitorExitTemplates = new SimpleTemplates(NULL_CHECK) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            asm.restart(CiKind.Void);
+            XirParameter object = asm.createInputParameter("object", CiKind.Object);
+            XirParameter lock = asm.createInputParameter("lock", target.wordKind);
+
+            if (config.useFastLocking) {
+                useRegisters(asm, AMD64.rax, AMD64.rbx);
+                useRegisters(asm, getGeneralParameterRegister(0));
+                useRegisters(asm, getGeneralParameterRegister(1));
+                asm.callRuntime(config.fastMonitorExitStub, null, object, lock);
+            } else {
+                asm.reserveOutgoingStack(target.wordSize);
+                asm.pstore(target.wordKind, asm.createRegister("rsp", target.wordKind, asRegister(AMD64.RSP)), asm.i(0), lock, false);
+                asm.callRuntime(config.monitorExitStub, null);
+            }
+
+            return asm.finishTemplate("monitorExit");
+        }
+    };
+
+    private KindTemplates getFieldTemplates = new KindTemplates(NULL_CHECK) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, CiKind kind) {
+            XirOperand result = asm.restart(kind);
+            XirParameter object = asm.createInputParameter("object", CiKind.Object);
+
+            XirParameter fieldOffset = asm.createConstantInputParameter("fieldOffset", CiKind.Int);
+            if (is(NULL_CHECK, flags)) {
+                asm.mark(MARK_IMPLICIT_NULL);
+            }
+            asm.pload(kind, result, object, fieldOffset, is(NULL_CHECK, flags));
+            return asm.finishTemplate("getfield<" + kind + ">");
+        }
+    };
+
+    private KindTemplates writeBarrierTemplate = new KindTemplates() {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, CiKind kind) {
+            asm.restart(CiKind.Void);
+            XirParameter object = asm.createInputParameter("object", CiKind.Object);
+
+            // Need temp operand, because the write barrier destroys the object pointer.
+            XirOperand temp = asm.createTemp("temp", target.wordKind);
+            asm.mov(temp, object);
+
+            writeBarrier(asm, temp);
+            return asm.finishTemplate("writeBarrier");
+        }
+    };
+
+    private KindTemplates putFieldTemplates = new KindTemplates(WRITE_BARRIER, NULL_CHECK) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, CiKind kind) {
+            asm.restart(CiKind.Void);
+            XirParameter object = asm.createInputParameter("object", CiKind.Object);
+            XirParameter value = asm.createInputParameter("value", kind);
+            XirParameter fieldOffset = asm.createConstantInputParameter("fieldOffset", CiKind.Int);
+            if (kind == CiKind.Object) {
+                verifyPointer(asm, value);
+            }
+            if (is(NULL_CHECK, flags)) {
+                asm.mark(MARK_IMPLICIT_NULL);
+            }
+            asm.pstore(kind, object, fieldOffset, value, is(NULL_CHECK, flags));
+            if (is(WRITE_BARRIER, flags) && kind == CiKind.Object) {
+                XirOperand temp = asm.createTemp("temp", target.wordKind);
+                asm.mov(temp, object);
+                writeBarrier(asm, temp);
+            }
+            return asm.finishTemplate("putfield<" + kind + ">");
+        }
+    };
+
+    private final IndexTemplates newInstanceTemplates = new IndexTemplates() {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, int size) {
+            XirOperand result = asm.restart(target.wordKind);
+            XirOperand type = asm.createInputParameter("type", CiKind.Object);
+
+            XirOperand temp1 = asm.createRegisterTemp("temp1", target.wordKind, AMD64.rcx);
+            XirOperand temp1o = asm.createRegister("temp1o", CiKind.Object, AMD64.rcx);
+            XirOperand temp2 = asm.createRegisterTemp("temp2", target.wordKind, AMD64.rbx);
+            XirOperand temp2i = asm.createRegister("temp2i", CiKind.Int, AMD64.rbx);
+            useRegisters(asm, AMD64.rsi);
+            XirLabel tlabFull = asm.createOutOfLineLabel("tlab full");
+            XirLabel resume = asm.createInlineLabel("resume");
+
+            // check if the class is already initialized
+            asm.pload(CiKind.Int, temp2i, type, asm.i(config.klassStateOffset), false);
+            asm.jneq(tlabFull, temp2i, asm.i(config.klassStateFullyInitialized));
+
+            XirOperand thread = asm.createRegisterTemp("thread", target.wordKind, AMD64.r15);
+            asm.pload(target.wordKind, result, thread, asm.i(config.threadTlabTopOffset), false);
+            asm.add(temp1, result, wordConst(asm, size));
+            asm.pload(target.wordKind, temp2, thread, asm.i(config.threadTlabEndOffset), false);
+
+            asm.jgt(tlabFull, temp1, temp2);
+            asm.pstore(target.wordKind, thread, asm.i(config.threadTlabTopOffset), temp1, false);
+
+            asm.bindInline(resume);
+
+            asm.pload(target.wordKind, temp1, type, asm.i(config.instanceHeaderPrototypeOffset), false);
+            asm.pstore(target.wordKind, result, temp1, false);
+            asm.mov(temp1o, type); // need a temporary register since Intel cannot store 64-bit constants to memory
+            asm.pstore(CiKind.Object, result, asm.i(config.hubOffset), temp1o, false);
+
+            if (size > 2 * target.wordSize) {
+                asm.mov(temp1, wordConst(asm, 0));
+                for (int offset = 2 * target.wordSize; offset < size; offset += target.wordSize) {
+                    asm.pstore(target.wordKind, result, asm.i(offset), temp1, false);
+                }
+            }
+
+            // -- out of line -------------------------------------------------------
+            asm.bindOutOfLine(tlabFull);
+            XirOperand arg = asm.createRegisterTemp("runtime call argument", CiKind.Object, AMD64.rdx);
+            asm.mov(arg, type);
+            useRegisters(asm, AMD64.rax);
+            asm.callRuntime(config.newInstanceStub, result);
+            asm.jmp(resume);
+
+            return asm.finishTemplate("new instance");
+        }
+    };
+
+    private SimpleTemplates newObjectArrayCloneTemplates = new SimpleTemplates() {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            XirOperand result = asm.restart(CiKind.Object);
+            XirParameter lengthParam = asm.createInputParameter("length", CiKind.Int, true);
+            XirParameter src = asm.createInputParameter("src", CiKind.Object);
+
+            // Set up length and hub.
+            XirOperand length = asm.createRegisterTemp("length", CiKind.Int, AMD64.rbx);
+            XirOperand hub = asm.createRegisterTemp("hub", CiKind.Object, AMD64.rdx);
+            asm.pload(CiKind.Object, hub, src, asm.i(config.hubOffset), false);
+            asm.mov(length, lengthParam);
+
+            useRegisters(asm, AMD64.rsi, AMD64.rcx, AMD64.rdi, AMD64.rax);
+            asm.callRuntime(config.newObjectArrayStub, result);
+            return asm.finishTemplate("objectArrayClone");
+        }
+    };
+
+    private SimpleTemplates newObjectArrayTemplates = new SimpleTemplates() {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            emitNewTypeArray(asm, CiKind.Object, config.useFastNewObjectArray, config.newObjectArrayStub);
+            return asm.finishTemplate("newObjectArray");
+        }
+    };
+
+    private void emitNewTypeArray(CiXirAssembler asm, CiKind kind, boolean useFast, long slowPathStub) {
+        XirOperand result = asm.restart(target.wordKind);
+
+        XirParameter lengthParam = asm.createInputParameter("length", CiKind.Int, true);
+
+        XirOperand length = asm.createRegisterTemp("length", CiKind.Int, AMD64.rbx);
+        XirOperand hub = asm.createRegisterTemp("hub", CiKind.Object, AMD64.rdx);
+
+        // Registers rsi, rcx, rdi, and rax are needed by the runtime call.
+        // Hub needs to be on rdx, length on rbx.
+        XirOperand temp1 = asm.createRegisterTemp("temp1", target.wordKind, AMD64.rcx);
+        XirOperand temp1o = asm.createRegister("temp1o", CiKind.Object, AMD64.rcx);
+        XirOperand temp2 = asm.createRegisterTemp("temp2", target.wordKind, AMD64.rax);
+        XirOperand temp3 = asm.createRegisterTemp("temp3", target.wordKind, AMD64.rdi);
+        XirOperand size = asm.createRegisterTemp("size", CiKind.Int, AMD64.rsi);
+
+        asm.mov(hub, asm.createConstantInputParameter("hub", CiKind.Object));
+        asm.mov(length, lengthParam);
+
+        if (useFast) {
+
+            XirLabel slowPath = asm.createOutOfLineLabel("slowPath");
+
+            XirLabel done = asm.createInlineLabel("done");
+
+            // Check for negative array size.
+            // TODO: Also check for upper bound
+            asm.jlt(slowPath, length, asm.i(0));
+
+            final int aligning = target.wordSize;
+            final int arrayLengthOffset = target.wordSize * 2;
+            final int arrayElementOffset = config.getArrayOffset(kind);
+
+            // Calculate aligned size
+            asm.mov(size, length);
+            int scale = CiUtil.log2(target.sizeInBytes(kind));
+            if (scale != 0) {
+                asm.shl(size, size, asm.i(scale));
+            }
+            asm.add(size, size, asm.i(arrayElementOffset + aligning - 1));
+            long mask = 0xFFFFFFFFL;
+            mask <<= CiUtil.log2(aligning);
+            asm.and(size, size, asm.i((int) mask));
+
+            // Try tlab allocation
+            XirOperand thread = asm.createRegisterTemp("thread", target.wordKind, AMD64.r15);
+            asm.pload(target.wordKind, result, thread, asm.i(config.threadTlabTopOffset), false);
+            asm.add(temp1, result, size);
+            asm.pload(target.wordKind, temp2, thread, asm.i(config.threadTlabEndOffset), false);
+            asm.jgt(slowPath, temp1, temp2);
+            asm.pstore(target.wordKind, thread, asm.i(config.threadTlabTopOffset), temp1, false);
+
+            // Now the new object is in result, store mark word and klass
+            asm.pload(target.wordKind, temp1, hub, asm.i(config.instanceHeaderPrototypeOffset), false);
+            asm.pstore(target.wordKind, result, temp1, false);
+            asm.mov(temp1o, hub); // need a temporary register since Intel cannot store 64-bit constants to memory
+            asm.pstore(CiKind.Object, result, asm.i(config.hubOffset), temp1o, false);
+
+            // Store array length
+            asm.pstore(CiKind.Int, result, asm.i(arrayLengthOffset), length, false);
+
+            // Initialize with 0
+            XirLabel top = asm.createInlineLabel("top");
+            asm.sub(size, size, asm.i(arrayElementOffset));
+            asm.shr(size, size, asm.i(Scale.Times8.log2));
+            asm.jeq(done, size, asm.i(0));
+            asm.xor(temp3, temp3, temp3);
+            asm.bindInline(top);
+            asm.pstore(target.wordKind, result, size, temp3, arrayElementOffset - target.wordSize, Scale.Times8, false);
+            asm.decAndJumpNotZero(top, size);
+
+            asm.bindInline(done);
+
+            // Slow path
+            asm.bindOutOfLine(slowPath);
+            asm.callRuntime(slowPathStub, result);
+            asm.jmp(done);
+        } else {
+            asm.callRuntime(slowPathStub, result);
+        }
+    }
+
+    private KindTemplates newTypeArrayTemplates = new KindTemplates() {
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, CiKind kind) {
+            emitNewTypeArray(asm, kind, config.useFastNewTypeArray, config.newTypeArrayStub);
+            return asm.finishTemplate("newTypeArray<" + kind.toString() + ">");
+        }
+    };
+
+    private final IndexTemplates multiNewArrayTemplate = new IndexTemplates() {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, int dimensions) {
+            XirOperand result = asm.restart(CiKind.Object);
+
+            XirOperand hub = asm.createRegisterTemp("hub", CiKind.Object, AMD64.rax);
+            XirOperand rank = asm.createRegisterTemp("rank", CiKind.Int, AMD64.rbx);
+            XirOperand sizes = asm.createRegisterTemp("sizes", CiKind.Long, AMD64.rcx);
+            XirOperand thread = asm.createRegisterTemp("thread", CiKind.Long, AMD64.r15);
+            asm.add(sizes, thread, asm.l(config.threadMultiNewArrayStorage));
+            for (int i = 0; i < dimensions; i++) {
+                XirParameter length = asm.createInputParameter("length" + i, CiKind.Int, true);
+                asm.pstore(CiKind.Int, sizes, asm.i(i * target.sizeInBytes(CiKind.Int)), length, false);
+            }
+
+            asm.mov(hub, asm.createConstantInputParameter("hub", CiKind.Object));
+
+            asm.mov(rank, asm.i(dimensions));
+            // not necessary because we already have a temp in rax:  useRegisters(asm, AMD64.rax);
+            asm.callRuntime(config.newMultiArrayStub, result);
+            return asm.finishTemplate("multiNewArray" + dimensions);
+        }
+    };
+
+    private IndexTemplates checkCastTemplates = new IndexTemplates(NULL_CHECK, EXACT_HINTS) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, int hintCount) {
+            asm.restart(CiKind.Void);
+            XirParameter object = asm.createInputParameter("object", CiKind.Object);
+            final XirOperand hub = is(EXACT_HINTS, flags) ? null : asm.createConstantInputParameter("hub", CiKind.Object);
+
+            XirOperand objHub = asm.createTemp("objHub", CiKind.Object);
+
+            XirLabel end = asm.createInlineLabel("end");
+            XirLabel slowPath = asm.createOutOfLineLabel("slow path");
+
+            if (is(NULL_CHECK, flags)) {
+                // null can be cast to anything
+                asm.jeq(end, object, asm.o(null));
+            }
+
+            asm.pload(CiKind.Object, objHub, object, asm.i(config.hubOffset), false);
+            if (hintCount == 0) {
+                assert !is(EXACT_HINTS, flags);
+                checkSubtype(asm, objHub, objHub, hub);
+                asm.jeq(slowPath, objHub, asm.o(null));
+                asm.bindInline(end);
+
+                // -- out of line -------------------------------------------------------
+                asm.bindOutOfLine(slowPath);
+            } else {
+                XirOperand scratchObject = asm.createRegisterTemp("scratch", CiKind.Object, AMD64.r10);
+                // if we get an exact match: succeed immediately
+                for (int i = 0; i < hintCount; i++) {
+                    XirParameter hintHub = asm.createConstantInputParameter("hintHub" + i, CiKind.Object);
+                    asm.mov(scratchObject, hintHub);
+                    if (i < hintCount - 1) {
+                        asm.jeq(end, objHub, scratchObject);
+                    } else {
+                        asm.jneq(slowPath, objHub, scratchObject);
+                    }
+                }
+                asm.bindInline(end);
+
+                // -- out of line -------------------------------------------------------
+                asm.bindOutOfLine(slowPath);
+                if (!is(EXACT_HINTS, flags)) {
+                    checkSubtype(asm, objHub, objHub, hub);
+                    asm.jneq(end, objHub, asm.o(null));
+                }
+            }
+            XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10);
+
+            asm.mov(scratch, wordConst(asm, 2));
+
+            asm.callRuntime(CiRuntimeCall.Deoptimize, null);
+            asm.shouldNotReachHere();
+
+            return asm.finishTemplate("checkcast");
+        }
+    };
+
+    private IndexTemplates instanceOfTemplates = new IndexTemplates(NULL_CHECK, EXACT_HINTS) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, int hintCount) {
+            asm.restart(CiKind.Void);
+            XirParameter object = asm.createInputParameter("object", CiKind.Object);
+            final XirOperand hub = is(EXACT_HINTS, flags) ? null : asm.createConstantInputParameter("hub", CiKind.Object);
+
+            XirOperand objHub = asm.createTemp("objHub", CiKind.Object);
+
+            XirLabel trueSucc = asm.createInlineLabel(XirLabel.TrueSuccessor);
+            XirLabel falseSucc = asm.createInlineLabel(XirLabel.FalseSuccessor);
+
+            if (is(NULL_CHECK, flags)) {
+                // null isn't "instanceof" anything
+                asm.jeq(falseSucc, object, asm.o(null));
+            }
+
+            asm.pload(CiKind.Object, objHub, object, asm.i(config.hubOffset), false);
+            if (hintCount == 0) {
+                assert !is(EXACT_HINTS, flags);
+                checkSubtype(asm, objHub, objHub, hub);
+                asm.jeq(falseSucc, objHub, asm.o(null));
+                asm.jmp(trueSucc);
+            } else {
+                XirLabel slowPath = null;
+                XirOperand scratchObject = asm.createRegisterTemp("scratch", CiKind.Object, AMD64.r10);
+
+                // if we get an exact match: succeed immediately
+                for (int i = 0; i < hintCount; i++) {
+                    XirParameter hintHub = asm.createConstantInputParameter("hintHub" + i, CiKind.Object);
+                    asm.mov(scratchObject, hintHub);
+                    if (i < hintCount - 1) {
+                        asm.jeq(trueSucc, objHub, scratchObject);
+                    } else {
+                        if (is(EXACT_HINTS, flags)) {
+                            asm.jneq(falseSucc, objHub, scratchObject);
+                            asm.jmp(trueSucc);
+                        } else {
+                            slowPath = asm.createOutOfLineLabel("slow path");
+                            asm.jneq(slowPath, objHub, scratchObject);
+                            asm.jmp(trueSucc);
+                        }
+                    }
+                }
+
+                // -- out of line -------------------------------------------------------
+                if (slowPath != null) {
+                    asm.bindOutOfLine(slowPath);
+                    checkSubtype(asm, objHub, objHub, hub);
+                    asm.jeq(falseSucc, objHub, asm.o(null));
+                    asm.jmp(trueSucc);
+                }
+            }
+
+            return asm.finishTemplate("instanceof");
+        }
+    };
+
+    private IndexTemplates materializeInstanceOfTemplates = new IndexTemplates(NULL_CHECK, EXACT_HINTS) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, int hintCount) {
+            XirOperand result = asm.restart(CiKind.Int);
+            XirParameter object = asm.createInputParameter("object", CiKind.Object);
+            final XirOperand hub = is(EXACT_HINTS, flags) ? null : asm.createConstantInputParameter("hub", CiKind.Object);
+            XirOperand trueValue = asm.createInputParameter("trueValue", CiKind.Int);
+            XirOperand falseValue = asm.createInputParameter("falseValue", CiKind.Int);
+
+            XirOperand objHub = asm.createTemp("objHub", CiKind.Object);
+
+            XirLabel end = asm.createInlineLabel("end");
+            XirLabel falseSucc = asm.createInlineLabel("ko");
+
+            if (is(NULL_CHECK, flags)) {
+                // null isn't "instanceof" anything
+                asm.jeq(falseSucc, object, asm.o(null));
+            }
+
+            asm.pload(CiKind.Object, objHub, object, asm.i(config.hubOffset), false);
+            asm.mov(result, trueValue);
+
+            if (hintCount == 0) {
+                assert !is(EXACT_HINTS, flags);
+                checkSubtype(asm, objHub, objHub, hub);
+                asm.jneq(end, objHub, asm.o(null));
+                asm.bindInline(falseSucc);
+                asm.mov(result, falseValue);
+                asm.bindInline(end);
+            } else {
+                XirLabel slowPath = null;
+                XirOperand scratchObject = asm.createRegisterTemp("scratch", CiKind.Object, AMD64.r10);
+
+                // if we get an exact match: succeed immediately
+                for (int i = 0; i < hintCount; i++) {
+                    XirParameter hintHub = asm.createConstantInputParameter("hintHub" + i, CiKind.Object);
+                    asm.mov(scratchObject, hintHub);
+                    if (i < hintCount - 1) {
+                        asm.jeq(end, objHub, scratchObject);
+                    } else {
+                        if (is(EXACT_HINTS, flags)) {
+                            asm.jeq(end, objHub, scratchObject);
+                        } else {
+                            slowPath = asm.createOutOfLineLabel("slow path");
+                            asm.jeq(end, objHub, scratchObject);
+                            asm.jmp(slowPath);
+                        }
+                    }
+                }
+                asm.bindInline(falseSucc);
+                asm.mov(result, falseValue);
+                asm.bindInline(end);
+
+                // -- out of line -------------------------------------------------------
+                if (slowPath != null) {
+                    asm.bindOutOfLine(slowPath);
+                    checkSubtype(asm, objHub, objHub, hub);
+                    asm.jeq(falseSucc, objHub, asm.o(null));
+                    asm.jmp(end);
+                }
+            }
+
+            return asm.finishTemplate("instanceof");
+        }
+    };
+
+    private XirOperand genArrayLength(CiXirAssembler asm, XirOperand array, boolean implicitNullException) {
+        XirOperand length = asm.createTemp("length", CiKind.Int);
+        genArrayLength(asm, length, array, implicitNullException);
+        return length;
+    }
+
+    private void genArrayLength(CiXirAssembler asm, XirOperand length, XirOperand array, boolean implicitNullException) {
+        if (implicitNullException) {
+            asm.mark(MARK_IMPLICIT_NULL);
+        }
+        asm.pload(CiKind.Int, length, array, asm.i(config.arrayLengthOffset), implicitNullException);
+    }
+
+    private KindTemplates arrayLoadTemplates = new KindTemplates(NULL_CHECK, READ_BARRIER, BOUNDS_CHECK, GIVEN_LENGTH) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, CiKind kind) {
+            XirOperand result = asm.restart(kind);
+            XirParameter array = asm.createInputParameter("array", CiKind.Object);
+            XirParameter index = asm.createInputParameter("index", CiKind.Int, true);
+            XirLabel failBoundsCheck = null;
+            // if the length is known the array cannot be null
+            boolean implicitNullException = is(NULL_CHECK, flags);
+
+            if (is(BOUNDS_CHECK, flags)) {
+                // load the array length and check the index
+                failBoundsCheck = asm.createOutOfLineLabel("failBoundsCheck");
+                XirOperand length;
+                if (is(GIVEN_LENGTH, flags)) {
+                    length = asm.createInputParameter("length", CiKind.Int, true);
+                } else {
+                    length = genArrayLength(asm, array, implicitNullException);
+                }
+                asm.jugteq(failBoundsCheck, index, length);
+                implicitNullException = false;
+            }
+            int elemSize = target.sizeInBytes(kind);
+            if (implicitNullException) {
+                asm.mark(MARK_IMPLICIT_NULL);
+            }
+            asm.pload(kind, result, array, index, config.getArrayOffset(kind), Scale.fromInt(elemSize), implicitNullException);
+            if (is(BOUNDS_CHECK, flags)) {
+                asm.bindOutOfLine(failBoundsCheck);
+                XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10);
+                asm.mov(scratch, wordConst(asm, 0));
+                asm.callRuntime(CiRuntimeCall.Deoptimize, null);
+                asm.shouldNotReachHere();
+            }
+            return asm.finishTemplate("arrayload<" + kind + ">");
+        }
+    };
+
+    private SimpleTemplates getClassTemplates = new SimpleTemplates() {
+       @Override
+       protected XirTemplate create(CiXirAssembler asm, long flags) {
+           XirOperand result = asm.restart(CiKind.Object);
+           XirOperand object = asm.createInputParameter("object", CiKind.Object);
+           asm.pload(CiKind.Object, result, object, asm.i(config.hubOffset), is(NULL_CHECK, flags));
+           asm.pload(CiKind.Object, result, result, asm.i(config.classMirrorOffset), false);
+           return asm.finishTemplate("getClass");
+       }
+    };
+
+    private SimpleTemplates currentThreadTemplates = new SimpleTemplates() {
+       @Override
+       protected XirTemplate create(CiXirAssembler asm, long flags) {
+           XirOperand result = asm.restart(CiKind.Object);
+           XirOperand thread = asm.createRegisterTemp("thread", target.wordKind, AMD64.r15);
+           asm.pload(CiKind.Object, result, thread, asm.i(config.threadObjectOffset), false);
+           return asm.finishTemplate("currentThread");
+       }
+    };
+
+    @Override
+    public XirSnippet genCurrentThread(XirSite site) {
+        return new XirSnippet(currentThreadTemplates.get(site));
+    }
+
+    @Override
+    public XirSnippet genGetClass(XirSite site, XirArgument object) {
+        return new XirSnippet(getClassTemplates.get(site), object);
+    }
+
+    private KindTemplates arrayCopyTemplates = new KindTemplates() {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, CiKind kind) {
+            asm.restart(CiKind.Void);
+            XirParameter src = asm.createInputParameter("src", CiKind.Object);
+            XirParameter srcPos = asm.createInputParameter("srcPos", CiKind.Int, true);
+            XirParameter dest = asm.createInputParameter("dest", CiKind.Object);
+            XirParameter destPos = asm.createInputParameter("destPos", CiKind.Int, true);
+            XirParameter length = asm.createInputParameter("length", CiKind.Int, true);
+
+            XirOperand tempSrc = asm.createTemp("tempSrc", target.wordKind);
+            XirOperand tempDest = asm.createTemp("tempDest", target.wordKind);
+            XirOperand lengthOperand = asm.createRegisterTemp("lengthOperand", CiKind.Int, AMD64.rax);
+
+            XirOperand compHub = null;
+            XirOperand valueHub = null;
+            XirOperand temp = null;
+            XirLabel store = null;
+            XirLabel slowStoreCheck = null;
+
+            if (is(STORE_CHECK, flags) && kind == CiKind.Object) {
+                valueHub = asm.createRegisterTemp("valueHub", target.wordKind, AMD64.rdi);
+                compHub = asm.createRegisterTemp("compHub", target.wordKind, AMD64.rsi);
+                temp = asm.createRegisterTemp("temp", target.wordKind, AMD64.r10);
+            }
+
+            // Calculate the factor for the repeat move instruction.
+            int elementSize = target.sizeInBytes(kind);
+            int factor;
+            boolean wordSize;
+            if (elementSize >= target.wordSize) {
+                assert elementSize % target.wordSize == 0;
+                wordSize = true;
+                factor = elementSize / target.wordSize;
+            } else {
+                factor = elementSize;
+                wordSize = false;
+            }
+
+            // Adjust the length if the factor is not 1.
+            if (factor != 1) {
+                asm.shl(lengthOperand, length, asm.i(CiUtil.log2(factor)));
+            } else {
+                asm.mov(lengthOperand, length);
+            }
+
+            // Set the start and the end pointer.
+            asm.lea(tempSrc, src, srcPos, config.getArrayOffset(kind), Scale.fromInt(elementSize));
+            asm.lea(tempDest, dest, destPos, config.getArrayOffset(kind), Scale.fromInt(elementSize));
+
+            XirLabel reverse = null;
+            XirLabel normal = null;
+
+            if (is(STORE_CHECK, flags)) {
+                reverse = asm.createInlineLabel("reverse");
+                asm.jneq(reverse, src, dest);
+            }
+
+            if (!is(STORE_CHECK, flags) && !is(INPUTS_DIFFERENT, flags) && !is(INPUTS_SAME, flags)) {
+                normal = asm.createInlineLabel("normal");
+                asm.jneq(normal, src, dest);
+            }
+
+            if (!is(INPUTS_DIFFERENT, flags)) {
+                if (reverse == null) {
+                    reverse = asm.createInlineLabel("reverse");
+                }
+                asm.jlt(reverse, srcPos, destPos);
+            }
+
+            if (!is(STORE_CHECK, flags) && !is(INPUTS_DIFFERENT, flags) && !is(INPUTS_SAME, flags)) {
+                asm.bindInline(normal);
+            }
+
+            // Everything set up => repeat mov.
+            if (wordSize) {
+                asm.repmov(tempSrc, tempDest, lengthOperand);
+            } else {
+                asm.repmovb(tempSrc, tempDest, lengthOperand);
+            }
+
+            if (!is(INPUTS_DIFFERENT, flags) || is(STORE_CHECK, flags)) {
+
+                XirLabel end = asm.createInlineLabel("end");
+                asm.jmp(end);
+
+                // Implement reverse copy, because srcPos < destPos and src == dest.
+                asm.bindInline(reverse);
+
+                if (is(STORE_CHECK, flags)) {
+                    asm.pload(CiKind.Object, compHub, dest, asm.i(config.hubOffset), false);
+                    asm.pload(CiKind.Object, compHub, compHub, asm.i(config.arrayClassElementOffset), false);
+                }
+
+                CiKind copyKind = wordSize ? CiKind.Object : CiKind.Byte;
+                XirOperand tempValue = asm.createTemp("tempValue", copyKind);
+                XirLabel start = asm.createInlineLabel("start");
+                asm.bindInline(start);
+                asm.sub(lengthOperand, lengthOperand, asm.i(1));
+                asm.jlt(end, lengthOperand, asm.i(0));
+
+                Scale scale = wordSize ? Scale.fromInt(target.wordSize) : Scale.Times1;
+                asm.pload(copyKind, tempValue, tempSrc, lengthOperand, 0, scale, false);
+
+                if (is(STORE_CHECK, flags)) {
+                    slowStoreCheck = asm.createOutOfLineLabel("slowStoreCheck");
+                    store = asm.createInlineLabel("store");
+                    asm.jeq(store, tempValue, asm.o(null)); // first check if value is null
+                    asm.pload(CiKind.Object, valueHub, tempValue, asm.i(config.hubOffset), false);
+                    asm.jneq(slowStoreCheck, compHub, valueHub); // then check component hub matches value hub
+                    asm.bindInline(store);
+                }
+
+                asm.pstore(copyKind, tempDest, lengthOperand, tempValue, 0, scale, false);
+
+                asm.jmp(start);
+                asm.bindInline(end);
+            }
+
+            if (kind == CiKind.Object) {
+                // Do write barriers
+                asm.lea(tempDest, dest, destPos, config.getArrayOffset(kind), Scale.fromInt(elementSize));
+                asm.shr(tempDest, tempDest, asm.i(config.cardtableShift));
+                asm.pstore(CiKind.Boolean, wordConst(asm, config.cardtableStartAddress), tempDest, asm.b(false), false);
+
+                XirOperand tempDestEnd = tempSrc; // Reuse src temp
+                asm.lea(tempDestEnd, dest, destPos, config.getArrayOffset(kind), Scale.fromInt(elementSize));
+                asm.add(tempDestEnd, tempDestEnd, length);
+                asm.shr(tempDestEnd, tempDestEnd, asm.i(config.cardtableShift));
+
+                // Jump to out-of-line write barrier loop if the array is big.
+                XirLabel writeBarrierLoop = asm.createOutOfLineLabel("writeBarrierLoop");
+                asm.jneq(writeBarrierLoop, tempDest, tempSrc);
+                XirLabel back = asm.createInlineLabel("back");
+                asm.bindInline(back);
+
+                asm.bindOutOfLine(writeBarrierLoop);
+                asm.pstore(CiKind.Boolean, wordConst(asm, config.cardtableStartAddress), tempDestEnd, asm.b(false), false);
+                asm.sub(tempDestEnd, tempDestEnd, asm.i(1));
+                asm.jneq(writeBarrierLoop, tempDestEnd, tempDest);
+                asm.jmp(back);
+            }
+
+            if (is(STORE_CHECK, flags)) {
+                assert kind == CiKind.Object;
+                useRegisters(asm, AMD64.rax);
+                asm.bindOutOfLine(slowStoreCheck);
+                checkSubtype(asm, temp, valueHub, compHub);
+                asm.jneq(store, temp, wordConst(asm, 0));
+                XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10);
+                asm.mov(scratch, wordConst(asm, 0));
+                asm.callRuntime(CiRuntimeCall.Deoptimize, null);
+                asm.jmp(store);
+            }
+
+            return asm.finishTemplate("arraycopy<" + kind + ">");
+        }
+    };
+
+    private KindTemplates arrayStoreTemplates = new KindTemplates(NULL_CHECK, WRITE_BARRIER, BOUNDS_CHECK, STORE_CHECK, GIVEN_LENGTH) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, CiKind kind) {
+            asm.restart(CiKind.Void);
+            XirParameter array = asm.createInputParameter("array", CiKind.Object);
+            XirParameter index = asm.createInputParameter("index", CiKind.Int, true);
+            XirParameter value = asm.createInputParameter("value", kind, kind != CiKind.Object);
+            XirOperand temp = asm.createTemp("temp", target.wordKind);
+            XirOperand valueHub = null;
+            XirOperand compHub = null;
+            XirLabel store = asm.createInlineLabel("store");
+            XirLabel failBoundsCheck = null;
+            XirLabel slowStoreCheck = null;
+            // if the length is known the array cannot be null
+            boolean implicitNullException = is(NULL_CHECK, flags);
+
+            if (is(BOUNDS_CHECK, flags)) {
+                // load the array length and check the index
+                failBoundsCheck = asm.createOutOfLineLabel("failBoundsCheck");
+                XirOperand length;
+                if (is(GIVEN_LENGTH, flags)) {
+                    length = asm.createInputParameter("length", CiKind.Int);
+                } else {
+                    length = asm.createTemp("length", CiKind.Int);
+                    if (implicitNullException) {
+                        asm.mark(MARK_IMPLICIT_NULL);
+                    }
+                    asm.pload(CiKind.Int, length, array, asm.i(config.arrayLengthOffset), implicitNullException);
+                    implicitNullException = false;
+                }
+                asm.jugteq(failBoundsCheck, index, length);
+
+            }
+            if (is(STORE_CHECK, flags) && kind == CiKind.Object) {
+                slowStoreCheck = asm.createOutOfLineLabel("slowStoreCheck");
+                asm.jeq(store, value, asm.o(null)); // first check if value is null
+                valueHub = asm.createTemp("valueHub", CiKind.Object);
+                compHub = asm.createTemp("compHub", CiKind.Object);
+                if (implicitNullException) {
+                    asm.mark(MARK_IMPLICIT_NULL);
+                }
+                asm.pload(CiKind.Object, compHub, array, asm.i(config.hubOffset), implicitNullException);
+                asm.pload(CiKind.Object, compHub, compHub, asm.i(config.arrayClassElementOffset), false);
+                asm.pload(CiKind.Object, valueHub, value, asm.i(config.hubOffset), false);
+                asm.jneq(slowStoreCheck, compHub, valueHub); // then check component hub matches value hub
+
+                implicitNullException = false;
+            }
+            asm.bindInline(store);
+            int elemSize = target.sizeInBytes(kind);
+
+            if (implicitNullException) {
+                asm.mark(MARK_IMPLICIT_NULL);
+            }
+            int disp = config.getArrayOffset(kind);
+            Scale scale = Scale.fromInt(elemSize);
+            if (kind == CiKind.Object) {
+                verifyPointer(asm, value);
+            }
+            if (is(WRITE_BARRIER, flags) && kind == CiKind.Object) {
+                asm.lea(temp, array, index, disp, scale);
+                asm.pstore(kind, temp, value, implicitNullException);
+                writeBarrier(asm, temp);
+            } else {
+                asm.pstore(kind, array, index, value, disp, scale, implicitNullException);
+            }
+
+            // -- out of line -------------------------------------------------------
+            if (is(BOUNDS_CHECK, flags)) {
+                asm.bindOutOfLine(failBoundsCheck);
+                XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10);
+                asm.mov(scratch, wordConst(asm, 0));
+                asm.callRuntime(CiRuntimeCall.Deoptimize, null);
+                asm.shouldNotReachHere();
+            }
+            if (is(STORE_CHECK, flags) && kind == CiKind.Object) {
+                useRegisters(asm, AMD64.rax);
+                asm.bindOutOfLine(slowStoreCheck);
+                checkSubtype(asm, temp, valueHub, compHub);
+                asm.jneq(store, temp, wordConst(asm, 0));
+                XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10);
+                asm.mov(scratch, wordConst(asm, 0));
+                asm.callRuntime(CiRuntimeCall.Deoptimize, null);
+                asm.shouldNotReachHere();
+            }
+            return asm.finishTemplate("arraystore<" + kind + ">");
+        }
+    };
+
+    private SimpleTemplates arrayLengthTemplates = new SimpleTemplates(NULL_CHECK) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            XirOperand result = asm.restart(CiKind.Int);
+            XirParameter object = asm.createInputParameter("object", CiKind.Object);
+            if (is(NULL_CHECK, flags)) {
+                asm.mark(MARK_IMPLICIT_NULL);
+            }
+            verifyPointer(asm, object);
+            asm.pload(CiKind.Int, result, object, asm.i(config.arrayLengthOffset), true);
+            return asm.finishTemplate("arrayLength");
+        }
+    };
+
+    private SimpleTemplates typeCheckTemplates = new SimpleTemplates(NULL_CHECK) {
+       @Override
+       protected XirTemplate create(CiXirAssembler asm, long flags) {
+           asm.restart(CiKind.Void);
+           XirParameter objHub = asm.createInputParameter("objectHub", CiKind.Object);
+           XirOperand hub = asm.createConstantInputParameter("hub", CiKind.Object);
+           XirLabel falseSucc = asm.createInlineLabel(XirLabel.FalseSuccessor);
+
+           XirOperand checkHub = asm.createTemp("checkHub", CiKind.Object);
+
+           if (is(NULL_CHECK, flags)) {
+               asm.mark(MARK_IMPLICIT_NULL);
+           }
+
+           asm.mov(checkHub, hub);
+           // if we get an exact match: continue.
+           asm.jneq(falseSucc, objHub, checkHub);
+
+           return asm.finishTemplate("typeCheck");
+       }
+    };
+
+    @Override
+    public XirSnippet genPrologue(XirSite site, RiResolvedMethod method) {
+        boolean staticMethod = Modifier.isStatic(method.accessFlags());
+        return new XirSnippet(staticMethod ? prologueTemplates.get(site, STATIC_METHOD) : prologueTemplates.get(site));
+    }
+
+    @Override
+    public XirSnippet genEpilogue(XirSite site, RiResolvedMethod method) {
+        return new XirSnippet(epilogueTemplates.get(site));
+    }
+
+    @Override
+    public XirSnippet genSafepointPoll(XirSite site) {
+        return new XirSnippet(safepointTemplates.get(site));
+    }
+
+    @Override
+    public XirSnippet genExceptionObject(XirSite site) {
+        return new XirSnippet(exceptionObjectTemplates.get(site));
+    }
+
+    @Override
+    public XirSnippet genResolveClass(XirSite site, RiType type, Representation rep) {
+        throw new CiBailout("Xir ResolveClass not available");
+    }
+
+    @Override
+    public XirSnippet genIntrinsic(XirSite site, XirArgument[] arguments, RiMethod method) {
+        return null;
+    }
+
+    @Override
+    public XirSnippet genInvokeInterface(XirSite site, XirArgument receiver, RiMethod method) {
+        return new XirSnippet(invokeInterfaceTemplates.get(site), receiver, wordArg(0));
+    }
+
+    @Override
+    public XirSnippet genInvokeVirtual(XirSite site, XirArgument receiver, RiMethod method) {
+        return new XirSnippet(invokeVirtualTemplates.get(site), receiver, wordArg(0));
+    }
+
+    @Override
+    public XirSnippet genInvokeSpecial(XirSite site, XirArgument receiver, RiMethod method) {
+        return new XirSnippet(invokeSpecialTemplates.get(site), receiver, wordArg(0));
+    }
+
+    @Override
+    public XirSnippet genInvokeStatic(XirSite site, RiMethod method) {
+        return new XirSnippet(invokeStaticTemplates.get(site), wordArg(0));
+    }
+
+    @Override
+    public XirSnippet genMonitorEnter(XirSite site, XirArgument receiver, XirArgument lockAddress) {
+        return new XirSnippet(monitorEnterTemplates.get(site), receiver, lockAddress);
+    }
+
+    @Override
+    public XirSnippet genMonitorExit(XirSite site, XirArgument receiver, XirArgument lockAddress) {
+        return new XirSnippet(monitorExitTemplates.get(site), receiver, lockAddress);
+    }
+
+    @Override
+    public XirSnippet genGetField(XirSite site, XirArgument object, RiField field) {
+        return new XirSnippet(getFieldTemplates.get(site, field.kind(false)), object, XirArgument.forInt(((HotSpotField) field).offset()));
+    }
+
+    @Override
+    public XirSnippet genWriteBarrier(XirArgument object) {
+        return new XirSnippet(writeBarrierTemplate.get(null, CiKind.Void), object);
+    }
+
+    @Override
+    public XirSnippet genPutField(XirSite site, XirArgument object, RiField field, XirArgument value) {
+        return new XirSnippet(putFieldTemplates.get(site, field.kind(false)), object, value, XirArgument.forInt(((HotSpotField) field).offset()));
+    }
+
+    @Override
+    public XirSnippet genGetStatic(XirSite site, XirArgument object, RiField field) {
+        return new XirSnippet(getFieldTemplates.get(site, field.kind(false)), object, XirArgument.forInt(((HotSpotField) field).offset()));
+    }
+
+    @Override
+    public XirSnippet genPutStatic(XirSite site, XirArgument object, RiField field, XirArgument value) {
+        return new XirSnippet(putFieldTemplates.get(site, field.kind(false)), object, value, XirArgument.forInt(((HotSpotField) field).offset()));
+    }
+
+    @Override
+    public XirSnippet genNewInstance(XirSite site, RiType type) {
+        int instanceSize = ((HotSpotTypeResolved) type).instanceSize();
+        return new XirSnippet(newInstanceTemplates.get(site, instanceSize), XirArgument.forObject(type));
+    }
+
+    @Override
+    public XirSnippet genNewArray(XirSite site, XirArgument length, CiKind elementKind, RiType componentType, RiType arrayType) {
+        if (elementKind == CiKind.Object) {
+            assert arrayType instanceof RiResolvedType;
+            return new XirSnippet(newObjectArrayTemplates.get(site), length, XirArgument.forObject(arrayType));
+        } else {
+            assert arrayType == null;
+            RiType primitiveArrayType = compiler.getVMEntries().getPrimitiveArrayType(elementKind);
+            return new XirSnippet(newTypeArrayTemplates.get(site, elementKind), length, XirArgument.forObject(primitiveArrayType));
+        }
+    }
+
+    @Override
+    public XirSnippet genNewObjectArrayClone(XirSite site, XirArgument newLength, XirArgument referenceArray) {
+        return new XirSnippet(newObjectArrayCloneTemplates.get(site), newLength, referenceArray);
+    }
+
+    @Override
+    public XirSnippet genNewMultiArray(XirSite site, XirArgument[] lengths, RiType type) {
+        XirArgument[] params = Arrays.copyOf(lengths, lengths.length + 1);
+        params[lengths.length] = XirArgument.forObject(type);
+        return new XirSnippet(multiNewArrayTemplate.get(site, lengths.length), params);
+    }
+
+    @Override
+    public XirSnippet genCheckCast(XirSite site, XirArgument receiver, XirArgument hub, RiType type, RiResolvedType[] hints, boolean hintsExact) {
+        if (hints == null || hints.length == 0) {
+            return new XirSnippet(checkCastTemplates.get(site, 0), receiver, hub);
+        } else {
+            XirArgument[] params = new XirArgument[hints.length + (hintsExact ? 1 : 2)];
+            int i = 0;
+            params[i++] = receiver;
+            if (!hintsExact) {
+                params[i++] = hub;
+            }
+            for (RiResolvedType hint : hints) {
+                params[i++] = XirArgument.forObject(hint);
+            }
+            XirTemplate template = hintsExact ? checkCastTemplates.get(site, hints.length, EXACT_HINTS) : checkCastTemplates.get(site, hints.length);
+            return new XirSnippet(template, params);
+        }
+    }
+
+    @Override
+    public XirSnippet genInstanceOf(XirSite site, XirArgument object, XirArgument hub, RiType type, RiResolvedType[] hints, boolean hintsExact) {
+        if (hints == null || hints.length == 0) {
+            return new XirSnippet(instanceOfTemplates.get(site, 0), object, hub);
+        } else {
+            XirArgument[] params = new XirArgument[hints.length + (hintsExact ? 1 : 2)];
+            int i = 0;
+            params[i++] = object;
+            if (!hintsExact) {
+                params[i++] = hub;
+            }
+            for (RiResolvedType hint : hints) {
+                params[i++] = XirArgument.forObject(hint);
+            }
+            XirTemplate template = hintsExact ? instanceOfTemplates.get(site, hints.length, EXACT_HINTS) : instanceOfTemplates.get(site, hints.length);
+            return new XirSnippet(template, params);
+        }
+    }
+
+    @Override
+    public XirSnippet genMaterializeInstanceOf(XirSite site, XirArgument object, XirArgument hub, XirArgument trueValue, XirArgument falseValue, RiType type, RiResolvedType[] hints, boolean hintsExact) {
+        if (hints == null || hints.length == 0) {
+            return new XirSnippet(materializeInstanceOfTemplates.get(site, 0), object, hub, trueValue, falseValue);
+        } else {
+            XirArgument[] params = new XirArgument[hints.length + (hintsExact ? 3 : 4)];
+            int i = 0;
+            params[i++] = object;
+            if (!hintsExact) {
+                params[i++] = hub;
+            }
+            params[i++] = trueValue;
+            params[i++] = falseValue;
+            for (RiResolvedType hint : hints) {
+                params[i++] = XirArgument.forObject(hint);
+            }
+            XirTemplate template = hintsExact ? materializeInstanceOfTemplates.get(site, hints.length, EXACT_HINTS) : materializeInstanceOfTemplates.get(site, hints.length);
+            return new XirSnippet(template, params);
+        }
+    }
+
+    @Override
+    public XirSnippet genArrayLoad(XirSite site, XirArgument array, XirArgument index, CiKind elementKind, RiType elementType) {
+        return new XirSnippet(arrayLoadTemplates.get(site, elementKind), array, index);
+    }
+
+    @Override
+    public XirSnippet genArrayStore(XirSite site, XirArgument array, XirArgument index, XirArgument value, CiKind elementKind, RiType elementType) {
+        return new XirSnippet(arrayStoreTemplates.get(site, elementKind), array, index, value);
+    }
+
+    @Override
+    public XirSnippet genArrayCopy(XirSite site, XirArgument src, XirArgument srcPos, XirArgument dest, XirArgument destPos, XirArgument length, RiType elementType, boolean inputsSame, boolean inputsDifferent) {
+        if (elementType == null) {
+            return null;
+        }
+        assert !inputsDifferent || !inputsSame;
+        XirTemplate template = null;
+        if (inputsDifferent) {
+            template = arrayCopyTemplates.get(site, elementType.kind(true), INPUTS_DIFFERENT);
+        } else if (inputsSame) {
+            template = arrayCopyTemplates.get(site, elementType.kind(true), INPUTS_SAME);
+        } else {
+            template = arrayCopyTemplates.get(site, elementType.kind(true));
+        }
+        return new XirSnippet(template, src, srcPos, dest, destPos, length);
+    }
+
+    @Override
+    public XirSnippet genArrayLength(XirSite site, XirArgument array) {
+        return new XirSnippet(arrayLengthTemplates.get(site), array);
+    }
+
+    @Override
+    public XirSnippet genTypeBranch(XirSite site, XirArgument thisHub, XirArgument otherHub, RiType type) {
+        assert type instanceof RiResolvedType;
+        return new XirSnippet(typeCheckTemplates.get(site), thisHub, otherHub);
+    }
+
+    @Override
+    public void initialize(CiXirAssembler asm) {
+        this.globalAsm = asm;
+    }
+
+    private void verifyPointer(CiXirAssembler asm, XirOperand pointer) {
+        if (config.verifyPointers) {
+            // The verify pointer stub wants the argument in a fixed register.
+            XirOperand fixed = asm.createRegisterTemp("fixed", CiKind.Object, AMD64.r13);
+            asm.push(fixed);
+            asm.mov(fixed, pointer);
+            asm.callRuntime(config.verifyPointerStub, null);
+            asm.pop(fixed);
+        }
+    }
+
+    private void checkSubtype(CiXirAssembler asm, XirOperand result, XirOperand objHub, XirOperand hub) {
+        asm.push(objHub);
+        asm.push(hub);
+        asm.callRuntime(config.instanceofStub, null);
+        asm.pop(result);
+        asm.pop(result);
+    }
+
+    private static void useRegisters(CiXirAssembler asm, CiRegister... registers) {
+        if (registers != null) {
+            for (CiRegister register : registers) {
+                asm.createRegisterTemp("reg", CiKind.Illegal, register);
+            }
+        }
+    }
+
+    private void writeBarrier(CiXirAssembler asm, XirOperand base) {
+        asm.shr(base, base, asm.i(config.cardtableShift));
+        asm.pstore(CiKind.Boolean, wordConst(asm, config.cardtableStartAddress), base, asm.b(false), false);
+    }
+
+    public boolean is(TemplateFlag check, long flags) {
+        return (flags & check.bits()) == check.bits();
+    }
+
+    /**
+     * Base class for all the ondemand template generators. It is not normally subclassed directly, but through one of
+     * its subclasses (SimpleTemplates, KindTemplates, IndexTemplates).
+     */
+    private abstract class Templates {
+
+        private ConcurrentHashMap<Long, XirTemplate> templates = new ConcurrentHashMap<>();
+        private final long mask;
+
+        /**
+         * Each flag passed to this method will cause templates with and without it to be generated.
+         */
+        public Templates(TemplateFlag... flags) {
+            this.mask = getBits((int) INDEX_MASK, null, flags);
+        }
+
+        protected abstract XirTemplate create(CiXirAssembler asm, long flags);
+
+        protected long getBits(int index, XirSite site, TemplateFlag... flags) {
+            long bits = index;
+            if (site != null) {
+                bits |= site.requiresNullCheck() ? NULL_CHECK.bits() : 0;
+                bits |= site.requiresReadBarrier() ? READ_BARRIER.bits() : 0;
+                bits |= site.requiresWriteBarrier() ? WRITE_BARRIER.bits() : 0;
+                bits |= site.requiresArrayStoreCheck() ? STORE_CHECK.bits() : 0;
+                bits |= site.requiresBoundsCheck() ? BOUNDS_CHECK.bits() : 0;
+            }
+            if (flags != null) {
+                for (TemplateFlag flag : flags) {
+                    bits |= flag.bits();
+                }
+            }
+            return bits;
+        }
+
+        protected XirTemplate getInternal(long flags) {
+            long maskedFlags = flags & mask;
+            XirTemplate template = templates.get(maskedFlags);
+            if (template == null) {
+                template = create(HotSpotXirGenerator.this.globalAsm.copy(), maskedFlags);
+                templates.put(maskedFlags, template);
+            }
+            return template;
+        }
+    }
+
+    private abstract class SimpleTemplates extends Templates {
+
+        public SimpleTemplates(TemplateFlag... flags) {
+            super(flags);
+        }
+
+        public XirTemplate get(XirSite site, TemplateFlag... flags) {
+            return getInternal(getBits(0, site, flags));
+        }
+    }
+
+    private abstract class IndexTemplates extends Templates {
+
+        public IndexTemplates(TemplateFlag... flags) {
+            super(flags);
+        }
+
+        @Override
+        protected final XirTemplate create(CiXirAssembler asm, long flags) {
+            return create(asm, flags & FLAGS_MASK, (int) (flags & INDEX_MASK));
+        }
+
+        protected abstract XirTemplate create(CiXirAssembler asm, long flags, int index);
+
+        public XirTemplate get(XirSite site, int size, TemplateFlag... flags) {
+            return getInternal(getBits(size, site, flags));
+        }
+    }
+
+    private abstract class KindTemplates extends Templates {
+
+        public KindTemplates(TemplateFlag... flags) {
+            super(flags);
+        }
+
+        @Override
+        protected final XirTemplate create(CiXirAssembler asm, long flags) {
+            return create(asm, flags & FLAGS_MASK, CiKind.VALUES[(int) (flags & INDEX_MASK)]);
+        }
+
+        protected abstract XirTemplate create(CiXirAssembler asm, long flags, CiKind kind);
+
+        public XirTemplate get(XirSite site, CiKind kind, TemplateFlag... flags) {
+            return getInternal(getBits(kind.ordinal(), site, flags));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/TemplateFlag.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,36 @@
+/*
+ * 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.max.graal.hotspot.ri;
+
+enum TemplateFlag {
+    NULL_CHECK, READ_BARRIER, WRITE_BARRIER, STORE_CHECK, BOUNDS_CHECK, GIVEN_LENGTH, INPUTS_DIFFERENT, INPUTS_SAME, STATIC_METHOD, SYNCHRONIZED, EXACT_HINTS;
+
+    private static final long FIRST_FLAG = 0x0000000100000000L;
+    public static final long FLAGS_MASK = 0x0000FFFF00000000L;
+    public static final long INDEX_MASK = 0x00000000FFFFFFFFL;
+
+    public long bits() {
+        assert ((FIRST_FLAG << ordinal()) & FLAGS_MASK) != 0;
+        return FIRST_FLAG << ordinal();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/server/CompilationServer.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,122 @@
+/*
+ * 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.max.graal.hotspot.server;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import javax.net.*;
+
+import com.oracle.max.graal.hotspot.*;
+import com.oracle.max.graal.hotspot.Compiler;
+import com.oracle.max.graal.hotspot.bridge.*;
+import com.oracle.max.graal.hotspot.logging.*;
+
+/**
+ * Server side of the client/server compilation model. The server listens for connections on the hardcoded port 1199.
+ */
+public class CompilationServer implements Runnable {
+
+    public static void main(String[] args) throws Exception {
+        new CompilationServer(false).run();
+    }
+
+    public interface ConnectionObserver {
+
+        void connectionStarted(Compiler compiler);
+
+        void connectionFinished(Compiler compiler);
+    }
+
+    private final boolean multiple;
+    private final ArrayList<ConnectionObserver> observers = new ArrayList<>();
+
+    /**
+     * Creates a new Compilation server. The server is activated by calling {@link #run()} directly or via a new
+     * {@link Thread}.
+     *
+     * @param multiple true if the server should server should serve an infinite amount of consecutive connections,
+     *            false if it should terminate after the first connection ends.
+     */
+    public CompilationServer(boolean multiple) {
+        this.multiple = multiple;
+        HotSpotOptions.setDefaultOptions();
+    }
+
+    public void addConnectionObserver(ConnectionObserver observer) {
+        observers.add(observer);
+    }
+
+    public void removeConnectionObserver(ConnectionObserver observer) {
+        observers.remove(observer);
+    }
+
+    public void run() {
+        final ServerSocket serverSocket;
+        try {
+            serverSocket = ServerSocketFactory.getDefault().createServerSocket(1199);
+        } catch (IOException e) {
+            throw new RuntimeException("Couldn't create compilation server", e);
+        }
+        do {
+            Socket socket = null;
+            try {
+                Logger.log("Compilation server ready, waiting for client to connect...");
+                socket = serverSocket.accept();
+                Logger.log("Connected to " + socket.getRemoteSocketAddress());
+
+                ReplacingStreams streams = new ReplacingStreams(socket.getOutputStream(), socket.getInputStream());
+
+                // get the VMEntries proxy from the client
+                CompilerToVM entries = (CompilerToVM) streams.getInvocation().waitForResult(false);
+
+                // return the initialized compiler to the client
+                Compiler compiler = CompilerImpl.initializeServer(entries);
+                compiler.getCompiler();
+                streams.getInvocation().sendResult(compiler);
+
+                for (ConnectionObserver observer : observers) {
+                    observer.connectionStarted(compiler);
+                }
+
+                streams.getInvocation().waitForResult(true);
+
+                for (ConnectionObserver observer : observers) {
+                    observer.connectionFinished(compiler);
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            } catch (ClassNotFoundException e) {
+                throw new RuntimeException(e);
+            } finally {
+                if (socket != null) {
+                    try {
+                        socket.close();
+                    } catch (IOException e) {
+                    }
+                }
+            }
+        } while (multiple);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/server/InvocationSocket.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,282 @@
+/*
+ * 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.max.graal.hotspot.server;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.max.graal.hotspot.logging.*;
+
+/**
+ * A collection of java.lang.reflect proxies that communicate over a socket connection.
+ *
+ * Calling a method sends the method name and the parameters through the socket. Afterwards this class waits for a
+ * result. While waiting for a result three types of objects can arrive through the socket: a method invocation, a
+ * method result or an exception. Method invocation can thus be recursive.
+ */
+public class InvocationSocket {
+
+    private static final boolean DEBUG = false;
+    private static final boolean COUNT_CALLS = false;
+
+    private static final HashSet<String> cachedMethodNames = new HashSet<>();
+    private static final HashSet<String> forbiddenMethodNames = new HashSet<>();
+
+    static {
+        cachedMethodNames.add("name");
+        cachedMethodNames.add("kind");
+        cachedMethodNames.add("isResolved");
+        cachedMethodNames.add("getVMEntries");
+        cachedMethodNames.add("exactType");
+        cachedMethodNames.add("isInitialized");
+        forbiddenMethodNames.add("javaClass");
+    }
+
+    private final ObjectOutputStream output;
+    private final ObjectInputStream input;
+
+    private final Map<String, Integer> counts = new HashMap<>();
+
+    public InvocationSocket(ObjectOutputStream output, ObjectInputStream input) {
+        this.output = output;
+        this.input = input;
+
+        if (COUNT_CALLS) {
+            Runtime.getRuntime().addShutdownHook(new Thread() {
+                @Override
+                public void run() {
+                    SortedMap<Integer, String> sorted = new TreeMap<>();
+                    for (Map.Entry<String, Integer> entry : counts.entrySet()) {
+                        sorted.put(entry.getValue(), entry.getKey());
+                    }
+                    for (Map.Entry<Integer, String> entry : sorted.entrySet()) {
+                        System.out.println(entry.getKey() + ": " + entry.getValue());
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * Represents one invocation of a method that is transferred via the socket connection.
+     *
+     */
+    private static class Invocation implements Serializable {
+
+        /**
+         * 
+         */
+        private static final long serialVersionUID = -799162779226626066L;
+        public Object receiver;
+        public String methodName;
+        public Object[] args;
+
+        public Invocation(Object receiver, String methodName, Object[] args) {
+            this.receiver = receiver;
+            this.methodName = methodName;
+            this.args = args;
+        }
+    }
+
+    /**
+     * Represents the result of an invocation that is transferred via the socket connection.
+     *
+     */
+    private static class Result implements Serializable {
+
+        /**
+         * 
+         */
+        private static final long serialVersionUID = -7496058356272415814L;
+        public Object result;
+
+        public Result(Object result) {
+            this.result = result;
+        }
+    }
+
+    private void incCount(String name, Object[] args) {
+        if (COUNT_CALLS) {
+            String nameAndArgCount = name + (args == null ? 0 : args.length);
+            if (counts.get(nameAndArgCount) != null) {
+                counts.put(nameAndArgCount, counts.get(nameAndArgCount) + 1);
+            } else {
+                counts.put(nameAndArgCount, 1);
+            }
+        }
+    }
+
+    /**
+     * Each instance of this class handles remote invocations for one instance of a Remote class. It will forward all
+     * interface methods to the other end of the socket and cache the results of calls to certain methods.
+     *
+     */
+    public class Handler implements InvocationHandler {
+
+        private final Object receiver;
+        private final HashMap<String, Object> cache = new HashMap<>();
+
+        public Handler(Object receiver) {
+            this.receiver = receiver;
+        }
+
+        @Override
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+            // only interface methods can be transferred, java.lang.Object methods
+            if (method.getDeclaringClass() == Object.class) {
+                return method.invoke(receiver, args);
+            }
+            String methodName = method.getName();
+            // check if the result of this zero-arg method was cached
+            if (args == null || args.length == 0) {
+                if (cache.containsKey(methodName)) {
+                    return cache.get(methodName);
+                }
+            }
+            if (forbiddenMethodNames.contains(methodName)) {
+                throw new IllegalAccessException(methodName + " not allowed");
+            }
+            Object result = null;
+            try {
+                if (DEBUG) {
+                    Logger.startScope("invoking remote " + methodName);
+                }
+                incCount(methodName, args);
+
+                output.writeObject(new Invocation(receiver, methodName, args));
+                output.flush();
+                result = waitForResult(false);
+
+                // result caching for selected methods
+                if ((args == null || args.length == 0) && cachedMethodNames.contains(methodName)) {
+                    cache.put(methodName, result);
+                }
+                return result;
+            } catch (Throwable t) {
+                t.printStackTrace();
+                throw t;
+            } finally {
+                if (DEBUG) {
+                    Logger.endScope(" = " + result);
+                }
+            }
+        }
+    }
+
+    /**
+     * Waits for the result of a remote method invocation. Invocations that should be executed in this VM might arrive
+     * while waiting for the result, and these invocations will be executed before again waiting fort he result.
+     */
+    @SuppressWarnings("unused")
+    public Object waitForResult(boolean eofExpected) throws IOException, ClassNotFoundException {
+        while (true) {
+            Object in;
+            try {
+                in = input.readObject();
+            } catch (EOFException e) {
+                if (eofExpected) {
+                    return null;
+                }
+                throw e;
+            }
+            if (in instanceof Result) {
+                return ((Result) in).result;
+            } else if (in instanceof RuntimeException) {
+                throw (RuntimeException) in;
+            } else if (in instanceof Throwable) {
+                throw new RuntimeException((Throwable) in);
+            }
+
+            Invocation invoke = (Invocation) in;
+            Method method = null;
+            for (Class<?> clazz = invoke.receiver.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
+                for (Method m : clazz.getDeclaredMethods()) {
+                    if (invoke.methodName.equals(m.getName())) {
+                        method = m;
+                        break;
+                    }
+                }
+            }
+            if (method == null) {
+                Exception e = new UnsupportedOperationException("unknown method " + invoke.methodName);
+                e.printStackTrace();
+                output.writeObject(e);
+                output.flush();
+            } else {
+                Object result = null;
+                try {
+                    if (invoke.args == null) {
+                        if (DEBUG) {
+                            Logger.startScope("invoking local " + invoke.methodName);
+                        }
+                        result = method.invoke(invoke.receiver);
+                    } else {
+                        if (Logger.ENABLED && DEBUG) {
+                            StringBuilder str = new StringBuilder();
+                            str.append("invoking local " + invoke.methodName + "(");
+                            for (int i = 0; i < invoke.args.length; i++) {
+                                str.append(i == 0 ? "" : ", ");
+                                str.append(Logger.pretty(invoke.args[i]));
+                            }
+                            str.append(")");
+                            Logger.startScope(str.toString());
+                        }
+                        result = method.invoke(invoke.receiver, invoke.args);
+                    }
+                    result = new Result(result);
+                } catch (IllegalArgumentException e) {
+                    System.out.println("error while invoking " + invoke.methodName);
+                    e.getCause().printStackTrace();
+                    result = e.getCause();
+                } catch (InvocationTargetException e) {
+                    System.out.println("error while invoking " + invoke.methodName);
+                    e.getCause().printStackTrace();
+                    result = e.getCause();
+                } catch (IllegalAccessException e) {
+                    System.out.println("error while invoking " + invoke.methodName);
+                    e.getCause().printStackTrace();
+                    result = e.getCause();
+                } finally {
+                    if (DEBUG) {
+                        if (result instanceof Result) {
+                            Logger.endScope(" = " + ((Result) result).result);
+                        } else {
+                            Logger.endScope(" = " + result);
+                        }
+                    }
+                }
+                output.writeObject(result);
+                output.flush();
+            }
+        }
+    }
+
+    /**
+     * Sends a result without invoking a method, used by CompilationServer startup code.
+     */
+    public void sendResult(Object obj) throws IOException {
+        output.writeObject(new Result(obj));
+        output.flush();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/server/Remote.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,28 @@
+/*
+ * 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.max.graal.hotspot.server;
+
+
+public interface Remote {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/server/ReplacingStreams.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,234 @@
+/*
+ * 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.max.graal.hotspot.server;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.hotspot.*;
+
+public class ReplacingStreams {
+
+    private IdentityHashMap<Object, Placeholder> objectMap = new IdentityHashMap<>();
+    private ArrayList<Object> objectList = new ArrayList<>();
+
+    private ReplacingOutputStream output;
+    private ReplacingInputStream input;
+
+    private InvocationSocket invocation;
+
+    public ReplacingStreams(OutputStream outputStream, InputStream inputStream) throws IOException {
+        output = new ReplacingOutputStream(new BufferedOutputStream(outputStream));
+        // required, because creating an ObjectOutputStream writes a header, but doesn't flush the stream
+        output.flush();
+        input = new ReplacingInputStream(new BufferedInputStream(inputStream));
+        invocation = new InvocationSocket(output, input);
+
+        addStaticObject(CiValue.IllegalValue);
+        addStaticObject(HotSpotProxy.DUMMY_CONSTANT_OBJ);
+    }
+
+    public void setInvocationSocket(InvocationSocket invocation) {
+        this.invocation = invocation;
+    }
+
+    public ReplacingOutputStream getOutput() {
+        return output;
+    }
+
+    public ReplacingInputStream getInput() {
+        return input;
+    }
+
+    public InvocationSocket getInvocation() {
+        return invocation;
+    }
+
+    private void addStaticObject(Object obj) {
+        int id = objectList.size();
+        objectList.add(obj);
+        objectMap.put(obj, new Placeholder(id));
+    }
+
+    public static class Placeholder implements Serializable {
+
+        /**
+         *
+         */
+        private static final long serialVersionUID = 6071894297788156945L;
+        public final int id;
+
+        public Placeholder(int id) {
+            this.id = id;
+        }
+
+        @Override
+        public String toString() {
+            return "#<" + id + ">";
+        }
+    }
+
+    public static class NewRemoteCallPlaceholder implements Serializable {
+
+        /**
+         *
+         */
+        private static final long serialVersionUID = 3084101671389500206L;
+        public final Class<?>[] interfaces;
+
+        public NewRemoteCallPlaceholder(Class<?>[] interfaces) {
+            this.interfaces = interfaces;
+        }
+    }
+
+    public static class NewDummyPlaceholder implements Serializable {
+
+        /**
+         *
+         */
+        private static final long serialVersionUID = 2692666726573532288L;
+    }
+
+    /**
+     * Replaces certain cir objects that cannot easily be made Serializable.
+     */
+    public class ReplacingInputStream extends ObjectInputStream {
+
+        public ReplacingInputStream(InputStream in) throws IOException {
+            super(in);
+            enableResolveObject(true);
+        }
+
+        @Override
+        protected Object resolveObject(Object obj) throws IOException {
+            // see ReplacingInputStream.replaceObject for details on when these types of objects are created
+
+            if (obj instanceof Placeholder) {
+                Placeholder placeholder = (Placeholder) obj;
+                Object resolvedObj = objectList.get(placeholder.id);
+                return resolvedObj;
+            }
+
+            if (obj instanceof NewRemoteCallPlaceholder) {
+                NewRemoteCallPlaceholder newPlaceholder = (NewRemoteCallPlaceholder) obj;
+                Placeholder placeholder = new Placeholder(objectList.size());
+                Object resolvedObj = Proxy.newProxyInstance(getClass().getClassLoader(), newPlaceholder.interfaces, invocation.new Handler(placeholder));
+                objectMap.put(resolvedObj, placeholder);
+                objectList.add(resolvedObj);
+                return resolvedObj;
+            }
+
+            if (obj instanceof NewDummyPlaceholder) {
+                Object resolvedObj = new Placeholder(objectList.size());
+                objectMap.put(resolvedObj, (Placeholder) resolvedObj);
+                objectList.add(resolvedObj);
+                return resolvedObj;
+            }
+
+            return obj;
+        }
+    }
+
+    /**
+     * Replaces certain cir objects that cannot easily be made Serializable.
+     */
+    public class ReplacingOutputStream extends ObjectOutputStream {
+
+        public ReplacingOutputStream(OutputStream out) throws IOException {
+            super(out);
+            enableReplaceObject(true);
+        }
+
+        @Override
+        protected Object replaceObject(Object obj) throws IOException {
+            // is the object a known instance?
+            Placeholder placeholder = objectMap.get(obj);
+            if (placeholder != null) {
+                return placeholder;
+            }
+
+            // is the object an instance of a class that will always be executed remotely?
+            if (obj instanceof Remote) {
+                return createRemoteCallPlaceholder(obj);
+            }
+
+            // is the object a constant of object type?
+            if (obj.getClass() == CiConstant.class) {
+                CiConstant constant = (CiConstant) obj;
+                if (constant.kind != CiKind.Object) {
+                    return obj;
+                }
+                Object contents = constant.asObject();
+                if (contents == null) {
+                    return obj;
+                }
+                // don't replace if the object already is a placeholder
+                if (contents instanceof Placeholder || contents instanceof Long) {
+                    return obj;
+                }
+                placeholder = objectMap.get(contents);
+                if (placeholder != null) {
+                    return CiConstant.forObject(placeholder);
+                }
+                if (contents instanceof Remote) {
+                    return CiConstant.forObject(createRemoteCallPlaceholder(contents));
+                }
+                return CiConstant.forObject(createDummyPlaceholder(contents));
+            }
+            return obj;
+        }
+    }
+
+    public static Class<?>[] getAllInterfaces(Class<?> clazz) {
+        HashSet<Class< ? >> interfaces = new HashSet<>();
+        getAllInterfaces(clazz, interfaces);
+        return interfaces.toArray(new Class<?>[interfaces.size()]);
+    }
+
+    private static void getAllInterfaces(Class<?> clazz, HashSet<Class<?>> interfaces) {
+        for (Class< ? > iface : clazz.getInterfaces()) {
+            if (!interfaces.contains(iface)) {
+                interfaces.add(iface);
+                getAllInterfaces(iface, interfaces);
+            }
+        }
+        if (clazz.getSuperclass() != null) {
+            getAllInterfaces(clazz.getSuperclass(), interfaces);
+        }
+    }
+
+    private Object createRemoteCallPlaceholder(Object obj) {
+        // collect all interfaces that this object's class implements (proxies only support interfaces)
+        objectMap.put(obj, new Placeholder(objectList.size()));
+        objectList.add(obj);
+        return new NewRemoteCallPlaceholder(getAllInterfaces(obj.getClass()));
+    }
+
+    public Object createDummyPlaceholder(Object obj) {
+        objectMap.put(obj, new Placeholder(objectList.size()));
+        objectList.add(obj);
+        return new NewDummyPlaceholder();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/server/package-info.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/**
+ * Implementation of a compilation server socket that delegates incoming requests to Graal.
+ */
+package com.oracle.max.graal.hotspot.server;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/snippets/ArrayCopySnippets.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,458 @@
+/*
+ * 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.max.graal.hotspot.snippets;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.hotspot.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+import com.oracle.max.graal.snippets.*;
+import com.oracle.max.graal.snippets.nodes.*;
+
+
+public class ArrayCopySnippets implements SnippetsInterface{
+
+    @Snippet
+    public static void arraycopy(byte[] src, int srcPos, byte[] dest, int destPos, int length) {
+        if (src == null || dest == null) {
+            throw new NullPointerException();
+        }
+        if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (src == dest && srcPos < destPos) { // bad aliased case
+            if ((length & 0x01) == 0) {
+                if ((length & 0x02) == 0) {
+                    if ((length & 0x04) == 0) {
+                        copyLongsDown(src, srcPos, dest, destPos, length >> 3);
+                    } else {
+                        copyIntsDown(src, srcPos, dest, destPos, length >> 2);
+                    }
+                } else {
+                    copyShortsDown(src, srcPos, dest, destPos, length >> 1);
+                }
+            } else {
+                copyBytesDown(src, srcPos, dest, destPos, length);
+            }
+        } else {
+            if ((length & 0x01) == 0) {
+                if ((length & 0x02) == 0) {
+                    if ((length & 0x04) == 0) {
+                        copyLongsUp(src, srcPos, dest, destPos, length >> 3);
+                    } else {
+                        copyIntsUp(src, srcPos, dest, destPos, length >> 2);
+                    }
+                } else {
+                    copyShortsUp(src, srcPos, dest, destPos, length >> 1);
+                }
+            } else {
+                copyBytesUp(src, srcPos, dest, destPos, length);
+            }
+        }
+    }
+
+    @Snippet
+    public static void arraycopy(char[] src, int srcPos, char[] dest, int destPos, int length) {
+        if (src == null || dest == null) {
+            throw new NullPointerException();
+        }
+        if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (src == dest && srcPos < destPos) { // bad aliased case
+            if ((length & 0x01) == 0) {
+                if ((length & 0x02) == 0) {
+                    copyLongsDown(src, srcPos * 2L, dest, destPos * 2L, length >> 2);
+                } else {
+                    copyIntsDown(src, srcPos * 2L, dest, destPos * 2L, length >> 1);
+                }
+            } else {
+                copyShortsDown(src, srcPos * 2L, dest, destPos * 2L, length);
+            }
+        } else {
+            if ((length & 0x01) == 0) {
+                if ((length & 0x02) == 0) {
+                    copyLongsUp(src, srcPos * 2L, dest, destPos * 2L, length >> 2);
+                } else {
+                    copyIntsUp(src, srcPos * 2L, dest, destPos * 2L, length >> 1);
+                }
+            } else {
+                copyShortsUp(src, srcPos * 2L, dest, destPos * 2L, length);
+            }
+        }
+    }
+
+    @Snippet
+    public static void arraycopy(short[] src, int srcPos, short[] dest, int destPos, int length) {
+        if (src == null || dest == null) {
+            throw new NullPointerException();
+        }
+        if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (src == dest && srcPos < destPos) { // bad aliased case
+            if ((length & 0x01) == 0) {
+                if ((length & 0x02) == 0) {
+                    copyLongsDown(src, srcPos * 2L, dest, destPos * 2L, length >> 2);
+                } else {
+                    copyIntsDown(src, srcPos * 2L, dest, destPos * 2L, length >> 1);
+                }
+            } else {
+                copyShortsDown(src, srcPos * 2L, dest, destPos * 2L, length);
+            }
+        } else {
+            if ((length & 0x01) == 0) {
+                if ((length & 0x02) == 0) {
+                    copyLongsUp(src, srcPos * 2L, dest, destPos * 2L, length >> 2);
+                } else {
+                    copyIntsUp(src, srcPos * 2L, dest, destPos * 2L, length >> 1);
+                }
+            } else {
+                copyShortsUp(src, srcPos * 2L, dest, destPos * 2L, length);
+            }
+        }
+    }
+
+    @Snippet
+    public static void arraycopy(int[] src, int srcPos, int[] dest, int destPos, int length) {
+        if (src == null || dest == null) {
+            throw new NullPointerException();
+        }
+        if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (src == dest && srcPos < destPos) { // bad aliased case
+            if ((length & 0x01) == 0) {
+                copyLongsDown(src, srcPos * 4L, dest, destPos * 4L, length >> 1);
+            } else {
+                copyIntsDown(src, srcPos * 4L, dest, destPos * 4L, length);
+            }
+        } else {
+            if ((length & 0x01) == 0) {
+                copyLongsUp(src, srcPos * 4L, dest, destPos * 4L, length >> 1);
+            } else {
+                copyIntsUp(src, srcPos * 4L, dest, destPos * 4L, length);
+            }
+        }
+    }
+
+    @Snippet
+    public static void arraycopy(float[] src, int srcPos, float[] dest, int destPos, int length) {
+        if (src == null || dest == null) {
+            throw new NullPointerException();
+        }
+        if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (src == dest && srcPos < destPos) { // bad aliased case
+            if ((length & 0x01) == 0) {
+                copyLongsDown(src, srcPos * 4L, dest, destPos * 4L, length >> 1);
+            } else {
+                copyIntsDown(src, srcPos * 4L, dest, destPos * 4L, length);
+            }
+        } else {
+            if ((length & 0x01) == 0) {
+                copyLongsUp(src, srcPos * 4L, dest, destPos * 4L, length >> 1);
+            } else {
+                copyIntsUp(src, srcPos * 4L, dest, destPos * 4L, length);
+            }
+        }
+    }
+
+    @Snippet
+    public static void arraycopy(long[] src, int srcPos, long[] dest, int destPos, int length) {
+        if (src == null || dest == null) {
+            throw new NullPointerException();
+        }
+        if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (src == dest && srcPos < destPos) { // bad aliased case
+            copyLongsDown(src, srcPos * 8L, dest, destPos * 8L, length);
+        } else {
+            copyLongsUp(src, srcPos * 8L, dest, destPos * 8L, length);
+        }
+    }
+
+    @Snippet
+    public static void arraycopy(double[] src, int srcPos, double[] dest, int destPos, int length) {
+        if (src == null || dest == null) {
+            throw new NullPointerException();
+        }
+        if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (src == dest && srcPos < destPos) { // bad aliased case
+            copyLongsDown(src, srcPos * 8L, dest, destPos * 8L, length);
+        } else {
+            copyLongsUp(src, srcPos * 8L, dest, destPos * 8L, length);
+        }
+    }
+
+    // Does NOT perform store checks
+    @Snippet
+    public static void arraycopy(Object[] src, int srcPos, Object[] dest, int destPos, int length) {
+        if (src == null || dest == null) {
+            throw new NullPointerException();
+        }
+        if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (src == dest && srcPos < destPos) { // bad aliased case
+            copyObjectsDown(src, srcPos * 8L, dest, destPos * 8L, length);
+        } else {
+            copyObjectsUp(src, srcPos * 8L, dest, destPos * 8L, length);
+        }
+        if (length > 0) {
+            long header = ArrayHeaderSizeNode.sizeFor(CiKind.Object);
+            int cardShift = CardTableShiftNode.get();
+            long cardStart = CardTableStartNode.get();
+            long dstAddr = GetObjectAddressNode.get(dest);
+            long start = (dstAddr + header + destPos * 8L) >>> cardShift;
+            long end = (dstAddr + header + (destPos + length - 1) * 8L) >>> cardShift;
+            long count = end - start + 1;
+            while (count-- > 0) {
+                DirectStoreNode.store((start + cardStart) + count, false);
+            }
+        }
+    }
+
+    @Snippet
+    public static void copyBytesDown(Object src, int srcPos, Object dest, int destPos, int length)  {
+        long header = ArrayHeaderSizeNode.sizeFor(CiKind.Byte);
+        for (long i = length - 1; i >= 0; i--) {
+            Byte a = UnsafeLoadNode.load(src, i + (srcPos + header), CiKind.Byte);
+            UnsafeStoreNode.store(dest, i + (destPos + header), a.byteValue(), CiKind.Byte);
+        }
+    }
+
+    @Snippet
+    public static void copyShortsDown(Object src, long srcOffset, Object dest, long destOffset, int length)  {
+        long header = ArrayHeaderSizeNode.sizeFor(CiKind.Short);
+        for (long i = (length - 1) * 2; i >= 0; i -= 2) {
+            Character a = UnsafeLoadNode.load(src, i + (srcOffset + header), CiKind.Short);
+            UnsafeStoreNode.store(dest, i + (destOffset + header), a.charValue(), CiKind.Short);
+        }
+    }
+
+    @Snippet
+    public static void copyIntsDown(Object src, long srcOffset, Object dest, long destOffset, int length)  {
+        long header = ArrayHeaderSizeNode.sizeFor(CiKind.Short);
+        for (long i = (length - 1) * 4; i >= 0; i -= 4) {
+            Integer a = UnsafeLoadNode.load(src, i + (srcOffset + header), CiKind.Int);
+            UnsafeStoreNode.store(dest, i + (destOffset + header), a.intValue(), CiKind.Int);
+        }
+    }
+
+    @Snippet
+    public static void copyLongsDown(Object src, long srcOffset, Object dest, long destOffset, int length)  {
+        long header = ArrayHeaderSizeNode.sizeFor(CiKind.Short);
+        for (long i = (length - 1) * 8; i >= 0; i -= 8) {
+            Long a = UnsafeLoadNode.load(src, i + (srcOffset + header), CiKind.Long);
+            UnsafeStoreNode.store(dest, i + (destOffset + header), a.longValue(), CiKind.Long);
+        }
+    }
+
+    // Does NOT perform store checks
+    @Snippet
+    public static void copyObjectsDown(Object src, long srcOffset, Object dest, long destOffset, int length)  {
+        long header = ArrayHeaderSizeNode.sizeFor(CiKind.Object);
+        for (long i = (length - 1) * 8; i >= 0; i -= 8) {
+            Object a = UnsafeLoadNode.load(src, i + (srcOffset + header), CiKind.Object);
+            DirectObjectStoreNode.store(dest, i + (destOffset + header), a);
+        }
+    }
+    /**
+     * Copies {@code length} bytes from {@code src} starting at {@code srcPos} to {@code dest} starting at {@code destPos}.
+     * @param src source object
+     * @param srcPos source offset
+     * @param dest destination object
+     * @param destPos destination offset
+     * @param length number of bytes to copy
+     */
+    @Snippet
+    public static void copyBytesUp(Object src, int srcPos, Object dest, int destPos, int length)  {
+        long header = ArrayHeaderSizeNode.sizeFor(CiKind.Byte);
+        for (long i = 0; i < length; i++) {
+            Byte a = UnsafeLoadNode.load(src, i + (srcPos + header), CiKind.Byte);
+            UnsafeStoreNode.store(dest, i + (destPos + header), a.byteValue(), CiKind.Byte);
+        }
+    }
+
+    /**
+     * Copies {@code length} shorts from {@code src} starting at offset {@code srcOffset} (in bytes) to {@code dest} starting at offset {@code destOffset} (in bytes).
+     * @param src
+     * @param srcOffset (in bytes)
+     * @param dest
+     * @param destOffset (in bytes)
+     * @param length  (in shorts)
+     */
+    @Snippet
+    public static void copyShortsUp(Object src, long srcOffset, Object dest, long destOffset, int length)  {
+        long header = ArrayHeaderSizeNode.sizeFor(CiKind.Short);
+        for (long i = 0; i < length * 2L; i += 2) {
+            Character a = UnsafeLoadNode.load(src, i + (srcOffset + header), CiKind.Short);
+            UnsafeStoreNode.store(dest, i + (destOffset + header), a.charValue(), CiKind.Short);
+        }
+    }
+
+    @Snippet
+    public static void copyIntsUp(Object src, long srcOffset, Object dest, long destOffset, int length)  {
+        long header = ArrayHeaderSizeNode.sizeFor(CiKind.Int);
+        for (long i = 0; i < length * 4L; i += 4) {
+            Integer a = UnsafeLoadNode.load(src, i + (srcOffset + header), CiKind.Int);
+            UnsafeStoreNode.store(dest, i + (destOffset + header), a.intValue(), CiKind.Int);
+        }
+    }
+
+    @Snippet
+    public static void copyLongsUp(Object src, long srcOffset, Object dest, long destOffset, int length)  {
+        long header = ArrayHeaderSizeNode.sizeFor(CiKind.Long);
+        for (long i = 0; i < length * 8L; i += 8) {
+            Long a = UnsafeLoadNode.load(src, i + (srcOffset + header), CiKind.Long);
+            UnsafeStoreNode.store(dest, i + (destOffset + header), a.longValue(), CiKind.Long);
+        }
+    }
+
+    // Does NOT perform store checks
+    @Snippet
+    public static void copyObjectsUp(Object src, long srcOffset, Object dest, long destOffset, int length)  {
+        long header = ArrayHeaderSizeNode.sizeFor(CiKind.Object);
+        for (long i = 0; i < length * 8L; i += 8) {
+            Object a = UnsafeLoadNode.load(src, i + (srcOffset + header), CiKind.Object);
+            DirectObjectStoreNode.store(dest, i + (destOffset + header), a);
+        }
+    }
+    private static class GetObjectAddressNode extends FixedWithNextNode implements LIRLowerable {
+        @Input private ValueNode object;
+
+        public GetObjectAddressNode(ValueNode obj) {
+            super(StampFactory.forKind(CiKind.Long));
+            this.object = obj;
+        }
+
+        @SuppressWarnings("unused")
+        @NodeIntrinsic
+        public static long get(Object array) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void generate(LIRGeneratorTool gen) {
+            CiValue obj = gen.newVariable(gen.target().wordKind);
+            gen.emitMove(gen.operand(object), obj);
+            gen.setResult(this, obj);
+        }
+    }
+    private static class DirectStoreNode extends FixedWithNextNode implements LIRLowerable {
+        @Input private ValueNode address;
+        @Input private ValueNode value;
+
+        public DirectStoreNode(ValueNode address, ValueNode value) {
+            super(StampFactory.illegal());
+            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) {
+            CiValue v = gen.operand(value);
+            gen.emitStore(new CiAddress(v.kind, gen.operand(address)), v, false);
+        }
+    }
+
+    private static class DirectObjectStoreNode extends FixedWithNextNode implements Lowerable {
+        @Input private ValueNode object;
+        @Input private ValueNode value;
+        @Input private ValueNode offset;
+
+        public DirectObjectStoreNode(ValueNode object, ValueNode offset, ValueNode value) {
+            super(StampFactory.illegal());
+            this.object = object;
+            this.value = value;
+            this.offset = offset;
+        }
+
+        @SuppressWarnings("unused")
+        @NodeIntrinsic
+        public static void store(Object obj, long offset, long value) {
+            throw new UnsupportedOperationException();
+        }
+
+        @SuppressWarnings("unused")
+        @NodeIntrinsic
+        public static void store(Object obj, long offset, boolean value) {
+            throw new UnsupportedOperationException();
+        }
+
+        @SuppressWarnings("unused")
+        @NodeIntrinsic
+        public static void store(Object obj, long offset, Object value) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void lower(CiLoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) this.graph();
+            IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, value.kind(), 0, offset, graph, false);
+            WriteNode write = graph.add(new WriteNode(object, value, location));
+            graph.replaceFixedWithFixed(this, write);
+        }
+    }
+
+    private static class CardTableShiftNode extends ConstantNode {
+        public CardTableShiftNode() {
+            super(CiConstant.forInt(CompilerImpl.getInstance().getConfig().cardtableShift));
+        }
+
+        @NodeIntrinsic
+        public static int get() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    private static class CardTableStartNode extends ConstantNode {
+        public CardTableStartNode() {
+            super(CiConstant.forLong(CompilerImpl.getInstance().getConfig().cardtableStartAddress));
+        }
+
+        @NodeIntrinsic
+        public static long get() {
+            throw new UnsupportedOperationException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,130 @@
+/*
+ * 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.max.graal.hotspot.snippets;
+
+import java.lang.reflect.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.java.*;
+
+public class IntrinsifyArrayCopyPhase extends Phase {
+    private final GraalRuntime runtime;
+    private RiResolvedMethod arrayCopy;
+    private RiResolvedMethod byteArrayCopy;
+    private RiResolvedMethod shortArrayCopy;
+    private RiResolvedMethod charArrayCopy;
+    private RiResolvedMethod intArrayCopy;
+    private RiResolvedMethod longArrayCopy;
+    private RiResolvedMethod floatArrayCopy;
+    private RiResolvedMethod doubleArrayCopy;
+    private RiResolvedMethod objectArrayCopy;
+
+    public IntrinsifyArrayCopyPhase(GraalRuntime runtime) {
+        this.runtime = runtime;
+        try {
+            byteArrayCopy = getArrayCopySnippet(runtime, byte.class);
+            charArrayCopy = getArrayCopySnippet(runtime, char.class);
+            shortArrayCopy = getArrayCopySnippet(runtime, short.class);
+            intArrayCopy = getArrayCopySnippet(runtime, int.class);
+            longArrayCopy = getArrayCopySnippet(runtime, long.class);
+            floatArrayCopy = getArrayCopySnippet(runtime, float.class);
+            doubleArrayCopy = getArrayCopySnippet(runtime, double.class);
+            objectArrayCopy = getArrayCopySnippet(runtime, Object.class);
+            arrayCopy = runtime.getRiMethod(System.class.getDeclaredMethod("arraycopy", Object.class, int.class, Object.class, int.class, int.class));
+        } catch (SecurityException e) {
+            e.printStackTrace();
+        } catch (NoSuchMethodException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static RiResolvedMethod getArrayCopySnippet(RiRuntime runtime, Class<?> componentClass) throws NoSuchMethodException {
+        Class<?> arrayClass = Array.newInstance(componentClass, 0).getClass();
+        return runtime.getRiMethod(ArrayCopySnippets.class.getDeclaredMethod("arraycopy", arrayClass, int.class, arrayClass, int.class, int.class));
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        boolean hits = false;
+        for (MethodCallTargetNode methodCallTarget : graph.getNodes(MethodCallTargetNode.class)) {
+            RiResolvedMethod targetMethod = methodCallTarget.targetMethod();
+            RiResolvedMethod snippetMethod = null;
+            if (targetMethod == arrayCopy) {
+                ValueNode src = methodCallTarget.arguments().get(0);
+                ValueNode dest = methodCallTarget.arguments().get(2);
+                if (src == null || dest == null) { //TODO (gd) this should never be null : check
+                    return;
+                }
+                RiResolvedType srcDeclaredType = src.declaredType();
+                RiResolvedType destDeclaredType = dest.declaredType();
+                if (srcDeclaredType != null
+                                && srcDeclaredType.isArrayClass()
+                                && destDeclaredType != null
+                                && destDeclaredType.isArrayClass()) {
+                    CiKind componentKind = srcDeclaredType.componentType().kind(false);
+                    if (srcDeclaredType.componentType() == destDeclaredType.componentType()) {
+                        if (componentKind == CiKind.Int) {
+                            snippetMethod = intArrayCopy;
+                        } else if (componentKind == CiKind.Char) {
+                            snippetMethod = charArrayCopy;
+                        } else if (componentKind == CiKind.Long) {
+                            snippetMethod = longArrayCopy;
+                        } else if (componentKind == CiKind.Byte) {
+                            snippetMethod = byteArrayCopy;
+                        } else if (componentKind == CiKind.Short) {
+                            snippetMethod = shortArrayCopy;
+                        } else if (componentKind == CiKind.Float) {
+                            snippetMethod = floatArrayCopy;
+                        } else if (componentKind == CiKind.Double) {
+                            snippetMethod = doubleArrayCopy;
+                        } else if (componentKind == CiKind.Object) {
+                            snippetMethod = objectArrayCopy;
+                        }
+                    } else if (componentKind == CiKind.Object
+                                    && srcDeclaredType.componentType().isSubtypeOf(destDeclaredType.componentType())) {
+                        snippetMethod = objectArrayCopy;
+                    }
+                }
+            }
+
+            if (snippetMethod != null) {
+                StructuredGraph snippetGraph = (StructuredGraph) snippetMethod.compilerStorage().get(Graph.class);
+                assert snippetGraph != null : "ArrayCopySnippets should be installed";
+                hits = true;
+                Debug.log("%s > Intinsify (%s)", Debug.currentScope(), snippetMethod.signature().argumentTypeAt(0, snippetMethod.holder()).componentType());
+                InliningUtil.inline(methodCallTarget.invoke(), snippetGraph, false);
+            }
+        }
+        if (GraalOptions.OptCanonicalizer && hits) {
+            new CanonicalizerPhase(null, runtime, null).apply(graph);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/snippets/SystemSnippets.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * 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.max.graal.hotspot.snippets;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.snippets.*;
+
+/**
+ * Snippets for {@link java.lang.System} methods.
+ */
+@ClassSubstitution(java.lang.System.class)
+public class SystemSnippets implements SnippetsInterface {
+
+    public static long currentTimeMillis() {
+        return RuntimeCallNode.performCall(CiRuntimeCall.JavaTimeMillis);
+    }
+
+    public static long nanoTime() {
+        return RuntimeCallNode.performCall(CiRuntimeCall.JavaTimeNanos);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/snippets/UnsafeSnippets.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,252 @@
+/*
+ * 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.max.graal.hotspot.snippets;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.util.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.java.*;
+import com.oracle.max.graal.snippets.*;
+
+/**
+ * Snippets for {@link sun.misc.Unsafe} methods.
+ */
+@ClassSubstitution(sun.misc.Unsafe.class)
+public class UnsafeSnippets implements SnippetsInterface {
+
+    public boolean compareAndSwapObject(Object o, long offset, Object expected, Object x) {
+        return CompareAndSwapNode.compareAndSwap(o, offset, expected, x);
+    }
+
+    public boolean compareAndSwapInt(Object o, long offset, int expected, int x) {
+        return CompareAndSwapNode.compareAndSwap(o, offset, expected, x);
+    }
+
+    public boolean compareAndSwapLong(Object o, long offset, long expected, long x) {
+        return CompareAndSwapNode.compareAndSwap(o, offset, expected, x);
+    }
+
+    public Object getObject(Object o, long offset) {
+        return UnsafeLoadNode.load(o, offset, CiKind.Object);
+    }
+
+    public Object getObjectVolatile(Object o, long offset) {
+        MembarNode.get(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        Object result = getObject(o, offset);
+        MembarNode.get(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    public void putObject(Object o, long offset, Object x) {
+        UnsafeStoreNode.store(o, offset, x, CiKind.Object);
+    }
+
+    public void putObjectVolatile(Object o, long offset, Object x) {
+        MembarNode.get(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putObject(o, offset, x);
+        MembarNode.get(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    public int getInt(Object o, long offset) {
+        Integer value = UnsafeLoadNode.load(o, offset, CiKind.Int);
+        return value;
+    }
+
+    public int getIntVolatile(Object o, long offset) {
+        MembarNode.get(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        int result = getInt(o, offset);
+        MembarNode.get(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    public void putInt(Object o, long offset, int x) {
+        UnsafeStoreNode.store(o, offset, x, CiKind.Int);
+    }
+
+    public void putIntVolatile(Object o, long offset, int x) {
+        MembarNode.get(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putInt(o, offset, x);
+        MembarNode.get(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    public boolean getBoolean(Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Boolean result = UnsafeLoadNode.load(o, offset, CiKind.Boolean);
+        return result;
+    }
+
+    public boolean getBooleanVolatile(Object o, long offset) {
+        MembarNode.get(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        boolean result = getBoolean(o, offset);
+        MembarNode.get(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    public void putBoolean(Object o, long offset, boolean x) {
+        UnsafeStoreNode.store(o, offset, x, CiKind.Boolean);
+    }
+
+    public void putBooleanVolatile(Object o, long offset, boolean x) {
+        MembarNode.get(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putBoolean(o, offset, x);
+        MembarNode.get(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    public byte getByte(Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Byte result = UnsafeLoadNode.load(o, offset, CiKind.Byte);
+        return result;
+    }
+
+    public byte getByteVolatile(Object o, long offset) {
+        MembarNode.get(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        byte result = getByte(o, offset);
+        MembarNode.get(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    public void putByte(Object o, long offset, byte x) {
+        UnsafeStoreNode.store(o, offset, x, CiKind.Byte);
+    }
+
+    public void putByteVolatile(Object o, long offset, byte x) {
+        MembarNode.get(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putByte(o, offset, x);
+        MembarNode.get(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    public short getShort(Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Short result = UnsafeLoadNode.load(o, offset, CiKind.Short);
+        return result;
+    }
+
+    public short getShortVolatile(Object o, long offset) {
+        MembarNode.get(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        short result = getShort(o, offset);
+        MembarNode.get(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    public void putShort(Object o, long offset, short x) {
+        UnsafeStoreNode.store(o, offset, x, CiKind.Short);
+    }
+
+    public void putShortVolatile(Object o, long offset, short x) {
+        MembarNode.get(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putShort(o, offset, x);
+        MembarNode.get(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    public char getChar(Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Character result = UnsafeLoadNode.load(o, offset, CiKind.Char);
+        return result;
+    }
+
+    public char getCharVolatile(Object o, long offset) {
+        MembarNode.get(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        char result = getChar(o, offset);
+        MembarNode.get(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    public void putChar(Object o, long offset, char x) {
+        UnsafeStoreNode.store(o, offset, x, CiKind.Char);
+    }
+
+    public void putCharVolatile(Object o, long offset, char x) {
+        MembarNode.get(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putChar(o, offset, x);
+        MembarNode.get(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    public long getLong(Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Long result = UnsafeLoadNode.load(o, offset, CiKind.Long);
+        return result;
+    }
+
+    public long getLongVolatile(Object o, long offset) {
+        MembarNode.get(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        long result = getLong(o, offset);
+        MembarNode.get(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    public void putLong(Object o, long offset, long x) {
+        UnsafeStoreNode.store(o, offset, x, CiKind.Long);
+    }
+
+    public void putLongVolatile(Object o, long offset, long x) {
+        MembarNode.get(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putLong(o, offset, x);
+        MembarNode.get(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    public float getFloat(Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Float result = UnsafeLoadNode.load(o, offset, CiKind.Float);
+        return result;
+    }
+
+    public float getFloatVolatile(Object o, long offset) {
+        MembarNode.get(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        float result = getFloat(o, offset);
+        MembarNode.get(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    public void putFloat(Object o, long offset, float x) {
+        UnsafeStoreNode.store(o, offset, x, CiKind.Float);
+    }
+
+    public void putFloatVolatile(Object o, long offset, float x) {
+        MembarNode.get(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putFloat(o, offset, x);
+        MembarNode.get(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    public double getDouble(Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Double result = UnsafeLoadNode.load(o, offset, CiKind.Double);
+        return result;
+    }
+
+    public double getDoubleVolatile(Object o, long offset) {
+        MembarNode.get(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        double result = getDouble(o, offset);
+        MembarNode.get(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    public void putDouble(Object o, long offset, double x) {
+        UnsafeStoreNode.store(o, offset, x, CiKind.Double);
+    }
+
+    public void putDoubleVolatile(Object o, long offset, double x) {
+        MembarNode.get(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putDouble(o, offset, x);
+        MembarNode.get(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/target/amd64/AMD64TailcallOp.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.hotspot.target.amd64;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.amd64.*;
+import com.oracle.max.graal.lir.asm.*;
+
+/**
+ * Performs a hard-coded tail call to the specified target, which normally should be an RiCompiledCode instance.
+ */
+public class AMD64TailcallOp extends AMD64LIRInstruction {
+
+    public AMD64TailcallOp(List<CiValue> parameters, CiValue target, CiValue[] callingConvention) {
+        super("TAILCALL", LIRInstruction.NO_OPERANDS, null, toArray(parameters, target), LIRInstruction.NO_OPERANDS, callingConvention.clone());
+        assert inputs.length == temps.length + 1;
+
+        for (int i = 0; i < temps.length; i++) {
+            assert isRegister(temps[i]) : "too many parameters for tail call";
+            assert sameRegister(temps[i], inputs[i]) : "inputs do not match calling convention";
+        }
+    }
+
+    private static CiValue[] toArray(List<CiValue> parameters, CiValue target) {
+        CiValue[] result = new CiValue[parameters.size() + 1];
+        parameters.toArray(result);
+        result[parameters.size()] = target;
+        return result;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        // destroy the current frame (now the return address is the top of stack)
+        masm.leave();
+
+        // jump to the target method
+        masm.jmp(asRegister(inputs[inputs.length - 1]));
+        masm.ensureUniquePC();
+    }
+
+    @Override
+    protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+        if (mode == OperandMode.Input) {
+            return EnumSet.of(OperandFlag.Register);
+        } else if (mode == OperandMode.Temp) {
+            return EnumSet.of(OperandFlag.Register);
+        }
+        throw GraalInternalError.shouldNotReachHere();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BciBlockMapping.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,643 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.java;
+
+import static com.oracle.max.graal.java.Bytecodes.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.nodes.*;
+
+/**
+ * Builds a mapping between bytecodes and basic blocks and builds a conservative control flow
+ * graph. Note that this class serves a similar role to C1's {@code BlockListBuilder}, but makes fewer assumptions about
+ * what the compiler interface provides. It builds all basic blocks for the control flow graph without requiring the
+ * compiler interface to provide a bitmap of the beginning of basic blocks. It makes two linear passes; one over the
+ * bytecodes to build block starts and successor lists, and one pass over the block map to build the CFG.
+ *
+ * Note that the CFG built by this class is <i>not</i> connected to the actual {@code BlockBegin} instances; this class
+ * does, however, compute and assign the reverse postorder number of the blocks. This comment needs refinement. (MJJ)
+ *
+ * <H2>More Details on {@link BciBlockMapping#build}</H2>
+ *
+ * If the method has any exception handlers the {@linkplain #exceptionMap exception map} will be created (TBD).
+ *
+ * The bytecodes are then scanned linearly looking for bytecodes that contain control transfers, e.g., {@code GOTO},
+ * {@code RETURN}, {@code IFGE}, and creating the corresponding entries in {@link #successorMap} and {@link #blockMap}.
+ * In addition, if {@link #exceptionMap} is not null, entries are made for any bytecode that can cause an exception.
+ * More TBD.
+ *
+ * Observe that this process finds bytecodes that terminate basic blocks, so the {@link #moveSuccessorLists} method is
+ * called to reassign the successors to the {@code BlockBegin} node that actually starts the block.
+ *
+ * <H3>Example</H3>
+ *
+ * Consider the following source code:
+ *
+ * <pre>
+ * <code>
+ *     public static int test(int arg1, int arg2) {
+ *         int x = 0;
+ *         while (arg2 > 0) {
+ *             if (arg1 > 0) {
+ *                 x += 1;
+ *             } else if (arg1 < 0) {
+ *                 x -= 1;
+ *             }
+ *         }
+ *         return x;
+ *     }
+ * </code>
+ * </pre>
+ *
+ * This is translated by javac to the following bytecode:
+ *
+ * <pre>
+ * <code>
+ *    0:   iconst_0
+ *    1:   istore_2
+ *    2:   goto    22
+ *    5:   iload_0
+ *    6:   ifle    15
+ *    9:   iinc    2, 1
+ *    12:  goto    22
+ *    15:  iload_0
+ *    16:  ifge    22
+ *    19:  iinc    2, -1
+ *    22:  iload_1
+ *    23:  ifgt    5
+ *    26:  iload_2
+ *    27:  ireturn
+ *    </code>
+ * </pre>
+ *
+ * There are seven basic blocks in this method, 0..2, 5..6, 9..12, 15..16, 19..19, 22..23 and 26..27. Therefore, before
+ * the call to {@code moveSuccessorLists}, the {@code blockMap} array has {@code BlockBegin} nodes at indices 0, 5, 9,
+ * 15, 19, 22 and 26. The {@code successorMap} array has entries at 2, 6, 12, 16, 23, 27 corresponding to the control
+ * transfer bytecodes. The entry at index 6, for example, is a length two array of {@code BlockBegin} nodes for indices
+ * 9 and 15, which are the successors for the basic block 5..6. After the call to {@code moveSuccessors}, {@code
+ * successorMap} has entries at 0, 5, 9, 15, 19, 22 and 26, i.e, matching {@code blockMap}.
+ * <p>
+ * Next the blocks are numbered using <a href="http://en.wikipedia.org/wiki/Depth-first_search#Vertex_orderings">reverse
+ * post-order</a>. For the above example this results in the numbering 2, 4, 7, 5, 6, 3, 8. Also loop header blocks are
+ * detected during the traversal by detecting a repeat visit to a block that is still being processed. This causes the
+ * block to be flagged as a loop header and also added to the {@link #loopBlocks} list. The {@code loopBlocks} list
+ * contains the blocks at 0, 5, 9, 15, 19, 22, with 22 as the loop header. (N.B. the loop header block is added multiple
+ * (4) times to this list). (Should 0 be in? It's not inside the loop).
+ *
+ * If the {@code computeStoresInLoops} argument to {@code build} is true, the {@code loopBlocks} list is processed to
+ * mark all local variables that are stored in the blocks in the list.
+ */
+public final class BciBlockMapping {
+
+    public static class Block implements Cloneable {
+        public int startBci;
+        public int endBci;
+        public boolean isExceptionEntry;
+        public boolean isLoopHeader;
+        public int blockID;
+
+        public FixedWithNextNode firstInstruction;
+
+        public ArrayList<Block> successors = new ArrayList<>(2);
+        public int normalSuccessors;
+
+        private boolean visited;
+        private boolean active;
+        public long loops;
+
+        public HashMap<JsrScope, Block> jsrAlternatives;
+        public JsrScope jsrScope = JsrScope.EMPTY_SCOPE;
+        public Block jsrSuccessor;
+        public int jsrReturnBci;
+        public Block retSuccessor;
+        public boolean endsWithRet = false;
+
+        public Block copy() {
+            try {
+                Block block = (Block) super.clone();
+                block.successors = new ArrayList<>(successors);
+                return block;
+            } catch (CloneNotSupportedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder("B").append(blockID);
+            sb.append('[').append(startBci).append("->").append(endBci);
+            if (isLoopHeader || isExceptionEntry) {
+                sb.append(' ');
+                if (isLoopHeader) {
+                    sb.append('L');
+                }
+                if (isExceptionEntry) {
+                    sb.append('!');
+                }
+            }
+            sb.append(']');
+            return sb.toString();
+        }
+    }
+
+    public static class ExceptionBlock extends Block {
+        public RiExceptionHandler handler;
+        public int deoptBci;
+    }
+
+    public static class DeoptBlock extends Block {
+        public DeoptBlock(int startBci) {
+            this.startBci = startBci;
+        }
+    }
+
+    /**
+     * The blocks found in this method, in reverse postorder.
+     */
+    public final List<Block> blocks;
+
+    public final RiResolvedMethod method;
+
+    private final RiExceptionHandler[] exceptionHandlers;
+
+    private Block[] blockMap;
+
+    public final BitSet canTrap;
+
+    public boolean hasJsrBytecodes;
+
+    public Block startBlock;
+
+    public final boolean useBranchPrediction;
+
+    /**
+     * Creates a new BlockMap instance from bytecode of the given method .
+     * @param method the compiler interface method containing the code
+     */
+    public BciBlockMapping(RiResolvedMethod method, boolean useBranchPrediction) {
+        this.method = method;
+        exceptionHandlers = method.exceptionHandlers();
+        this.blockMap = new Block[method.codeSize()];
+        this.canTrap = new BitSet(blockMap.length);
+        this.blocks = new ArrayList<>();
+        this.useBranchPrediction = useBranchPrediction;
+    }
+
+    public RiExceptionHandler[] exceptionHandlers() {
+        return exceptionHandlers;
+    }
+
+    /**
+     * Builds the block map and conservative CFG and numbers blocks.
+     */
+    public void build() {
+        makeExceptionEntries();
+        iterateOverBytecodes();
+        addExceptionEdges();
+        if (hasJsrBytecodes) {
+            if (!GraalOptions.SupportJsrBytecodes) {
+                throw new JsrNotSupportedBailout("jsr/ret parsing disabled");
+            }
+            createJsrAlternatives(blockMap[0]);
+        }
+        computeBlockOrder();
+
+        initializeBlockIds();
+
+        startBlock = blockMap[0];
+
+        // Discard big arrays so that they can be GCed
+        blockMap = null;
+    }
+
+    private void initializeBlockIds() {
+        for (int i = 0; i < blocks.size(); i++) {
+            blocks.get(i).blockID = i;
+        }
+    }
+
+    private void makeExceptionEntries() {
+        // start basic blocks at all exception handler blocks and mark them as exception entries
+        for (RiExceptionHandler h : this.exceptionHandlers) {
+            Block xhandler = makeBlock(h.handlerBCI());
+            xhandler.isExceptionEntry = true;
+        }
+    }
+
+    private void iterateOverBytecodes() {
+        // iterate over the bytecodes top to bottom.
+        // mark the entrypoints of basic blocks and build lists of successors for
+        // all bytecodes that end basic blocks (i.e. goto, ifs, switches, throw, jsr, returns, ret)
+        byte[] code = method.code();
+        RiProfilingInfo profilingInfo = method.profilingInfo();
+        Block current = null;
+        int bci = 0;
+        while (bci < code.length) {
+            if (current == null || blockMap[bci] != null) {
+                Block b = makeBlock(bci);
+                if (current != null) {
+                    setSuccessors(current.endBci, b);
+                }
+                current = b;
+            }
+            blockMap[bci] = current;
+            current.endBci = bci;
+
+            int opcode = Bytes.beU1(code, bci);
+            switch (opcode) {
+                case IRETURN: // fall through
+                case LRETURN: // fall through
+                case FRETURN: // fall through
+                case DRETURN: // fall through
+                case ARETURN: // fall through
+                case RETURN: {
+                    current = null;
+                    break;
+                }
+                case ATHROW: {
+                    current = null;
+                    canTrap.set(bci);
+                    break;
+                }
+                case IFEQ:      // fall through
+                case IFNE:      // fall through
+                case IFLT:      // fall through
+                case IFGE:      // fall through
+                case IFGT:      // fall through
+                case IFLE:      // fall through
+                case IF_ICMPEQ: // fall through
+                case IF_ICMPNE: // fall through
+                case IF_ICMPLT: // fall through
+                case IF_ICMPGE: // fall through
+                case IF_ICMPGT: // fall through
+                case IF_ICMPLE: // fall through
+                case IF_ACMPEQ: // fall through
+                case IF_ACMPNE: // fall through
+                case IFNULL:    // fall through
+                case IFNONNULL: {
+                    current = null;
+                    double probability = useBranchPrediction ? profilingInfo.getBranchTakenProbability(bci) : -1;
+
+                    Block b1 = probability == 0.0 ? new DeoptBlock(bci + Bytes.beS2(code, bci + 1)) : makeBlock(bci + Bytes.beS2(code, bci + 1));
+                    Block b2 = probability == 1.0 ? new DeoptBlock(bci + 3) : makeBlock(bci + 3);
+                    setSuccessors(bci, b1, b2);
+                    break;
+                }
+                case GOTO:
+                case GOTO_W: {
+                    current = null;
+                    int target = bci + Bytes.beSVar(code, bci + 1, opcode == GOTO_W);
+                    Block b1 = makeBlock(target);
+                    setSuccessors(bci, b1);
+                    break;
+                }
+                case TABLESWITCH: {
+                    current = null;
+                    BytecodeTableSwitch sw = new BytecodeTableSwitch(code, bci);
+                    setSuccessors(bci, makeSwitchSuccessors(sw));
+                    break;
+                }
+                case LOOKUPSWITCH: {
+                    current = null;
+                    BytecodeLookupSwitch sw = new BytecodeLookupSwitch(code, bci);
+                    setSuccessors(bci, makeSwitchSuccessors(sw));
+                    break;
+                }
+                case JSR:
+                case JSR_W: {
+                    hasJsrBytecodes = true;
+                    int target = bci + Bytes.beSVar(code, bci + 1, opcode == JSR_W);
+                    if (target == 0) {
+                        throw new JsrNotSupportedBailout("jsr target bci 0 not allowed");
+                    }
+                    Block b1 = makeBlock(target);
+                    current.jsrSuccessor = b1;
+                    current.jsrReturnBci = bci + lengthOf(opcode);
+                    current = null;
+                    setSuccessors(bci, b1);
+                    break;
+                }
+                case RET: {
+                    current.endsWithRet = true;
+                    current = null;
+                    break;
+                }
+                case WIDE: {
+                    int opcode2 = Bytes.beU1(code, bci);
+                    switch (opcode2) {
+                        case RET: {
+                            current.endsWithRet = true;
+                            current = null;
+                            break;
+                        }
+                    }
+                    break;
+                }
+                case INVOKEINTERFACE:
+                case INVOKESPECIAL:
+                case INVOKESTATIC:
+                case INVOKEVIRTUAL: {
+                    current = null;
+                    int target = bci + lengthOf(code, bci);
+                    Block b1 = makeBlock(target);
+                    setSuccessors(bci, b1);
+                    canTrap.set(bci);
+                    break;
+                }
+                default: {
+                    if (canTrap(opcode, bci, profilingInfo)) {
+                        canTrap.set(bci);
+                    }
+                }
+            }
+            bci += lengthOf(code, bci);
+        }
+    }
+
+    private static boolean canTrap(int opcode, int bci, RiProfilingInfo profilingInfo) {
+        switch (opcode) {
+            case IASTORE:
+            case LASTORE:
+            case FASTORE:
+            case DASTORE:
+            case AASTORE:
+            case BASTORE:
+            case CASTORE:
+            case SASTORE:
+            case IALOAD:
+            case LALOAD:
+            case FALOAD:
+            case DALOAD:
+            case AALOAD:
+            case BALOAD:
+            case CALOAD:
+            case SALOAD:
+            case PUTFIELD:
+            case GETFIELD: {
+                if (GraalOptions.AllowExplicitExceptionChecks) {
+                    return profilingInfo.getExceptionSeen(bci) != RiExceptionSeen.FALSE;
+                }
+            }
+        }
+        return false;
+    }
+
+    private Block makeBlock(int startBci) {
+        Block oldBlock = blockMap[startBci];
+        if (oldBlock == null) {
+            Block newBlock = new Block();
+            newBlock.startBci = startBci;
+            blockMap[startBci] = newBlock;
+            return newBlock;
+
+        } else if (oldBlock.startBci != startBci) {
+            // Backward branch into the middle of an already processed block.
+            // Add the correct fall-through successor.
+            Block newBlock = new Block();
+            newBlock.startBci = startBci;
+            newBlock.endBci = oldBlock.endBci;
+            newBlock.successors.addAll(oldBlock.successors);
+            newBlock.normalSuccessors = oldBlock.normalSuccessors;
+
+            oldBlock.endBci = startBci - 1;
+            oldBlock.successors.clear();
+            oldBlock.successors.add(newBlock);
+            oldBlock.normalSuccessors = 1;
+
+            for (int i = startBci; i <= newBlock.endBci; i++) {
+                blockMap[i] = newBlock;
+            }
+            return newBlock;
+
+        } else {
+            return oldBlock;
+        }
+    }
+
+    private Block[] makeSwitchSuccessors(BytecodeSwitch tswitch) {
+        int max = tswitch.numberOfCases();
+        Block[] successors = new Block[max + 1];
+        for (int i = 0; i < max; i++) {
+            successors[i] = makeBlock(tswitch.targetAt(i));
+        }
+        successors[max] = makeBlock(tswitch.defaultTarget());
+        return successors;
+    }
+
+    private void setSuccessors(int predBci, Block... successors) {
+        Block predecessor = blockMap[predBci];
+        assert predecessor.successors.size() == 0;
+        for (Block sux : successors) {
+            if (sux.isExceptionEntry) {
+                throw new CiBailout("Exception handler can be reached by both normal and exceptional control flow");
+            }
+            predecessor.successors.add(sux);
+        }
+        predecessor.normalSuccessors = successors.length;
+    }
+
+    private final HashSet<Block> jsrVisited = new HashSet<>();
+
+    private void createJsrAlternatives(Block block) {
+        jsrVisited.add(block);
+        JsrScope scope = block.jsrScope;
+
+        if (block.endsWithRet) {
+            block.retSuccessor = blockMap[scope.nextReturnAddress()];
+            block.successors.add(block.retSuccessor);
+            assert block.retSuccessor != block.jsrSuccessor;
+        }
+
+        if (block.jsrSuccessor != null || !scope.isEmpty()) {
+            for (int i = 0; i < block.successors.size(); i++) {
+                Block successor = block.successors.get(i);
+                JsrScope nextScope = scope;
+                if (successor == block.jsrSuccessor) {
+                    nextScope = scope.push(block.jsrReturnBci);
+                }
+                if (successor == block.retSuccessor) {
+                    nextScope = scope.pop();
+                }
+                if (!successor.jsrScope.isEmpty()) {
+                    throw new JsrNotSupportedBailout("unstructured control flow  (" + successor.jsrScope + " " + nextScope + ")");
+                }
+                if (!nextScope.isEmpty()) {
+                    Block clone;
+                    if (successor.jsrAlternatives != null && successor.jsrAlternatives.containsKey(nextScope)) {
+                        clone = successor.jsrAlternatives.get(nextScope);
+                    } else {
+                        if (successor.jsrAlternatives == null) {
+                            successor.jsrAlternatives = new HashMap<>();
+                        }
+                        clone = successor.copy();
+                        clone.jsrScope = nextScope;
+                        successor.jsrAlternatives.put(nextScope, clone);
+                    }
+                    block.successors.set(i, clone);
+                    if (successor == block.jsrSuccessor) {
+                        block.jsrSuccessor = clone;
+                    }
+                    if (successor == block.retSuccessor) {
+                        block.retSuccessor = clone;
+                    }
+                }
+            }
+        }
+        for (Block successor : block.successors) {
+            if (!jsrVisited.contains(successor)) {
+                createJsrAlternatives(successor);
+            }
+        }
+    }
+
+    private HashMap<RiExceptionHandler, ExceptionBlock> exceptionDispatch = new HashMap<>();
+
+    private Block makeExceptionDispatch(List<RiExceptionHandler> handlers, int index, int bci) {
+        RiExceptionHandler handler = handlers.get(index);
+        if (handler.isCatchAll()) {
+            return blockMap[handler.handlerBCI()];
+        }
+        ExceptionBlock block = exceptionDispatch.get(handler);
+        if (block == null) {
+            block = new ExceptionBlock();
+            block.startBci = -1;
+            block.endBci = -1;
+            block.deoptBci = bci;
+            block.handler = handler;
+            block.successors.add(blockMap[handler.handlerBCI()]);
+            if (index < handlers.size() - 1) {
+                block.successors.add(makeExceptionDispatch(handlers, index + 1, bci));
+            }
+            exceptionDispatch.put(handler, block);
+        }
+        return block;
+    }
+
+    private void addExceptionEdges() {
+        for (int bci = canTrap.nextSetBit(0); bci >= 0; bci = canTrap.nextSetBit(bci + 1)) {
+            Block block = blockMap[bci];
+
+            ArrayList<RiExceptionHandler> handlers = null;
+            for (RiExceptionHandler h : this.exceptionHandlers) {
+                if (h.startBCI() <= bci && bci < h.endBCI()) {
+                    if (handlers == null) {
+                        handlers = new ArrayList<>();
+                    }
+                    handlers.add(h);
+                    if (h.isCatchAll()) {
+                        break;
+                    }
+                }
+            }
+            if (handlers != null) {
+                Block dispatch = makeExceptionDispatch(handlers, 0, bci);
+                block.successors.add(dispatch);
+            }
+        }
+    }
+
+    private void computeBlockOrder() {
+        long loop = computeBlockOrder(blockMap[0]);
+
+        if (loop != 0) {
+            // There is a path from a loop end to the method entry that does not pass the loop header.
+            // Therefore, the loop is non reducible (has more than one entry).
+            // We don't want to compile such methods because the IR only supports structured loops.
+            throw new CiBailout("Non-reducible loop");
+        }
+
+        // Convert postorder to the desired reverse postorder.
+        Collections.reverse(blocks);
+    }
+
+    /**
+     * The next available loop number.
+     */
+    private int nextLoop;
+
+    /**
+     * Mark the block as a loop header, using the next available loop number.
+     * Also checks for corner cases that we don't want to compile.
+     */
+    private void makeLoopHeader(Block block) {
+        if (!block.isLoopHeader) {
+            block.isLoopHeader = true;
+
+            if (block.isExceptionEntry) {
+                // Loops that are implicitly formed by an exception handler lead to all sorts of corner cases.
+                // Don't compile such methods for now, until we see a concrete case that allows checking for correctness.
+                throw new CiBailout("Loop formed by an exception handler");
+            }
+            if (nextLoop >= Long.SIZE) {
+                // This restriction can be removed by using a fall-back to a BitSet in case we have more than 64 loops
+                // Don't compile such methods for now, until we see a concrete case that allows checking for correctness.
+                throw new CiBailout("Too many loops in method");
+            }
+
+            assert block.loops == 0;
+            block.loops = (long) 1 << (long) nextLoop;
+            nextLoop++;
+        }
+        assert Long.bitCount(block.loops) == 1;
+    }
+
+    /**
+     * Depth-first traversal of the control flow graph. The flag {@linkplain Block#visited} is used to
+     * visit every block only once. The flag {@linkplain Block#active} is used to detect cycles (backward
+     * edges).
+     */
+    private long computeBlockOrder(Block block) {
+        if (block.visited) {
+            if (block.active) {
+                // Reached block via backward branch.
+                makeLoopHeader(block);
+            }
+            // Return cached loop information for this block.
+            return block.loops;
+        }
+
+        block.visited = true;
+        block.active = true;
+
+        int loops = 0;
+        for (Block successor : block.successors) {
+            // Recursively process successors.
+            loops |= computeBlockOrder(successor);
+        }
+
+        if (block.isLoopHeader) {
+            assert Long.bitCount(block.loops) == 1;
+            loops &= ~block.loops;
+        }
+
+        block.loops = loops;
+        block.active = false;
+        blocks.add(block);
+
+        return loops;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BytecodeLookupSwitch.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.java;
+
+/**
+ * A utility for processing {@link Bytecodes#LOOKUPSWITCH} bytecodes.
+ */
+class BytecodeLookupSwitch extends BytecodeSwitch {
+    private static final int OFFSET_TO_NUMBER_PAIRS = 4;
+    private static final int OFFSET_TO_FIRST_PAIR_MATCH = 8;
+    private static final int OFFSET_TO_FIRST_PAIR_OFFSET = 12;
+    private static final int PAIR_SIZE = 8;
+
+    /**
+     * Constructor for a {@link BytecodeStream}.
+     * @param stream the {@code BytecodeStream} containing the switch instruction
+     * @param bci the index in the stream of the switch instruction
+     */
+    public BytecodeLookupSwitch(BytecodeStream stream, int bci) {
+        super(stream, bci);
+    }
+
+    /**
+     * Constructor for a bytecode array.
+     * @param code the bytecode array containing the switch instruction.
+     * @param bci the index in the array of the switch instruction
+     */
+    public BytecodeLookupSwitch(byte[] code, int bci) {
+        super(code, bci);
+    }
+
+    @Override
+    public int defaultOffset() {
+        return readWord(alignedBci);
+    }
+
+    @Override
+    public int offsetAt(int i) {
+        return readWord(alignedBci + OFFSET_TO_FIRST_PAIR_OFFSET + PAIR_SIZE * i);
+    }
+
+    @Override
+    public int keyAt(int i) {
+        return readWord(alignedBci + OFFSET_TO_FIRST_PAIR_MATCH + PAIR_SIZE * i);
+    }
+
+    @Override
+    public int numberOfCases() {
+        return readWord(alignedBci + OFFSET_TO_NUMBER_PAIRS);
+    }
+
+    @Override
+    public int size() {
+        return alignedBci + OFFSET_TO_FIRST_PAIR_MATCH + PAIR_SIZE * numberOfCases() - bci;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BytecodeStream.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.java;
+
+/**
+ * A utility class that makes iterating over bytecodes and reading operands
+ * simpler and less error prone. For example, it handles the {@link Bytecodes#WIDE} instruction
+ * and wide variants of instructions internally.
+ */
+public final class BytecodeStream {
+
+    private final byte[] code;
+    private int opcode;
+    private int curBCI;
+    private int nextBCI;
+
+    /**
+     * Creates a new {@code BytecodeStream} for the specified bytecode.
+     * @param code the array of bytes that contains the bytecode
+     */
+    public BytecodeStream(byte[] code) {
+        assert code != null;
+        this.code = code;
+        setBCI(0);
+    }
+
+    /**
+     * Advances to the next bytecode.
+     */
+    public void next() {
+        setBCI(nextBCI);
+    }
+
+    /**
+     * Gets the next bytecode index (no side-effects).
+     * @return the next bytecode index
+     */
+    public int nextBCI() {
+        return nextBCI;
+    }
+
+    /**
+     * Gets the current bytecode index.
+     * @return the current bytecode index
+     */
+    public int currentBCI() {
+        return curBCI;
+    }
+
+    /**
+     * Gets the bytecode index of the end of the code.
+     * @return the index of the end of the code
+     */
+    public int endBCI() {
+        return code.length;
+    }
+
+    /**
+     * Gets the current opcode. This method will never return the
+     * {@link Bytecodes#WIDE WIDE} opcode, but will instead
+     * return the opcode that is modified by the {@code WIDE} opcode.
+     * @return the current opcode; {@link Bytecodes#END} if at or beyond the end of the code
+     */
+    public int currentBC() {
+        if (opcode == Bytecodes.WIDE) {
+            return Bytes.beU1(code, curBCI + 1);
+        } else {
+            return opcode;
+        }
+    }
+
+    /**
+     * Reads the index of a local variable for one of the load or store instructions.
+     * The WIDE modifier is handled internally.
+     * @return the index of the local variable
+     */
+    public int readLocalIndex() {
+        // read local variable index for load/store
+        if (opcode == Bytecodes.WIDE) {
+            return Bytes.beU2(code, curBCI + 2);
+        }
+        return Bytes.beU1(code, curBCI + 1);
+    }
+
+    /**
+     * Read the delta for an {@link Bytecodes#IINC} bytecode.
+     * @return the delta for the {@code IINC}
+     */
+    public int readIncrement() {
+        // read the delta for the iinc bytecode
+        if (opcode == Bytecodes.WIDE) {
+            return Bytes.beS2(code, curBCI + 4);
+        }
+        return Bytes.beS1(code, curBCI + 2);
+    }
+
+    /**
+     * Read the destination of a {@link Bytecodes#GOTO} or {@code IF} instructions.
+     * @return the destination bytecode index
+     */
+    public int readBranchDest() {
+        // reads the destination for a branch bytecode
+        return curBCI + Bytes.beS2(code, curBCI + 1);
+    }
+
+    /**
+     * Read the destination of a {@link Bytecodes#GOTO_W} or {@link Bytecodes#JSR_W} instructions.
+     * @return the destination bytecode index
+     */
+    public int readFarBranchDest() {
+        // reads the destination for a wide branch bytecode
+        return curBCI + Bytes.beS4(code, curBCI + 1);
+    }
+
+    /**
+     * Read a signed 4-byte integer from the bytecode stream at the specified bytecode index.
+     * @param bci the bytecode index
+     * @return the integer value
+     */
+    public int readInt(int bci) {
+        // reads a 4-byte signed value
+        return Bytes.beS4(code, bci);
+    }
+
+    /**
+     * Reads an unsigned, 1-byte value from the bytecode stream at the specified bytecode index.
+     * @param bci the bytecode index
+     * @return the byte
+     */
+    public int readUByte(int bci) {
+        return Bytes.beU1(code, bci);
+    }
+
+    /**
+     * Reads a constant pool index for the current instruction.
+     * @return the constant pool index
+     */
+    public char readCPI() {
+        if (opcode == Bytecodes.LDC) {
+            return (char) Bytes.beU1(code, curBCI + 1);
+        }
+        return (char) Bytes.beU2(code, curBCI + 1);
+    }
+
+    /**
+     * Reads a signed, 1-byte value for the current instruction (e.g. BIPUSH).
+     * @return the byte
+     */
+    public byte readByte() {
+        return code[curBCI + 1];
+    }
+
+    /**
+     * Reads a signed, 2-byte short for the current instruction (e.g. SIPUSH).
+     * @return the short value
+     */
+    public short readShort() {
+        return (short) Bytes.beS2(code, curBCI + 1);
+    }
+
+    /**
+     * Sets the bytecode index to the specified value.
+     * If {@code bci} is beyond the end of the array, {@link #currentBC} will return
+     * {@link Bytecodes#END} and other methods may throw {@link ArrayIndexOutOfBoundsException}.
+     * @param bci the new bytecode index
+     */
+    public void setBCI(int bci) {
+        curBCI = bci;
+        if (curBCI < code.length) {
+            opcode = Bytes.beU1(code, bci);
+            nextBCI = bci + Bytecodes.lengthOf(code, bci);
+        } else {
+            opcode = Bytecodes.END;
+            nextBCI = curBCI;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BytecodeSwitch.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.java;
+
+/**
+ * An abstract class that provides the state and methods common to {@link Bytecodes#LOOKUPSWITCH}
+ * and {@link Bytecodes#TABLESWITCH} instructions.
+ */
+public abstract class BytecodeSwitch {
+    /**
+     * The {@link BytecodeStream} containing bytecode array or {@code null} if {@link #code} is not {@code null}.
+     */
+    private final BytecodeStream stream;
+    /**
+     * The bytecode array or {@code null} if {@link #stream} is not {@code null}.
+     */
+    private final byte[] code;
+    /**
+     * Index of start of switch instruction.
+     */
+    protected final int bci;
+    /**
+     * Index of the start of the additional data for the switch instruction, aligned to a multiple of four from the method start.
+     */
+    protected final int alignedBci;
+
+    /**
+     * Constructor for a {@link BytecodeStream}.
+     * @param stream the {@code BytecodeStream} containing the switch instruction
+     * @param bci the index in the stream of the switch instruction
+     */
+    public BytecodeSwitch(BytecodeStream stream, int bci) {
+        this.alignedBci = (bci + 4) & 0xfffffffc;
+        this.stream = stream;
+        this.code = null;
+        this.bci = bci;
+    }
+
+    /**
+     * Constructor for a bytecode array.
+     * @param code the bytecode array containing the switch instruction.
+     * @param bci the index in the array of the switch instruction
+     */
+    public BytecodeSwitch(byte[] code, int bci) {
+        this.alignedBci = (bci + 4) & 0xfffffffc;
+        this.stream = null;
+        this.code = code;
+        this.bci = bci;
+    }
+
+    /**
+     * Gets the current bytecode index.
+     * @return the current bytecode index
+     */
+    public int bci() {
+        return bci;
+    }
+
+    /**
+     * Gets the index of the instruction denoted by the {@code i}'th switch target.
+     * @param i index of the switch target
+     * @return the index of the instruction denoted by the {@code i}'th switch target
+     */
+    public int targetAt(int i) {
+        return bci + offsetAt(i);
+    }
+
+    /**
+     * Gets the index of the instruction for the default switch target.
+     * @return the index of the instruction for the default switch target
+     */
+    public int defaultTarget() {
+        return bci + defaultOffset();
+    }
+
+    /**
+     * Gets the offset from the start of the switch instruction to the default switch target.
+     * @return the offset to the default switch target
+     */
+    public abstract int defaultOffset();
+
+    /**
+     * Gets the key at {@code i}'th switch target index.
+     * @param i the switch target index
+     * @return the key at {@code i}'th switch target index
+     */
+    public abstract int keyAt(int i);
+
+    /**
+     * Gets the offset from the start of the switch instruction for the {@code i}'th switch target.
+     * @param i the switch target index
+     * @return the offset to the {@code i}'th switch target
+     */
+    public abstract int offsetAt(int i);
+
+    /**
+     * Gets the number of switch targets.
+     * @return the number of switch targets
+     */
+    public abstract int numberOfCases();
+
+    /**
+     * Gets the total size in bytes of the switch instruction.
+     * @return the total size in bytes of the switch instruction
+     */
+    public abstract int size();
+
+    /**
+     * Reads the signed value at given bytecode index.
+     * @param readBci the start index of the value to retrieve
+     * @return the signed, 4-byte value in the bytecode array starting at {@code bci}
+     */
+    protected int readWord(int readBci) {
+        if (code != null) {
+            return Bytes.beS4(code, readBci);
+        }
+        return stream.readInt(readBci);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BytecodeTableSwitch.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.java;
+
+/**
+ * A utility for processing {@link Bytecodes#TABLESWITCH} bytecodes.
+ */
+public class BytecodeTableSwitch extends BytecodeSwitch {
+    private static final int OFFSET_TO_LOW_KEY = 4;
+    private static final int OFFSET_TO_HIGH_KEY = 8;
+    private static final int OFFSET_TO_FIRST_JUMP_OFFSET = 12;
+    private static final int JUMP_OFFSET_SIZE = 4;
+
+    /**
+     * Constructor for a {@link BytecodeStream}.
+     * @param stream the {@code BytecodeStream} containing the switch instruction
+     * @param bci the index in the stream of the switch instruction
+     */
+    public BytecodeTableSwitch(BytecodeStream stream, int bci) {
+        super(stream, bci);
+    }
+
+    /**
+     * Constructor for a bytecode array.
+     * @param code the bytecode array containing the switch instruction.
+     * @param bci the index in the array of the switch instruction
+     */
+    public BytecodeTableSwitch(byte[] code, int bci) {
+        super(code, bci);
+    }
+
+    /**
+     * Gets the low key of the table switch.
+     * @return the low key
+     */
+    public int lowKey() {
+        return readWord(alignedBci + OFFSET_TO_LOW_KEY);
+    }
+
+    /**
+     * Gets the high key of the table switch.
+     * @return the high key
+     */
+    public int highKey() {
+        return readWord(alignedBci + OFFSET_TO_HIGH_KEY);
+    }
+
+    @Override
+    public int keyAt(int i) {
+        return lowKey() + i;
+    }
+
+    @Override
+    public int defaultOffset() {
+        return readWord(alignedBci);
+    }
+
+    @Override
+    public int offsetAt(int i) {
+        return readWord(alignedBci + OFFSET_TO_FIRST_JUMP_OFFSET + JUMP_OFFSET_SIZE * i);
+    }
+
+    @Override
+    public int numberOfCases() {
+        return highKey() - lowKey() + 1;
+    }
+
+    @Override
+    public int size() {
+        return alignedBci + OFFSET_TO_FIRST_JUMP_OFFSET + JUMP_OFFSET_SIZE * numberOfCases() - bci;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/Bytecodes.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,976 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.java;
+
+import static com.oracle.max.graal.java.Bytecodes.Flags.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.regex.*;
+
+/**
+ * The definitions of the bytecodes that are valid input to the compiler and
+ * related utility methods. This comprises two groups: the standard Java
+ * bytecodes defined by <a href=
+ * "http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html">
+ * Java Virtual Machine Specification</a>, and a set of <i>extended</i>
+ * bytecodes that support low-level programming, for example, memory barriers.
+ *
+ * The extended bytecodes are one or three bytes in size. The one-byte bytecodes
+ * follow the values in the standard set, with no gap. The three-byte extended
+ * bytecodes share a common first byte and carry additional instruction-specific
+ * information in the second and third bytes.
+ */
+public class Bytecodes {
+    public static final int NOP                  =   0; // 0x00
+    public static final int ACONST_NULL          =   1; // 0x01
+    public static final int ICONST_M1            =   2; // 0x02
+    public static final int ICONST_0             =   3; // 0x03
+    public static final int ICONST_1             =   4; // 0x04
+    public static final int ICONST_2             =   5; // 0x05
+    public static final int ICONST_3             =   6; // 0x06
+    public static final int ICONST_4             =   7; // 0x07
+    public static final int ICONST_5             =   8; // 0x08
+    public static final int LCONST_0             =   9; // 0x09
+    public static final int LCONST_1             =  10; // 0x0A
+    public static final int FCONST_0             =  11; // 0x0B
+    public static final int FCONST_1             =  12; // 0x0C
+    public static final int FCONST_2             =  13; // 0x0D
+    public static final int DCONST_0             =  14; // 0x0E
+    public static final int DCONST_1             =  15; // 0x0F
+    public static final int BIPUSH               =  16; // 0x10
+    public static final int SIPUSH               =  17; // 0x11
+    public static final int LDC                  =  18; // 0x12
+    public static final int LDC_W                =  19; // 0x13
+    public static final int LDC2_W               =  20; // 0x14
+    public static final int ILOAD                =  21; // 0x15
+    public static final int LLOAD                =  22; // 0x16
+    public static final int FLOAD                =  23; // 0x17
+    public static final int DLOAD                =  24; // 0x18
+    public static final int ALOAD                =  25; // 0x19
+    public static final int ILOAD_0              =  26; // 0x1A
+    public static final int ILOAD_1              =  27; // 0x1B
+    public static final int ILOAD_2              =  28; // 0x1C
+    public static final int ILOAD_3              =  29; // 0x1D
+    public static final int LLOAD_0              =  30; // 0x1E
+    public static final int LLOAD_1              =  31; // 0x1F
+    public static final int LLOAD_2              =  32; // 0x20
+    public static final int LLOAD_3              =  33; // 0x21
+    public static final int FLOAD_0              =  34; // 0x22
+    public static final int FLOAD_1              =  35; // 0x23
+    public static final int FLOAD_2              =  36; // 0x24
+    public static final int FLOAD_3              =  37; // 0x25
+    public static final int DLOAD_0              =  38; // 0x26
+    public static final int DLOAD_1              =  39; // 0x27
+    public static final int DLOAD_2              =  40; // 0x28
+    public static final int DLOAD_3              =  41; // 0x29
+    public static final int ALOAD_0              =  42; // 0x2A
+    public static final int ALOAD_1              =  43; // 0x2B
+    public static final int ALOAD_2              =  44; // 0x2C
+    public static final int ALOAD_3              =  45; // 0x2D
+    public static final int IALOAD               =  46; // 0x2E
+    public static final int LALOAD               =  47; // 0x2F
+    public static final int FALOAD               =  48; // 0x30
+    public static final int DALOAD               =  49; // 0x31
+    public static final int AALOAD               =  50; // 0x32
+    public static final int BALOAD               =  51; // 0x33
+    public static final int CALOAD               =  52; // 0x34
+    public static final int SALOAD               =  53; // 0x35
+    public static final int ISTORE               =  54; // 0x36
+    public static final int LSTORE               =  55; // 0x37
+    public static final int FSTORE               =  56; // 0x38
+    public static final int DSTORE               =  57; // 0x39
+    public static final int ASTORE               =  58; // 0x3A
+    public static final int ISTORE_0             =  59; // 0x3B
+    public static final int ISTORE_1             =  60; // 0x3C
+    public static final int ISTORE_2             =  61; // 0x3D
+    public static final int ISTORE_3             =  62; // 0x3E
+    public static final int LSTORE_0             =  63; // 0x3F
+    public static final int LSTORE_1             =  64; // 0x40
+    public static final int LSTORE_2             =  65; // 0x41
+    public static final int LSTORE_3             =  66; // 0x42
+    public static final int FSTORE_0             =  67; // 0x43
+    public static final int FSTORE_1             =  68; // 0x44
+    public static final int FSTORE_2             =  69; // 0x45
+    public static final int FSTORE_3             =  70; // 0x46
+    public static final int DSTORE_0             =  71; // 0x47
+    public static final int DSTORE_1             =  72; // 0x48
+    public static final int DSTORE_2             =  73; // 0x49
+    public static final int DSTORE_3             =  74; // 0x4A
+    public static final int ASTORE_0             =  75; // 0x4B
+    public static final int ASTORE_1             =  76; // 0x4C
+    public static final int ASTORE_2             =  77; // 0x4D
+    public static final int ASTORE_3             =  78; // 0x4E
+    public static final int IASTORE              =  79; // 0x4F
+    public static final int LASTORE              =  80; // 0x50
+    public static final int FASTORE              =  81; // 0x51
+    public static final int DASTORE              =  82; // 0x52
+    public static final int AASTORE              =  83; // 0x53
+    public static final int BASTORE              =  84; // 0x54
+    public static final int CASTORE              =  85; // 0x55
+    public static final int SASTORE              =  86; // 0x56
+    public static final int POP                  =  87; // 0x57
+    public static final int POP2                 =  88; // 0x58
+    public static final int DUP                  =  89; // 0x59
+    public static final int DUP_X1               =  90; // 0x5A
+    public static final int DUP_X2               =  91; // 0x5B
+    public static final int DUP2                 =  92; // 0x5C
+    public static final int DUP2_X1              =  93; // 0x5D
+    public static final int DUP2_X2              =  94; // 0x5E
+    public static final int SWAP                 =  95; // 0x5F
+    public static final int IADD                 =  96; // 0x60
+    public static final int LADD                 =  97; // 0x61
+    public static final int FADD                 =  98; // 0x62
+    public static final int DADD                 =  99; // 0x63
+    public static final int ISUB                 = 100; // 0x64
+    public static final int LSUB                 = 101; // 0x65
+    public static final int FSUB                 = 102; // 0x66
+    public static final int DSUB                 = 103; // 0x67
+    public static final int IMUL                 = 104; // 0x68
+    public static final int LMUL                 = 105; // 0x69
+    public static final int FMUL                 = 106; // 0x6A
+    public static final int DMUL                 = 107; // 0x6B
+    public static final int IDIV                 = 108; // 0x6C
+    public static final int LDIV                 = 109; // 0x6D
+    public static final int FDIV                 = 110; // 0x6E
+    public static final int DDIV                 = 111; // 0x6F
+    public static final int IREM                 = 112; // 0x70
+    public static final int LREM                 = 113; // 0x71
+    public static final int FREM                 = 114; // 0x72
+    public static final int DREM                 = 115; // 0x73
+    public static final int INEG                 = 116; // 0x74
+    public static final int LNEG                 = 117; // 0x75
+    public static final int FNEG                 = 118; // 0x76
+    public static final int DNEG                 = 119; // 0x77
+    public static final int ISHL                 = 120; // 0x78
+    public static final int LSHL                 = 121; // 0x79
+    public static final int ISHR                 = 122; // 0x7A
+    public static final int LSHR                 = 123; // 0x7B
+    public static final int IUSHR                = 124; // 0x7C
+    public static final int LUSHR                = 125; // 0x7D
+    public static final int IAND                 = 126; // 0x7E
+    public static final int LAND                 = 127; // 0x7F
+    public static final int IOR                  = 128; // 0x80
+    public static final int LOR                  = 129; // 0x81
+    public static final int IXOR                 = 130; // 0x82
+    public static final int LXOR                 = 131; // 0x83
+    public static final int IINC                 = 132; // 0x84
+    public static final int I2L                  = 133; // 0x85
+    public static final int I2F                  = 134; // 0x86
+    public static final int I2D                  = 135; // 0x87
+    public static final int L2I                  = 136; // 0x88
+    public static final int L2F                  = 137; // 0x89
+    public static final int L2D                  = 138; // 0x8A
+    public static final int F2I                  = 139; // 0x8B
+    public static final int F2L                  = 140; // 0x8C
+    public static final int F2D                  = 141; // 0x8D
+    public static final int D2I                  = 142; // 0x8E
+    public static final int D2L                  = 143; // 0x8F
+    public static final int D2F                  = 144; // 0x90
+    public static final int I2B                  = 145; // 0x91
+    public static final int I2C                  = 146; // 0x92
+    public static final int I2S                  = 147; // 0x93
+    public static final int LCMP                 = 148; // 0x94
+    public static final int FCMPL                = 149; // 0x95
+    public static final int FCMPG                = 150; // 0x96
+    public static final int DCMPL                = 151; // 0x97
+    public static final int DCMPG                = 152; // 0x98
+    public static final int IFEQ                 = 153; // 0x99
+    public static final int IFNE                 = 154; // 0x9A
+    public static final int IFLT                 = 155; // 0x9B
+    public static final int IFGE                 = 156; // 0x9C
+    public static final int IFGT                 = 157; // 0x9D
+    public static final int IFLE                 = 158; // 0x9E
+    public static final int IF_ICMPEQ            = 159; // 0x9F
+    public static final int IF_ICMPNE            = 160; // 0xA0
+    public static final int IF_ICMPLT            = 161; // 0xA1
+    public static final int IF_ICMPGE            = 162; // 0xA2
+    public static final int IF_ICMPGT            = 163; // 0xA3
+    public static final int IF_ICMPLE            = 164; // 0xA4
+    public static final int IF_ACMPEQ            = 165; // 0xA5
+    public static final int IF_ACMPNE            = 166; // 0xA6
+    public static final int GOTO                 = 167; // 0xA7
+    public static final int JSR                  = 168; // 0xA8
+    public static final int RET                  = 169; // 0xA9
+    public static final int TABLESWITCH          = 170; // 0xAA
+    public static final int LOOKUPSWITCH         = 171; // 0xAB
+    public static final int IRETURN              = 172; // 0xAC
+    public static final int LRETURN              = 173; // 0xAD
+    public static final int FRETURN              = 174; // 0xAE
+    public static final int DRETURN              = 175; // 0xAF
+    public static final int ARETURN              = 176; // 0xB0
+    public static final int RETURN               = 177; // 0xB1
+    public static final int GETSTATIC            = 178; // 0xB2
+    public static final int PUTSTATIC            = 179; // 0xB3
+    public static final int GETFIELD             = 180; // 0xB4
+    public static final int PUTFIELD             = 181; // 0xB5
+    public static final int INVOKEVIRTUAL        = 182; // 0xB6
+    public static final int INVOKESPECIAL        = 183; // 0xB7
+    public static final int INVOKESTATIC         = 184; // 0xB8
+    public static final int INVOKEINTERFACE      = 185; // 0xB9
+    public static final int XXXUNUSEDXXX         = 186; // 0xBA
+    public static final int NEW                  = 187; // 0xBB
+    public static final int NEWARRAY             = 188; // 0xBC
+    public static final int ANEWARRAY            = 189; // 0xBD
+    public static final int ARRAYLENGTH          = 190; // 0xBE
+    public static final int ATHROW               = 191; // 0xBF
+    public static final int CHECKCAST            = 192; // 0xC0
+    public static final int INSTANCEOF           = 193; // 0xC1
+    public static final int MONITORENTER         = 194; // 0xC2
+    public static final int MONITOREXIT          = 195; // 0xC3
+    public static final int WIDE                 = 196; // 0xC4
+    public static final int MULTIANEWARRAY       = 197; // 0xC5
+    public static final int IFNULL               = 198; // 0xC6
+    public static final int IFNONNULL            = 199; // 0xC7
+    public static final int GOTO_W               = 200; // 0xC8
+    public static final int JSR_W                = 201; // 0xC9
+    public static final int BREAKPOINT           = 202; // 0xCA
+
+    public static final int ILLEGAL = 255;
+    public static final int END = 256;
+
+    /**
+     * The last opcode defined by the JVM specification. To iterate over all JVM bytecodes:
+     * <pre>
+     *     for (int opcode = 0; opcode <= Bytecodes.LAST_JVM_OPCODE; ++opcode) {
+     *         //
+     *     }
+     * </pre>
+     */
+    public static final int LAST_JVM_OPCODE = JSR_W;
+
+    /**
+     * A collection of flags describing various bytecode attributes.
+     */
+    static class Flags {
+
+        /**
+         * Denotes an instruction that ends a basic block and does not let control flow fall through to its lexical successor.
+         */
+        static final int STOP = 0x00000001;
+
+        /**
+         * Denotes an instruction that ends a basic block and may let control flow fall through to its lexical successor.
+         * In practice this means it is a conditional branch.
+         */
+        static final int FALL_THROUGH = 0x00000002;
+
+        /**
+         * Denotes an instruction that has a 2 or 4 byte operand that is an offset to another instruction in the same method.
+         * This does not include the {@link Bytecodes#TABLESWITCH} or {@link Bytecodes#LOOKUPSWITCH} instructions.
+         */
+        static final int BRANCH = 0x00000004;
+
+        /**
+         * Denotes an instruction that reads the value of a static or instance field.
+         */
+        static final int FIELD_READ = 0x00000008;
+
+        /**
+         * Denotes an instruction that writes the value of a static or instance field.
+         */
+        static final int FIELD_WRITE = 0x00000010;
+
+        /**
+         * Denotes an instruction that is not defined in the JVM specification.
+         */
+        static final int EXTENSION = 0x00000020;
+
+        /**
+         * Denotes an instruction that can cause a trap.
+         */
+        static final int TRAP        = 0x00000080;
+        /**
+         * Denotes an instruction that is commutative.
+         */
+        static final int COMMUTATIVE = 0x00000100;
+        /**
+         * Denotes an instruction that is associative.
+         */
+        static final int ASSOCIATIVE = 0x00000200;
+        /**
+         * Denotes an instruction that loads an operand.
+         */
+        static final int LOAD        = 0x00000400;
+        /**
+         * Denotes an instruction that stores an operand.
+         */
+        static final int STORE       = 0x00000800;
+        /**
+         * Denotes the 4 INVOKE* instructions.
+         */
+        static final int INVOKE       = 0x00001000;
+    }
+
+    // Performs a sanity check that none of the flags overlap.
+    static {
+        int allFlags = 0;
+        try {
+            for (Field field : Flags.class.getDeclaredFields()) {
+                int flagsFilter = Modifier.FINAL | Modifier.STATIC;
+                if ((field.getModifiers() & flagsFilter) == flagsFilter && !field.isSynthetic()) {
+                    assert field.getType() == int.class : "Field is not int : " + field;
+                    final int flag = field.getInt(null);
+                    assert flag != 0;
+                    assert (flag & allFlags) == 0 : field.getName() + " has a value conflicting with another flag";
+                    allFlags |= flag;
+                }
+            }
+        } catch (Exception e) {
+            throw new InternalError(e.toString());
+        }
+    }
+
+    /**
+     * An array that maps from a bytecode value to a {@link String} for the corresponding instruction mnemonic.
+     * This will include the root instruction for the three-byte extended instructions.
+     */
+    private static final String[] nameArray = new String[256];
+
+    /**
+     * An array that maps from a bytecode value to the set of {@link Flags} for the corresponding instruction.
+     */
+    private static final int[] flagsArray = new int[256];
+
+    /**
+     * An array that maps from a bytecode value to the length in bytes for the corresponding instruction.
+     */
+    private static final int[] lengthArray = new int[256];
+
+    /**
+     * An array that maps from a bytecode value to the estimated complexity of the bytecode in terms of generated machine code.
+     */
+    private static final int[] compilationComplexityArray = new int[256];
+
+    // Checkstyle: stop
+    static {
+        def(NOP                 , "nop"             , "b"    , 0);
+        def(ACONST_NULL         , "aconst_null"     , "b"    , 0);
+        def(ICONST_M1           , "iconst_m1"       , "b"    , 0);
+        def(ICONST_0            , "iconst_0"        , "b"    , 0);
+        def(ICONST_1            , "iconst_1"        , "b"    , 0);
+        def(ICONST_2            , "iconst_2"        , "b"    , 0);
+        def(ICONST_3            , "iconst_3"        , "b"    , 0);
+        def(ICONST_4            , "iconst_4"        , "b"    , 0);
+        def(ICONST_5            , "iconst_5"        , "b"    , 0);
+        def(LCONST_0            , "lconst_0"        , "b"    , 0);
+        def(LCONST_1            , "lconst_1"        , "b"    , 0);
+        def(FCONST_0            , "fconst_0"        , "b"    , 0);
+        def(FCONST_1            , "fconst_1"        , "b"    , 0);
+        def(FCONST_2            , "fconst_2"        , "b"    , 0);
+        def(DCONST_0            , "dconst_0"        , "b"    , 0);
+        def(DCONST_1            , "dconst_1"        , "b"    , 0);
+        def(BIPUSH              , "bipush"          , "bc"   , 0);
+        def(SIPUSH              , "sipush"          , "bcc"  , 0);
+        def(LDC                 , "ldc"             , "bi"   , 0, TRAP);
+        def(LDC_W               , "ldc_w"           , "bii"  , 0, TRAP);
+        def(LDC2_W              , "ldc2_w"          , "bii"  , 0, TRAP);
+        def(ILOAD               , "iload"           , "bi"   , 0, LOAD);
+        def(LLOAD               , "lload"           , "bi"   , 0, LOAD);
+        def(FLOAD               , "fload"           , "bi"   , 0, LOAD);
+        def(DLOAD               , "dload"           , "bi"   , 0, LOAD);
+        def(ALOAD               , "aload"           , "bi"   , 0, LOAD);
+        def(ILOAD_0             , "iload_0"         , "b"    , 0, LOAD);
+        def(ILOAD_1             , "iload_1"         , "b"    , 0, LOAD);
+        def(ILOAD_2             , "iload_2"         , "b"    , 0, LOAD);
+        def(ILOAD_3             , "iload_3"         , "b"    , 0, LOAD);
+        def(LLOAD_0             , "lload_0"         , "b"    , 0, LOAD);
+        def(LLOAD_1             , "lload_1"         , "b"    , 0, LOAD);
+        def(LLOAD_2             , "lload_2"         , "b"    , 0, LOAD);
+        def(LLOAD_3             , "lload_3"         , "b"    , 0, LOAD);
+        def(FLOAD_0             , "fload_0"         , "b"    , 0, LOAD);
+        def(FLOAD_1             , "fload_1"         , "b"    , 0, LOAD);
+        def(FLOAD_2             , "fload_2"         , "b"    , 0, LOAD);
+        def(FLOAD_3             , "fload_3"         , "b"    , 0, LOAD);
+        def(DLOAD_0             , "dload_0"         , "b"    , 0, LOAD);
+        def(DLOAD_1             , "dload_1"         , "b"    , 0, LOAD);
+        def(DLOAD_2             , "dload_2"         , "b"    , 0, LOAD);
+        def(DLOAD_3             , "dload_3"         , "b"    , 0, LOAD);
+        def(ALOAD_0             , "aload_0"         , "b"    , 0, LOAD);
+        def(ALOAD_1             , "aload_1"         , "b"    , 0, LOAD);
+        def(ALOAD_2             , "aload_2"         , "b"    , 0, LOAD);
+        def(ALOAD_3             , "aload_3"         , "b"    , 0, LOAD);
+        def(IALOAD              , "iaload"          , "b"    , 0, TRAP);
+        def(LALOAD              , "laload"          , "b"    , 0, TRAP);
+        def(FALOAD              , "faload"          , "b"    , 0, TRAP);
+        def(DALOAD              , "daload"          , "b"    , 0, TRAP);
+        def(AALOAD              , "aaload"          , "b"    , 0, TRAP);
+        def(BALOAD              , "baload"          , "b"    , 0, TRAP);
+        def(CALOAD              , "caload"          , "b"    , 0, TRAP);
+        def(SALOAD              , "saload"          , "b"    , 0, TRAP);
+        def(ISTORE              , "istore"          , "bi"   , 0, STORE);
+        def(LSTORE              , "lstore"          , "bi"   , 0, STORE);
+        def(FSTORE              , "fstore"          , "bi"   , 0, STORE);
+        def(DSTORE              , "dstore"          , "bi"   , 0, STORE);
+        def(ASTORE              , "astore"          , "bi"   , 0, STORE);
+        def(ISTORE_0            , "istore_0"        , "b"    , 0, STORE);
+        def(ISTORE_1            , "istore_1"        , "b"    , 0, STORE);
+        def(ISTORE_2            , "istore_2"        , "b"    , 0, STORE);
+        def(ISTORE_3            , "istore_3"        , "b"    , 0, STORE);
+        def(LSTORE_0            , "lstore_0"        , "b"    , 0, STORE);
+        def(LSTORE_1            , "lstore_1"        , "b"    , 0, STORE);
+        def(LSTORE_2            , "lstore_2"        , "b"    , 0, STORE);
+        def(LSTORE_3            , "lstore_3"        , "b"    , 0, STORE);
+        def(FSTORE_0            , "fstore_0"        , "b"    , 0, STORE);
+        def(FSTORE_1            , "fstore_1"        , "b"    , 0, STORE);
+        def(FSTORE_2            , "fstore_2"        , "b"    , 0, STORE);
+        def(FSTORE_3            , "fstore_3"        , "b"    , 0, STORE);
+        def(DSTORE_0            , "dstore_0"        , "b"    , 0, STORE);
+        def(DSTORE_1            , "dstore_1"        , "b"    , 0, STORE);
+        def(DSTORE_2            , "dstore_2"        , "b"    , 0, STORE);
+        def(DSTORE_3            , "dstore_3"        , "b"    , 0, STORE);
+        def(ASTORE_0            , "astore_0"        , "b"    , 0, STORE);
+        def(ASTORE_1            , "astore_1"        , "b"    , 0, STORE);
+        def(ASTORE_2            , "astore_2"        , "b"    , 0, STORE);
+        def(ASTORE_3            , "astore_3"        , "b"    , 0, STORE);
+        def(IASTORE             , "iastore"         , "b"    , 3, TRAP);
+        def(LASTORE             , "lastore"         , "b"    , 3, TRAP);
+        def(FASTORE             , "fastore"         , "b"    , 3, TRAP);
+        def(DASTORE             , "dastore"         , "b"    , 3, TRAP);
+        def(AASTORE             , "aastore"         , "b"    , 4, TRAP);
+        def(BASTORE             , "bastore"         , "b"    , 3, TRAP);
+        def(CASTORE             , "castore"         , "b"    , 3, TRAP);
+        def(SASTORE             , "sastore"         , "b"    , 3, TRAP);
+        def(POP                 , "pop"             , "b"    , 0);
+        def(POP2                , "pop2"            , "b"    , 0);
+        def(DUP                 , "dup"             , "b"    , 0);
+        def(DUP_X1              , "dup_x1"          , "b"    , 0);
+        def(DUP_X2              , "dup_x2"          , "b"    , 0);
+        def(DUP2                , "dup2"            , "b"    , 0);
+        def(DUP2_X1             , "dup2_x1"         , "b"    , 0);
+        def(DUP2_X2             , "dup2_x2"         , "b"    , 0);
+        def(SWAP                , "swap"            , "b"    , 0);
+        def(IADD                , "iadd"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(LADD                , "ladd"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(FADD                , "fadd"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(DADD                , "dadd"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(ISUB                , "isub"            , "b"    , 1);
+        def(LSUB                , "lsub"            , "b"    , 1);
+        def(FSUB                , "fsub"            , "b"    , 1);
+        def(DSUB                , "dsub"            , "b"    , 1);
+        def(IMUL                , "imul"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(LMUL                , "lmul"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(FMUL                , "fmul"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(DMUL                , "dmul"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(IDIV                , "idiv"            , "b"    , 1, TRAP);
+        def(LDIV                , "ldiv"            , "b"    , 1, TRAP);
+        def(FDIV                , "fdiv"            , "b"    , 1);
+        def(DDIV                , "ddiv"            , "b"    , 1);
+        def(IREM                , "irem"            , "b"    , 1, TRAP);
+        def(LREM                , "lrem"            , "b"    , 1, TRAP);
+        def(FREM                , "frem"            , "b"    , 1);
+        def(DREM                , "drem"            , "b"    , 1);
+        def(INEG                , "ineg"            , "b"    , 1);
+        def(LNEG                , "lneg"            , "b"    , 1);
+        def(FNEG                , "fneg"            , "b"    , 1);
+        def(DNEG                , "dneg"            , "b"    , 1);
+        def(ISHL                , "ishl"            , "b"    , 1);
+        def(LSHL                , "lshl"            , "b"    , 1);
+        def(ISHR                , "ishr"            , "b"    , 1);
+        def(LSHR                , "lshr"            , "b"    , 1);
+        def(IUSHR               , "iushr"           , "b"    , 1);
+        def(LUSHR               , "lushr"           , "b"    , 1);
+        def(IAND                , "iand"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(LAND                , "land"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(IOR                 , "ior"             , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(LOR                 , "lor"             , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(IXOR                , "ixor"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(LXOR                , "lxor"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(IINC                , "iinc"            , "bic"  , 1, LOAD | STORE);
+        def(I2L                 , "i2l"             , "b"    , 1);
+        def(I2F                 , "i2f"             , "b"    , 1);
+        def(I2D                 , "i2d"             , "b"    , 1);
+        def(L2I                 , "l2i"             , "b"    , 1);
+        def(L2F                 , "l2f"             , "b"    , 1);
+        def(L2D                 , "l2d"             , "b"    , 1);
+        def(F2I                 , "f2i"             , "b"    , 1);
+        def(F2L                 , "f2l"             , "b"    , 1);
+        def(F2D                 , "f2d"             , "b"    , 1);
+        def(D2I                 , "d2i"             , "b"    , 1);
+        def(D2L                 , "d2l"             , "b"    , 1);
+        def(D2F                 , "d2f"             , "b"    , 1);
+        def(I2B                 , "i2b"             , "b"    , 1);
+        def(I2C                 , "i2c"             , "b"    , 1);
+        def(I2S                 , "i2s"             , "b"    , 1);
+        def(LCMP                , "lcmp"            , "b"    , 1);
+        def(FCMPL               , "fcmpl"           , "b"    , 1);
+        def(FCMPG               , "fcmpg"           , "b"    , 1);
+        def(DCMPL               , "dcmpl"           , "b"    , 1);
+        def(DCMPG               , "dcmpg"           , "b"    , 1);
+        def(IFEQ                , "ifeq"            , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IFNE                , "ifne"            , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IFLT                , "iflt"            , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IFGE                , "ifge"            , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IFGT                , "ifgt"            , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IFLE                , "ifle"            , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IF_ICMPEQ           , "if_icmpeq"       , "boo"  , 2, COMMUTATIVE | FALL_THROUGH | BRANCH);
+        def(IF_ICMPNE           , "if_icmpne"       , "boo"  , 2, COMMUTATIVE | FALL_THROUGH | BRANCH);
+        def(IF_ICMPLT           , "if_icmplt"       , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IF_ICMPGE           , "if_icmpge"       , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IF_ICMPGT           , "if_icmpgt"       , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IF_ICMPLE           , "if_icmple"       , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IF_ACMPEQ           , "if_acmpeq"       , "boo"  , 2, COMMUTATIVE | FALL_THROUGH | BRANCH);
+        def(IF_ACMPNE           , "if_acmpne"       , "boo"  , 2, COMMUTATIVE | FALL_THROUGH | BRANCH);
+        def(GOTO                , "goto"            , "boo"  , 1, STOP | BRANCH);
+        def(JSR                 , "jsr"             , "boo"  , 0, STOP | BRANCH);
+        def(RET                 , "ret"             , "bi"   , 0, STOP);
+        def(TABLESWITCH         , "tableswitch"     , ""     , 4, STOP);
+        def(LOOKUPSWITCH        , "lookupswitch"    , ""     , 4, STOP);
+        def(IRETURN             , "ireturn"         , "b"    , 1, TRAP | STOP);
+        def(LRETURN             , "lreturn"         , "b"    , 1, TRAP | STOP);
+        def(FRETURN             , "freturn"         , "b"    , 1, TRAP | STOP);
+        def(DRETURN             , "dreturn"         , "b"    , 1, TRAP | STOP);
+        def(ARETURN             , "areturn"         , "b"    , 1, TRAP | STOP);
+        def(RETURN              , "return"          , "b"    , 1, TRAP | STOP);
+        def(GETSTATIC           , "getstatic"       , "bjj"  , 2, TRAP | FIELD_READ);
+        def(PUTSTATIC           , "putstatic"       , "bjj"  , 2, TRAP | FIELD_WRITE);
+        def(GETFIELD            , "getfield"        , "bjj"  , 2, TRAP | FIELD_READ);
+        def(PUTFIELD            , "putfield"        , "bjj"  , 2, TRAP | FIELD_WRITE);
+        def(INVOKEVIRTUAL       , "invokevirtual"   , "bjj"  , 7, TRAP | INVOKE);
+        def(INVOKESPECIAL       , "invokespecial"   , "bjj"  , 5, TRAP | INVOKE);
+        def(INVOKESTATIC        , "invokestatic"    , "bjj"  , 5, TRAP | INVOKE);
+        def(INVOKEINTERFACE     , "invokeinterface" , "bjja_", 7, TRAP | INVOKE);
+        def(XXXUNUSEDXXX        , "xxxunusedxxx"    , ""     , 0);
+        def(NEW                 , "new"             , "bii"  , 6, TRAP);
+        def(NEWARRAY            , "newarray"        , "bc"   , 6, TRAP);
+        def(ANEWARRAY           , "anewarray"       , "bii"  , 6, TRAP);
+        def(ARRAYLENGTH         , "arraylength"     , "b"    , 2, TRAP);
+        def(ATHROW              , "athrow"          , "b"    , 5, TRAP | STOP);
+        def(CHECKCAST           , "checkcast"       , "bii"  , 3, TRAP);
+        def(INSTANCEOF          , "instanceof"      , "bii"  , 4, TRAP);
+        def(MONITORENTER        , "monitorenter"    , "b"    , 5, TRAP);
+        def(MONITOREXIT         , "monitorexit"     , "b"    , 5, TRAP);
+        def(WIDE                , "wide"            , ""     , 0);
+        def(MULTIANEWARRAY      , "multianewarray"  , "biic" , 6, TRAP);
+        def(IFNULL              , "ifnull"          , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IFNONNULL           , "ifnonnull"       , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(GOTO_W              , "goto_w"          , "boooo", 1, STOP | BRANCH);
+        def(JSR_W               , "jsr_w"           , "boooo", 0, STOP | BRANCH);
+        def(BREAKPOINT          , "breakpoint"      , "b"    , 0, TRAP);
+    }
+    // Checkstyle: resume
+
+    /**
+     * Determines if an opcode is commutative.
+     * @param opcode the opcode to check
+     * @return {@code true} iff commutative
+     */
+    public static boolean isCommutative(int opcode) {
+        return (flagsArray[opcode & 0xff] & COMMUTATIVE) != 0;
+    }
+
+    /**
+     * Gets the length of an instruction denoted by a given opcode.
+     *
+     * @param opcode an instruction opcode
+     * @return the length of the instruction denoted by {@code opcode}. If {@code opcode} is an illegal instruction or denotes a
+     *         variable length instruction (e.g. {@link #TABLESWITCH}), then 0 is returned.
+     */
+    public static int lengthOf(int opcode) {
+        return lengthArray[opcode & 0xff];
+    }
+
+    /**
+     * Gets the length of an instruction at a given position in a given bytecode array.
+     * This methods handles variable length and {@linkplain #WIDE widened} instructions.
+     *
+     * @param code an array of bytecode
+     * @param bci the position in {@code code} of an instruction's opcode
+     * @return the length of the instruction at position {@code bci} in {@code code}
+     */
+    public static int lengthOf(byte[] code, int bci) {
+        int opcode = Bytes.beU1(code, bci);
+        int length = Bytecodes.lengthArray[opcode & 0xff];
+        if (length == 0) {
+            switch (opcode) {
+                case TABLESWITCH: {
+                    return new BytecodeTableSwitch(code, bci).size();
+                }
+                case LOOKUPSWITCH: {
+                    return new BytecodeLookupSwitch(code, bci).size();
+                }
+                case WIDE: {
+                    int opc = Bytes.beU1(code, bci + 1);
+                    if (opc == RET) {
+                        return 4;
+                    } else if (opc == IINC) {
+                        return 6;
+                    } else {
+                        return 4; // a load or store bytecode
+                    }
+                }
+                default:
+                    throw new Error("unknown variable-length bytecode: " + opcode);
+            }
+        }
+        return length;
+    }
+
+    /**
+     * Gets the compilation complexity for a given opcode.
+     * @param opcode an opcode
+     * @return a value >= 0
+     */
+    public static int compilationComplexity(int opcode) {
+        return compilationComplexityArray[opcode & 0xff];
+    }
+
+    /**
+     * Gets the lower-case mnemonic for a given opcode.
+     *
+     * @param opcode an opcode
+     * @return the mnemonic for {@code opcode} or {@code "<illegal opcode: " + opcode + ">"} if {@code opcode} is not a legal opcode
+     */
+    public static String nameOf(int opcode) throws IllegalArgumentException {
+        String name = nameArray[opcode & 0xff];
+        if (name == null) {
+            return "<illegal opcode: " + opcode + ">";
+        }
+        return name;
+    }
+
+    /**
+     * Allocation-free version of {@linkplain #nameOf(int)}.
+     * @param opcode an opcode.
+     * @return the mnemonic for {@code opcode} or {@code "<illegal opcode>"} if {@code opcode} is not a legal opcode.
+     */
+    public static String baseNameOf(int opcode) {
+        String name = nameArray[opcode & 0xff];
+        if (name == null) {
+            return "<illegal opcode>";
+        }
+        return name;
+    }
+
+    /**
+     * Gets the opcode corresponding to a given mnemonic.
+     *
+     * @param name an opcode mnemonic
+     * @return the opcode corresponding to {@code mnemonic}
+     * @throws IllegalArgumentException if {@code name} does not denote a valid opcode
+     */
+    public static int valueOf(String name) {
+        for (int opcode = 0; opcode < nameArray.length; ++opcode) {
+            if (name.equalsIgnoreCase(nameArray[opcode])) {
+                return opcode;
+            }
+        }
+        throw new IllegalArgumentException("No opcode for " + name);
+    }
+
+    /**
+     * Determines if a given opcode denotes an instruction that can cause an implicit exception.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} can cause an implicit exception, {@code false} otherwise
+     */
+    public static boolean canTrap(int opcode) {
+        return (flagsArray[opcode & 0xff] & TRAP) != 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes an instruction that loads a local variable to the operand stack.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} loads a local variable to the operand stack, {@code false} otherwise
+     */
+    public static boolean isLoad(int opcode) {
+        return (flagsArray[opcode & 0xff] & LOAD) != 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes an instruction that ends a basic block and does not let control flow fall
+     * through to its lexical successor.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} properly ends a basic block
+     */
+    public static boolean isStop(int opcode) {
+        return (flagsArray[opcode & 0xff] & STOP) != 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes an instruction that stores a value to a local variable
+     * after popping it from the operand stack.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false} otherwise
+     */
+    public static boolean isInvoke(int opcode) {
+        return (flagsArray[opcode & 0xff] & INVOKE) != 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes an instruction that stores a value to a local variable
+     * after popping it from the operand stack.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false} otherwise
+     */
+    public static boolean isStore(int opcode) {
+        return (flagsArray[opcode & 0xff] & STORE) != 0;
+    }
+
+    /**
+     * Determines if a given opcode is an instruction that delimits a basic block.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} delimits a basic block
+     */
+    public static boolean isBlockEnd(int opcode) {
+        return (flagsArray[opcode & 0xff] & (STOP | FALL_THROUGH)) != 0;
+    }
+
+    /**
+     * Determines if a given opcode is an instruction that has a 2 or 4 byte operand that is an offset to another
+     * instruction in the same method. This does not include the {@linkplain #TABLESWITCH switch} instructions.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} is a branch instruction with a single operand
+     */
+    public static boolean isBranch(int opcode) {
+        return (flagsArray[opcode & 0xff] & BRANCH) != 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes a conditional branch.
+     * @param opcode
+     * @return {@code true} iff {@code opcode} is a conditional branch
+     */
+    public static boolean isConditionalBranch(int opcode) {
+        return (flagsArray[opcode & 0xff] & FALL_THROUGH) != 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes a standard bytecode. A standard bytecode is
+     * defined in the JVM specification.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} is a standard bytecode
+     */
+    public static boolean isStandard(int opcode) {
+        return (flagsArray[opcode & 0xff] & EXTENSION) == 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes an extended bytecode.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} if {@code opcode} is an extended bytecode
+     */
+    public static boolean isExtended(int opcode) {
+        return (flagsArray[opcode & 0xff] & EXTENSION) != 0;
+    }
+
+    /**
+     * Determines if a given opcode is a three-byte extended bytecode.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} if {@code (opcode & ~0xff) != 0}
+     */
+    public static boolean isThreeByteExtended(int opcode) {
+        return (opcode & ~0xff) != 0;
+    }
+
+    /**
+     * Gets the arithmetic operator name for a given opcode. If {@code opcode} does not denote an
+     * arithmetic instruction, then the {@linkplain #nameOf(int) name} of the opcode is returned
+     * instead.
+     *
+     * @param op an opcode
+     * @return the arithmetic operator name
+     */
+    public static String operator(int op) {
+        // Checkstyle: stop
+        switch (op) {
+            // arithmetic ops
+            case IADD : // fall through
+            case LADD : // fall through
+            case FADD : // fall through
+            case DADD : return "+";
+            case ISUB : // fall through
+            case LSUB : // fall through
+            case FSUB : // fall through
+            case DSUB : return "-";
+            case IMUL : // fall through
+            case LMUL : // fall through
+            case FMUL : // fall through
+            case DMUL : return "*";
+            case IDIV : // fall through
+            case LDIV : // fall through
+            case FDIV : // fall through
+            case DDIV : return "/";
+            case IREM : // fall through
+            case LREM : // fall through
+            case FREM : // fall through
+            case DREM : return "%";
+            // shift ops
+            case ISHL : // fall through
+            case LSHL : return "<<";
+            case ISHR : // fall through
+            case LSHR : return ">>";
+            case IUSHR: // fall through
+            case LUSHR: return ">>>";
+            // logic ops
+            case IAND : // fall through
+            case LAND : return "&";
+            case IOR  : // fall through
+            case LOR  : return "|";
+            case IXOR : // fall through
+            case LXOR : return "^";
+        }
+        // Checkstyle: resume
+        return nameOf(op);
+    }
+
+    /**
+     * Defines a bytecode by entering it into the arrays that record its name, length and flags.
+     *
+     * @param name instruction name (should be lower case)
+     * @param format encodes the length of the instruction
+     * @param flagsArray the set of {@link Flags} associated with the instruction
+     */
+    private static void def(int opcode, String name, String format, int compilationComplexity) {
+        def(opcode, name, format, compilationComplexity, 0);
+    }
+
+    /**
+     * Defines a bytecode by entering it into the arrays that record its name, length and flags.
+     *
+     * @param name instruction name (lower case)
+     * @param format encodes the length of the instruction
+     * @param flags the set of {@link Flags} associated with the instruction
+     */
+    private static void def(int opcode, String name, String format, int compilationComplexity, int flags) {
+        assert nameArray[opcode] == null : "opcode " + opcode + " is already bound to name " + nameArray[opcode];
+        nameArray[opcode] = name;
+        int instructionLength = format.length();
+        lengthArray[opcode] = instructionLength;
+        compilationComplexityArray[opcode] = compilationComplexity;
+        Bytecodes.flagsArray[opcode] = flags;
+
+        assert !isConditionalBranch(opcode) || isBranch(opcode) : "a conditional branch must also be a branch";
+    }
+
+    /**
+     * Utility for ensuring that the extended opcodes are contiguous and follow on directly
+     * from the standard JVM opcodes. If these conditions do not hold for the input source
+     * file, then it is modified 'in situ' to fix the problem.
+     *
+     * @param args {@code args[0]} is the path to this source file
+     */
+    public static void main(String[] args) throws Exception {
+        Method findWorkspaceDirectory = Class.forName("com.sun.max.ide.JavaProject").getDeclaredMethod("findWorkspaceDirectory");
+        File base = new File((File) findWorkspaceDirectory.invoke(null), "com.oracle.max.cri/src");
+        File file = new File(base, Bytecodes.class.getName().replace('.', File.separatorChar) + ".java").getAbsoluteFile();
+
+        Pattern opcodeDecl = Pattern.compile("(\\s*public static final int )(\\w+)(\\s*=\\s*)(\\d+)(;.*)");
+
+        BufferedReader br = new BufferedReader(new FileReader(file));
+        CharArrayWriter buffer = new CharArrayWriter((int) file.length());
+        PrintWriter out = new PrintWriter(buffer);
+        String line;
+        int lastExtendedOpcode = BREAKPOINT;
+        boolean modified = false;
+        int section = 0;
+        while ((line = br.readLine()) != null) {
+            if (section == 0) {
+                if (line.equals("    // Start extended bytecodes")) {
+                    section = 1;
+                }
+            } else if (section == 1) {
+                if (line.equals("    // End extended bytecodes")) {
+                    section = 2;
+                } else {
+                    Matcher matcher = opcodeDecl.matcher(line);
+                    if (matcher.matches()) {
+                        String name = matcher.group(2);
+                        String value = matcher.group(4);
+                        int opcode = Integer.parseInt(value);
+                        if (nameArray[opcode] == null || !nameArray[opcode].equalsIgnoreCase(name)) {
+                            throw new RuntimeException("Missing definition of name and flags for " + opcode + ":" + name + " -- " + nameArray[opcode]);
+                        }
+                        if (opcode != lastExtendedOpcode + 1) {
+                            System.err.println("Fixed declaration of opcode " + name + " to be " + (lastExtendedOpcode + 1) + " (was " + value + ")");
+                            opcode = lastExtendedOpcode + 1;
+                            line = line.substring(0, matcher.start(4)) + opcode + line.substring(matcher.end(4));
+                            modified = true;
+                        }
+
+                        if (opcode >= 256) {
+                            throw new RuntimeException("Exceeded maximum opcode value with " + name);
+                        }
+
+                        lastExtendedOpcode = opcode;
+                    }
+                }
+            }
+
+            out.println(line);
+        }
+        if (section == 0) {
+            throw new RuntimeException("Did not find line starting extended bytecode declarations:\n\n    // Start extended bytecodes");
+        } else if (section == 1) {
+            throw new RuntimeException("Did not find line ending extended bytecode declarations:\n\n    // End extended bytecodes");
+        }
+
+        if (modified) {
+            out.flush();
+            FileWriter fileWriter = new FileWriter(file);
+            fileWriter.write(buffer.toCharArray());
+            fileWriter.close();
+
+            System.out.println("Modified: " + file);
+        }
+
+
+        // Uncomment to print out visitor method declarations:
+//        for (int opcode = 0; opcode < flags.length; ++opcode) {
+//            if (isExtension(opcode)) {
+//                String visitorParams = length(opcode) == 1 ? "" : "int index";
+//                System.out.println("@Override");
+//                System.out.println("protected void " + name(opcode) + "(" + visitorParams + ") {");
+//                System.out.println("}");
+//                System.out.println();
+//            }
+//        }
+
+        // Uncomment to print out visitor method declarations:
+//        for (int opcode = 0; opcode < flags.length; ++opcode) {
+//            if (isExtension(opcode)) {
+//                System.out.println("case " + name(opcode).toUpperCase() + ": {");
+//                String arg = "";
+//                int length = length(opcode);
+//                if (length == 2) {
+//                    arg = "readUnsigned1()";
+//                } else if (length == 3) {
+//                    arg = "readUnsigned2()";
+//                }
+//                System.out.println("    bytecodeVisitor." + name(opcode) + "(" + arg + ");");
+//                System.out.println("    break;");
+//                System.out.println("}");
+//            }
+//        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/Bytes.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.java;
+
+/**
+ * A collection of utility methods for dealing with bytes, particularly in byte arrays.
+ */
+public class Bytes {
+    /**
+     * Gets a signed 1-byte value.
+     * @param data the array containing the data
+     * @param bci the start index of the value to retrieve
+     * @return the signed 1-byte value at index {@code bci} in array {@code data}
+     */
+    public static int beS1(byte[] data, int bci) {
+        return data[bci];
+    }
+
+    /**
+     * Gets a signed 2-byte big-endian value.
+     * @param data the array containing the data
+     * @param bci the start index of the value to retrieve
+     * @return the signed 2-byte, big-endian, value at index {@code bci} in array {@code data}
+     */
+    public static int beS2(byte[] data, int bci) {
+        return (data[bci] << 8) | (data[bci + 1] & 0xff);
+    }
+
+    /**
+     * Gets an unsigned 1-byte value.
+     * @param data the array containing the data
+     * @param bci the start index of the value to retrieve
+     * @return the unsigned 1-byte value at index {@code bci} in array {@code data}
+     */
+    public static int beU1(byte[] data, int bci) {
+        return data[bci] & 0xff;
+    }
+
+    /**
+     * Gets an unsigned 2-byte big-endian value.
+     * @param data the array containing the data
+     * @param bci the start index of the value to retrieve
+     * @return the unsigned 2-byte, big-endian, value at index {@code bci} in array {@code data}
+     */
+    public static int beU2(byte[] data, int bci) {
+        return ((data[bci] & 0xff) << 8) | (data[bci + 1] & 0xff);
+    }
+
+    /**
+     * Gets a signed 4-byte big-endian value.
+     * @param data the array containing the data
+     * @param bci the start index of the value to retrieve
+     * @return the signed 4-byte, big-endian, value at index {@code bci} in array {@code data}
+     */
+    public static int beS4(byte[] data, int bci) {
+        return (data[bci] << 24) | ((data[bci + 1] & 0xff) << 16) | ((data[bci + 2] & 0xff) << 8) | (data[bci + 3] & 0xff);
+    }
+
+    /**
+     * Gets either a signed 2-byte or a signed 4-byte big-endian value.
+     * @param data the array containing the data
+     * @param bci the start index of the value to retrieve
+     * @param fourByte if true, this method will return a 4-byte value
+     * @return the signed 2 or 4-byte, big-endian, value at index {@code bci} in array {@code data}
+     */
+    public static int beSVar(byte[] data, int bci, boolean fourByte) {
+        if (fourByte) {
+            return beS4(data, bci);
+        } else {
+            return beS2(data, bci);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/FrameStateBuilder.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,489 @@
+/*
+ * 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.max.graal.java;
+
+import static com.oracle.max.graal.nodes.ValueUtil.*;
+import static java.lang.reflect.Modifier.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.PhiNode.PhiType;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+
+public class FrameStateBuilder implements FrameStateAccess {
+
+    private final StructuredGraph graph;
+
+    private final ValueNode[] locals;
+    private final ValueNode[] stack;
+
+    private int stackIndex;
+    private boolean rethrowException;
+
+    private final RiResolvedMethod method;
+
+    public FrameStateBuilder(RiResolvedMethod method, int maxLocals, int maxStackSize, StructuredGraph graph, boolean eagerResolve) {
+        assert graph != null;
+        this.method = method;
+        this.graph = graph;
+        this.locals = new ValueNode[maxLocals];
+        // we always need at least one stack slot (for exceptions)
+        int stackSize = Math.max(1, maxStackSize);
+        this.stack = new ValueNode[stackSize];
+
+        int javaIndex = 0;
+        int index = 0;
+        if (!isStatic(method.accessFlags())) {
+            // add the receiver
+            LocalNode local = graph.unique(new LocalNode(javaIndex, StampFactory.declaredNonNull(method.holder())));
+            storeLocal(javaIndex, local);
+            javaIndex = 1;
+            index = 1;
+        }
+        RiSignature sig = method.signature();
+        int max = sig.argumentCount(false);
+        RiResolvedType accessingClass = method.holder();
+        for (int i = 0; i < max; i++) {
+            RiType type = sig.argumentTypeAt(i, accessingClass);
+            if (eagerResolve) {
+                type = type.resolve(accessingClass);
+            }
+            CiKind kind = type.kind(false).stackKind();
+            Stamp stamp;
+            if (kind == CiKind.Object && type instanceof RiResolvedType) {
+                RiResolvedType resolvedType = (RiResolvedType) type;
+                stamp = StampFactory.declared(resolvedType);
+            } else {
+                stamp = StampFactory.forKind(kind);
+            }
+            LocalNode local = graph.unique(new LocalNode(index, stamp));
+            storeLocal(javaIndex, local);
+            javaIndex += stackSlots(kind);
+            index++;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return String.format("FrameStateBuilder[stackSize=%d]", stackIndex);
+    }
+
+    public void initializeFrom(FrameState other) {
+        assert locals.length == other.localsSize() : "expected: " + locals.length + ", actual: " + other.localsSize();
+        assert stack.length >= other.stackSize() : "expected: <=" + stack.length + ", actual: " + other.stackSize();
+
+        this.stackIndex = other.stackSize();
+        for (int i = 0; i < other.localsSize(); i++) {
+            locals[i] = other.localAt(i);
+        }
+        for (int i = 0; i < other.stackSize(); i++) {
+            stack[i] = other.stackAt(i);
+        }
+        this.rethrowException = other.rethrowException();
+    }
+
+    public FrameState create(int bci) {
+        return graph.add(new FrameState(method, bci, locals, stack, stackIndex, rethrowException, false));
+    }
+
+    public FrameState duplicateWithException(int bci, ValueNode exceptionObject) {
+        FrameState frameState = graph.add(new FrameState(method, bci, locals, new ValueNode[]{exceptionObject}, 1, true, false));
+        frameState.setOuterFrameState(outerFrameState());
+        return frameState;
+    }
+
+    /**
+     * Pushes an instruction onto the stack with the expected type.
+     * @param kind the type expected for this instruction
+     * @param x the instruction to push onto the stack
+     */
+    public void push(CiKind kind, ValueNode x) {
+        assert kind != CiKind.Void;
+        xpush(assertKind(kind, x));
+        if (isTwoSlot(kind)) {
+            xpush(null);
+        }
+    }
+
+    /**
+     * Pushes a value onto the stack without checking the type.
+     * @param x the instruction to push onto the stack
+     */
+    public void xpush(ValueNode x) {
+        assert x == null || !x.isDeleted();
+        assert x == null || (x.kind() != CiKind.Void && x.kind() != CiKind.Illegal) : "unexpected value: " + x;
+        stack[stackIndex++] = x;
+    }
+
+    /**
+     * Pushes a value onto the stack and checks that it is an int.
+     * @param x the instruction to push onto the stack
+     */
+    public void ipush(ValueNode x) {
+        xpush(assertInt(x));
+    }
+
+    /**
+     * Pushes a value onto the stack and checks that it is a float.
+     * @param x the instruction to push onto the stack
+     */
+    public void fpush(ValueNode x) {
+        xpush(assertFloat(x));
+    }
+
+    /**
+     * Pushes a value onto the stack and checks that it is an object.
+     * @param x the instruction to push onto the stack
+     */
+    public void apush(ValueNode x) {
+        xpush(assertObject(x));
+    }
+
+    /**
+     * Pushes a value onto the stack and checks that it is a JSR return address.
+     * @param x the instruction to push onto the stack
+     */
+    public void jpush(ValueNode x) {
+        xpush(assertJsr(x));
+    }
+
+    /**
+     * Pushes a value onto the stack and checks that it is a long.
+     *
+     * @param x the instruction to push onto the stack
+     */
+    public void lpush(ValueNode x) {
+        xpush(assertLong(x));
+        xpush(null);
+    }
+
+    /**
+     * Pushes a value onto the stack and checks that it is a double.
+     * @param x the instruction to push onto the stack
+     */
+    public void dpush(ValueNode x) {
+        xpush(assertDouble(x));
+        xpush(null);
+    }
+
+    public void pushReturn(CiKind kind, ValueNode x) {
+        if (kind != CiKind.Void) {
+            push(kind.stackKind(), x);
+        }
+    }
+
+    /**
+     * Pops an instruction off the stack with the expected type.
+     * @param kind the expected type
+     * @return the instruction on the top of the stack
+     */
+    public ValueNode pop(CiKind kind) {
+        assert kind != CiKind.Void;
+        if (isTwoSlot(kind)) {
+            xpop();
+        }
+        return assertKind(kind, xpop());
+    }
+
+    /**
+     * Pops a value off of the stack without checking the type.
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode xpop() {
+        ValueNode result = stack[--stackIndex];
+        assert result == null || !result.isDeleted();
+        return result;
+    }
+
+    /**
+     * Pops a value off of the stack and checks that it is an int.
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode ipop() {
+        return assertInt(xpop());
+    }
+
+    /**
+     * Pops a value off of the stack and checks that it is a float.
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode fpop() {
+        return assertFloat(xpop());
+    }
+
+    /**
+     * Pops a value off of the stack and checks that it is an object.
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode apop() {
+        return assertObject(xpop());
+    }
+
+    /**
+     * Pops a value off of the stack and checks that it is a JSR return address.
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode jpop() {
+        return assertJsr(xpop());
+    }
+
+    /**
+     * Pops a value off of the stack and checks that it is a long.
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode lpop() {
+        assertHigh(xpop());
+        return assertLong(xpop());
+    }
+
+    /**
+     * Pops a value off of the stack and checks that it is a double.
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode dpop() {
+        assertHigh(xpop());
+        return assertDouble(xpop());
+    }
+
+    /**
+     * Pop the specified number of slots off of this stack and return them as an array of instructions.
+     * @param size the number of arguments off of the stack
+     * @return an array containing the arguments off of the stack
+     */
+    public ValueNode[] popArguments(int slotSize, int argSize) {
+        int base = stackIndex - slotSize;
+        ValueNode[] r = new ValueNode[argSize];
+        int argIndex = 0;
+        int stackindex = 0;
+        while (stackindex < slotSize) {
+            ValueNode element = stack[base + stackindex];
+            assert element != null;
+            r[argIndex++] = element;
+            stackindex += stackSlots(element.kind());
+        }
+        stackIndex = base;
+        return r;
+    }
+
+    /**
+     * Peeks an element from the operand stack.
+     * @param argumentNumber The number of the argument, relative from the top of the stack (0 = top).
+     *        Long and double arguments only count as one argument, i.e., null-slots are ignored.
+     * @return The peeked argument.
+     */
+    public ValueNode peek(int argumentNumber) {
+        int idx = stackSize() - 1;
+        for (int i = 0; i < argumentNumber; i++) {
+            if (stackAt(idx) == null) {
+                idx--;
+                assert isTwoSlot(stackAt(idx).kind());
+            }
+            idx--;
+        }
+        return stackAt(idx);
+    }
+
+    /**
+     * Truncates this stack to the specified size.
+     * @param size the size to truncate to
+     */
+    public void truncateStack(int size) {
+        stackIndex = size;
+        assert stackIndex >= 0;
+    }
+
+    /**
+     * Clears all values on this stack.
+     */
+    public void clearStack() {
+        stackIndex = 0;
+    }
+
+    /**
+     * Loads the local variable at the specified index.
+     *
+     * @param i the index of the local variable to load
+     * @return the instruction that produced the specified local
+     */
+    public ValueNode loadLocal(int i) {
+        ValueNode x = locals[i];
+        if (x != null) {
+            if (x instanceof PhiNode) {
+                assert ((PhiNode) x).type() == PhiType.Value;
+                if (x.isDeleted()) {
+                    return null;
+                }
+            }
+            assert !isTwoSlot(x.kind()) || locals[i + 1] == null || locals[i + 1] instanceof PhiNode;
+        }
+        return x;
+    }
+
+    /**
+     * Stores a given local variable at the specified index. If the value is a {@linkplain CiKind#isDoubleWord() double word},
+     * then the next local variable index is also overwritten.
+     *
+     * @param i the index at which to store
+     * @param x the instruction which produces the value for the local
+     */
+    public void storeLocal(int i, ValueNode x) {
+        assert x.kind() != CiKind.Void && x.kind() != CiKind.Illegal : "unexpected value: " + x;
+        locals[i] = x;
+        if (isTwoSlot(x.kind())) {
+            // (tw) if this was a double word then kill i+1
+            locals[i + 1] = null;
+        }
+        if (i > 0) {
+            // if there was a double word at i - 1, then kill it
+            ValueNode p = locals[i - 1];
+            if (p != null && isTwoSlot(p.kind())) {
+                locals[i - 1] = null;
+            }
+        }
+    }
+
+    /**
+     * Get the value on the stack at the specified stack index.
+     *
+     * @param i the index into the stack, with {@code 0} being the bottom of the stack
+     * @return the instruction at the specified position in the stack
+     */
+    public final ValueNode stackAt(int i) {
+        return stack[i];
+    }
+
+    /**
+     * Gets the value in the local variables at the specified index.
+     *
+     * @param i the index into the locals
+     * @return the instruction that produced the value for the specified local
+     */
+    public final ValueNode localAt(int i) {
+        return locals[i];
+    }
+
+    /**
+     * Returns the size of the local variables.
+     *
+     * @return the size of the local variables
+     */
+    public int localsSize() {
+        return locals.length;
+    }
+
+    /**
+     * Gets the current size (height) of the stack.
+     */
+    public int stackSize() {
+        return stackIndex;
+    }
+
+    public Iterator<ValueNode> locals() {
+        return new ValueArrayIterator(locals);
+    }
+
+    public Iterator<ValueNode> stack() {
+        return new ValueArrayIterator(locals);
+    }
+
+
+    private static class ValueArrayIterator implements Iterator<ValueNode> {
+        private final ValueNode[] array;
+        private int index;
+
+        public ValueArrayIterator(ValueNode[] array, int length) {
+            assert length <= array.length;
+            this.array = array;
+            this.index = 0;
+        }
+
+        public ValueArrayIterator(ValueNode[] array) {
+            this(array, array.length);
+        }
+
+        @Override
+        public boolean hasNext() {
+            return index < array.length;
+        }
+
+        @Override
+        public ValueNode next() {
+            return array[index++];
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException("cannot remove from array");
+        }
+
+    }
+
+
+    @Override
+    public FrameState duplicate(int bci) {
+        return create(bci);
+    }
+
+    @Override
+    public ValueNode valueAt(int i) {
+        if (i < locals.length) {
+            return locals[i];
+        } else {
+            return stack[i - locals.length];
+        }
+    }
+
+    @Override
+    public FrameState outerFrameState() {
+        return null;
+    }
+
+    public FrameState duplicateWithoutStack(int bci) {
+        FrameState frameState = graph.add(new FrameState(method, bci, locals, new ValueNode[0], 0, false, false));
+        frameState.setOuterFrameState(outerFrameState());
+        return frameState;
+    }
+
+    @Override
+    public boolean rethrowException() {
+        return rethrowException;
+    }
+
+    public void setRethrowException(boolean b) {
+        rethrowException = b;
+    }
+
+    public static int stackSlots(CiKind kind) {
+        return isTwoSlot(kind) ? 2 : 1;
+    }
+
+    public static boolean isTwoSlot(CiKind kind) {
+        assert kind != CiKind.Void && kind != CiKind.Illegal;
+        return kind == CiKind.Long || kind == CiKind.Double;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderConfiguration.java	Mon Feb 27 13:10:13 2012 +0100
@@ -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.max.graal.java;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.phases.*;
+
+public class GraphBuilderConfiguration {
+
+    public static enum ResolvePolicy {
+        Default, EagerForSnippets, Eager,
+    }
+
+    private final boolean useBranchPrediction;
+    private final ResolvePolicy resolving;
+    private final PhasePlan plan;
+    private RiResolvedType[] skippedExceptionTypes;
+
+    public GraphBuilderConfiguration(boolean useBranchPrediction, ResolvePolicy resolving, PhasePlan plan) {
+        this.useBranchPrediction = useBranchPrediction;
+        this.resolving = resolving;
+        this.plan = plan;
+    }
+
+    public boolean useBranchPrediction() {
+        return useBranchPrediction;
+    }
+
+
+    public void setSkippedExceptionTypes(RiResolvedType[] skippedExceptionTypes) {
+        this.skippedExceptionTypes = skippedExceptionTypes;
+    }
+
+    public RiResolvedType[] getSkippedExceptionTypes() {
+        return skippedExceptionTypes;
+    }
+
+    public boolean eagerResolvingForSnippets() {
+        return (resolving == ResolvePolicy.EagerForSnippets || resolving == ResolvePolicy.Eager);
+    }
+
+    public boolean eagerResolving() {
+        return (resolving == ResolvePolicy.Eager);
+    }
+
+    public PhasePlan plan() {
+        return plan;
+    }
+
+    public static GraphBuilderConfiguration getDefault() {
+        return getDefault(null);
+    }
+
+    public static GraphBuilderConfiguration getDefault(PhasePlan plan) {
+        return new GraphBuilderConfiguration(GraalOptions.UseBranchPrediction, ResolvePolicy.Default, plan);
+    }
+
+    public static GraphBuilderConfiguration getSnippetDefault() {
+        return getSnippetDefault(null);
+    }
+
+    public static GraphBuilderConfiguration getSnippetDefault(PhasePlan plan) {
+        return new GraphBuilderConfiguration(false, ResolvePolicy.EagerForSnippets, plan);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1790 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.java;
+
+import static com.oracle.max.graal.java.Bytecodes.*;
+import static java.lang.reflect.Modifier.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.cri.ri.RiType.Representation;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.java.BciBlockMapping.Block;
+import com.oracle.max.graal.java.BciBlockMapping.DeoptBlock;
+import com.oracle.max.graal.java.BciBlockMapping.ExceptionBlock;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction;
+import com.oracle.max.graal.nodes.PhiNode.PhiType;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.java.*;
+import com.oracle.max.graal.nodes.java.MethodCallTargetNode.InvokeKind;
+import com.oracle.max.graal.nodes.spi.*;
+
+/**
+ * The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph.
+ */
+public final class GraphBuilderPhase extends Phase {
+
+    /**
+     * The minimum value to which {@link GraalOptions#TraceBytecodeParserLevel} must be set to trace
+     * the bytecode instructions as they are parsed.
+     */
+    public static final int TRACELEVEL_INSTRUCTIONS = 1;
+
+    /**
+     * The minimum value to which {@link GraalOptions#TraceBytecodeParserLevel} must be set to trace
+     * the frame state before each bytecode instruction as it is parsed.
+     */
+    public static final int TRACELEVEL_STATE = 2;
+
+    private StructuredGraph currentGraph;
+
+    private final RiRuntime runtime;
+    private RiConstantPool constantPool;
+    private RiExceptionHandler[] exceptionHandlers;
+    private RiResolvedMethod method;
+    private RiProfilingInfo profilingInfo;
+
+    private BytecodeStream stream;           // the bytecode stream
+    private final LogStream log;
+
+    private FrameStateBuilder frameState;          // the current execution state
+    private Block currentBlock;
+
+    private int nextBlockNumber;
+
+    private ValueNode methodSynchronizedObject;
+    private ExceptionBlock unwindBlock;
+    private Block returnBlock;
+
+    // the worklist of blocks, sorted by depth first number
+    private final PriorityQueue<Block> workList = new PriorityQueue<>(10, new Comparator<Block>() {
+        public int compare(Block o1, Block o2) {
+            return o1.blockID - o2.blockID;
+        }
+    });
+
+    private FixedWithNextNode lastInstr;                 // the last instruction added
+
+    private Set<Block> blocksOnWorklist;
+    private Set<Block> blocksVisited;
+
+    private BitSet canTrapBitSet;
+
+    public static final Map<RiMethod, StructuredGraph> cachedGraphs = new WeakHashMap<>();
+
+    private final GraphBuilderConfiguration config;
+
+    public GraphBuilderPhase(RiRuntime runtime) {
+        this(runtime, GraphBuilderConfiguration.getDefault());
+    }
+
+    public GraphBuilderPhase(RiRuntime runtime, GraphBuilderConfiguration config) {
+        this.config = config;
+        this.runtime = runtime;
+        this.log = GraalOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        method = graph.method();
+        profilingInfo = method.profilingInfo();
+        assert method.code() != null : "method must contain bytecodes: " + method;
+        this.stream = new BytecodeStream(method.code());
+        this.constantPool = method.getConstantPool();
+        this.blocksOnWorklist = new HashSet<>();
+        this.blocksVisited = new HashSet<>();
+        unwindBlock = null;
+        returnBlock = null;
+        methodSynchronizedObject = null;
+        exceptionHandlers = null;
+        this.currentGraph = graph;
+        this.frameState = new FrameStateBuilder(method, method.maxLocals(), method.maxStackSize(), graph, config.eagerResolving());
+        build();
+    }
+
+    @Override
+    protected String getDetailedName() {
+        return getName() + " " + CiUtil.format("%H.%n(%p):%r", method);
+    }
+
+    private BciBlockMapping createBlockMap() {
+        BciBlockMapping map = new BciBlockMapping(method, config.useBranchPrediction());
+        map.build();
+
+//        if (currentContext.isObserved()) {
+//            String label = CiUtil.format("BlockListBuilder %f %R %H.%n(%P)", method);
+//            currentContext.observable.fireCompilationEvent(label, map);
+//        }
+        // TODO(tw): Reinstall this logging code when debug framework is finished.
+        return map;
+    }
+
+    private void build() {
+        if (log != null) {
+            log.println();
+            log.println("Compiling " + method);
+        }
+
+        // compute the block map, setup exception handlers and get the entrypoint(s)
+        BciBlockMapping blockMap = createBlockMap();
+        this.canTrapBitSet = blockMap.canTrap;
+
+        exceptionHandlers = blockMap.exceptionHandlers();
+
+        nextBlockNumber = blockMap.blocks.size();
+
+        lastInstr = currentGraph.start();
+        if (isSynchronized(method.accessFlags())) {
+            // add a monitor enter to the start block
+            currentGraph.start().setStateAfter(frameState.create(FrameState.BEFORE_BCI));
+            methodSynchronizedObject = synchronizedObject(frameState, method);
+            lastInstr = genMonitorEnter(methodSynchronizedObject);
+        }
+
+        // finish the start block
+        ((AbstractStateSplit) lastInstr).setStateAfter(frameState.create(0));
+        if (blockMap.startBlock.isLoopHeader) {
+            appendGoto(createTarget(blockMap.startBlock, frameState));
+        } else {
+            blockMap.startBlock.firstInstruction = lastInstr;
+        }
+        addToWorkList(blockMap.startBlock);
+
+        iterateAllBlocks();
+        connectLoopEndToBegin();
+
+        // remove Placeholders (except for loop exits)
+        for (PlaceholderNode n : currentGraph.getNodes(PlaceholderNode.class)) {
+            currentGraph.removeFixed(n);
+        }
+
+        // remove dead FrameStates
+        for (Node n : currentGraph.getNodes(FrameState.class)) {
+            if (n.usages().size() == 0 && n.predecessor() == null) {
+                n.safeDelete();
+            }
+        }
+
+        if (GraalOptions.CacheGraphs && !currentGraph.hasNode(DeoptimizeNode.class)) {
+            cachedGraphs.put(method, currentGraph.copy());
+        }
+    }
+
+    private int nextBlockNumber() {
+        return nextBlockNumber++;
+    }
+
+    private Block unwindBlock(int bci) {
+        if (unwindBlock == null) {
+            unwindBlock = new ExceptionBlock();
+            unwindBlock.startBci = -1;
+            unwindBlock.endBci = -1;
+            unwindBlock.deoptBci = bci;
+            unwindBlock.blockID = nextBlockNumber();
+            addToWorkList(unwindBlock);
+        }
+        return unwindBlock;
+    }
+
+    private Block returnBlock(int bci) {
+        if (returnBlock == null) {
+            returnBlock = new Block();
+            returnBlock.startBci = bci;
+            returnBlock.endBci = bci;
+            returnBlock.blockID = nextBlockNumber();
+            addToWorkList(returnBlock);
+        }
+        return returnBlock;
+    }
+
+    private void markOnWorkList(Block block) {
+        blocksOnWorklist.add(block);
+    }
+
+    private boolean isOnWorkList(Block block) {
+        return blocksOnWorklist.contains(block);
+    }
+
+    private void markVisited(Block block) {
+        blocksVisited.add(block);
+    }
+
+    private boolean isVisited(Block block) {
+        return blocksVisited.contains(block);
+    }
+
+    public void mergeOrClone(Block target, FrameStateAccess newState, StateSplit first) {
+
+        int bci = target.startBci;
+        if (target instanceof ExceptionBlock) {
+            bci = ((ExceptionBlock) target).deoptBci;
+        }
+
+        FrameState existingState = first.stateAfter();
+        if (existingState == null) {
+            // There was no state : new target
+            // copy state because it is modified
+            first.setStateAfter(newState.duplicate(bci));
+            return;
+        } else {
+            if (!GraalOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) {
+                // stacks or locks do not match--bytecodes would not verify
+                TTY.println(existingState.toString());
+                TTY.println(newState.duplicate(0).toString());
+                throw new CiBailout("stack or locks do not match");
+            }
+            assert existingState.localsSize() == newState.localsSize();
+            assert existingState.stackSize() == newState.stackSize();
+
+            if (first instanceof PlaceholderNode) {
+                // there is no merge yet here
+                PlaceholderNode p = (PlaceholderNode) first;
+                if (p.predecessor() == null) {
+                    //nothing seems to come here, yet there's a state?
+                    Debug.log("Funky control flow going to @bci %d : we already have a state but no predecessor", bci);
+                    p.setStateAfter(newState.duplicate(bci));
+                    return;
+                } else {
+                    //create a merge
+                    MergeNode merge = currentGraph.add(new MergeNode());
+                    FixedNode next = p.next();
+                    if (p.predecessor() != null) {
+                        EndNode end = currentGraph.add(new EndNode());
+                        p.setNext(end);
+                        merge.addForwardEnd(end);
+                    }
+                    merge.setNext(next);
+                    FrameState mergeState = existingState.duplicate(bci);
+                    merge.setStateAfter(mergeState);
+                    mergeState.merge(merge, newState);
+                    target.firstInstruction = merge;
+                }
+            } else {
+                existingState.merge((MergeNode) first, newState);
+            }
+        }
+    }
+
+    public BytecodeStream stream() {
+        return stream;
+    }
+
+    public int bci() {
+        return stream.currentBCI();
+    }
+
+    private void loadLocal(int index, CiKind kind) {
+        frameState.push(kind, frameState.loadLocal(index));
+    }
+
+    private void storeLocal(CiKind kind, int index) {
+        frameState.storeLocal(index, frameState.pop(kind));
+    }
+
+    public static boolean covers(RiExceptionHandler handler, int bci) {
+        return handler.startBCI() <= bci && bci < handler.endBCI();
+    }
+
+    public static boolean isCatchAll(RiExceptionHandler handler) {
+        return handler.catchTypeCPI() == 0;
+    }
+
+    private BeginNode handleException(ValueNode exceptionObject, int bci) {
+        assert bci == FrameState.BEFORE_BCI || bci == bci() : "invalid bci";
+
+        if (GraalOptions.UseExceptionProbability) {
+            // be conservative if information was not recorded (could result in endless recompiles otherwise)
+            if (bci != FrameState.BEFORE_BCI && exceptionObject == null && profilingInfo.getExceptionSeen(bci) == RiExceptionSeen.FALSE) {
+                return null;
+            } else {
+                Debug.log("Creating exception edges at %d, exception object=%s, exception seen=%s", bci, exceptionObject, profilingInfo.getExceptionSeen(bci));
+            }
+        }
+
+        RiExceptionHandler firstHandler = null;
+        // join with all potential exception handlers
+        if (exceptionHandlers != null) {
+            for (RiExceptionHandler handler : exceptionHandlers) {
+                if (covers(handler, bci)) {
+                    firstHandler = handler;
+                    break;
+                }
+            }
+        }
+
+        Block dispatchBlock = null;
+        if (firstHandler == null) {
+            dispatchBlock = unwindBlock(bci);
+        } else {
+            for (int i = currentBlock.normalSuccessors; i < currentBlock.successors.size(); i++) {
+                Block block = currentBlock.successors.get(i);
+                if (block instanceof ExceptionBlock && ((ExceptionBlock) block).handler == firstHandler) {
+                    dispatchBlock = block;
+                    break;
+                }
+                if (isCatchAll(firstHandler) && block.startBci == firstHandler.handlerBCI()) {
+                    dispatchBlock = block;
+                    break;
+                }
+            }
+        }
+
+        // TODO(tw): Merge BeginNode with ExceptionObject node to get a correct and uniform FrameState.
+        BeginNode p = currentGraph.add(new BeginNode());
+        p.setStateAfter(frameState.duplicateWithoutStack(bci));
+
+        ValueNode currentExceptionObject;
+        ExceptionObjectNode newObj = null;
+        if (exceptionObject == null) {
+            newObj = currentGraph.add(new ExceptionObjectNode());
+            currentExceptionObject = newObj;
+        } else {
+            currentExceptionObject = exceptionObject;
+        }
+        FrameState stateWithException = frameState.duplicateWithException(bci, currentExceptionObject);
+        if (newObj != null) {
+            newObj.setStateAfter(stateWithException);
+        }
+        FixedNode target = createTarget(dispatchBlock, stateWithException);
+        if (exceptionObject == null) {
+            ExceptionObjectNode eObj = (ExceptionObjectNode) currentExceptionObject;
+            eObj.setNext(target);
+            p.setNext(eObj);
+        } else {
+            p.setNext(target);
+        }
+        return p;
+    }
+
+    private void genLoadConstant(int cpi, int opcode) {
+        Object con = lookupConstant(cpi, opcode);
+
+        if (con instanceof RiType) {
+            // this is a load of class constant which might be unresolved
+            RiType riType = (RiType) con;
+            if (riType instanceof RiResolvedType) {
+                frameState.push(CiKind.Object, append(ConstantNode.forCiConstant(((RiResolvedType) riType).getEncoding(Representation.JavaClass), runtime, currentGraph)));
+            } else {
+                append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
+                frameState.push(CiKind.Object, append(ConstantNode.forObject(null, runtime, currentGraph)));
+            }
+        } else if (con instanceof CiConstant) {
+            CiConstant constant = (CiConstant) con;
+            frameState.push(constant.kind.stackKind(), appendConstant(constant));
+        } else {
+            throw new Error("lookupConstant returned an object of incorrect type");
+        }
+    }
+
+    private void genLoadIndexed(CiKind kind) {
+        emitExplicitExceptions(frameState.peek(1), frameState.peek(0));
+
+        ValueNode index = frameState.ipop();
+        ValueNode array = frameState.apop();
+        ValueNode length = append(currentGraph.add(new ArrayLengthNode(array)));
+        ValueNode v = append(currentGraph.add(new LoadIndexedNode(array, index, length, kind)));
+        frameState.push(kind.stackKind(), v);
+    }
+
+    private void genStoreIndexed(CiKind kind) {
+        emitExplicitExceptions(frameState.peek(2), frameState.peek(1));
+
+        ValueNode value = frameState.pop(kind.stackKind());
+        ValueNode index = frameState.ipop();
+        ValueNode array = frameState.apop();
+        ValueNode length = append(currentGraph.add(new ArrayLengthNode(array)));
+        StoreIndexedNode result = currentGraph.add(new StoreIndexedNode(array, index, length, kind, value));
+        append(result);
+    }
+
+    private void stackOp(int opcode) {
+        switch (opcode) {
+            case POP: {
+                frameState.xpop();
+                break;
+            }
+            case POP2: {
+                frameState.xpop();
+                frameState.xpop();
+                break;
+            }
+            case DUP: {
+                ValueNode w = frameState.xpop();
+                frameState.xpush(w);
+                frameState.xpush(w);
+                break;
+            }
+            case DUP_X1: {
+                ValueNode w1 = frameState.xpop();
+                ValueNode w2 = frameState.xpop();
+                frameState.xpush(w1);
+                frameState.xpush(w2);
+                frameState.xpush(w1);
+                break;
+            }
+            case DUP_X2: {
+                ValueNode w1 = frameState.xpop();
+                ValueNode w2 = frameState.xpop();
+                ValueNode w3 = frameState.xpop();
+                frameState.xpush(w1);
+                frameState.xpush(w3);
+                frameState.xpush(w2);
+                frameState.xpush(w1);
+                break;
+            }
+            case DUP2: {
+                ValueNode w1 = frameState.xpop();
+                ValueNode w2 = frameState.xpop();
+                frameState.xpush(w2);
+                frameState.xpush(w1);
+                frameState.xpush(w2);
+                frameState.xpush(w1);
+                break;
+            }
+            case DUP2_X1: {
+                ValueNode w1 = frameState.xpop();
+                ValueNode w2 = frameState.xpop();
+                ValueNode w3 = frameState.xpop();
+                frameState.xpush(w2);
+                frameState.xpush(w1);
+                frameState.xpush(w3);
+                frameState.xpush(w2);
+                frameState.xpush(w1);
+                break;
+            }
+            case DUP2_X2: {
+                ValueNode w1 = frameState.xpop();
+                ValueNode w2 = frameState.xpop();
+                ValueNode w3 = frameState.xpop();
+                ValueNode w4 = frameState.xpop();
+                frameState.xpush(w2);
+                frameState.xpush(w1);
+                frameState.xpush(w4);
+                frameState.xpush(w3);
+                frameState.xpush(w2);
+                frameState.xpush(w1);
+                break;
+            }
+            case SWAP: {
+                ValueNode w1 = frameState.xpop();
+                ValueNode w2 = frameState.xpop();
+                frameState.xpush(w1);
+                frameState.xpush(w2);
+                break;
+            }
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+
+    }
+
+    private void genArithmeticOp(CiKind result, int opcode, boolean canTrap) {
+        ValueNode y = frameState.pop(result);
+        ValueNode x = frameState.pop(result);
+        boolean isStrictFP = isStrict(method.accessFlags());
+        ArithmeticNode v;
+        switch(opcode){
+            case IADD:
+            case LADD: v = new IntegerAddNode(result, x, y); break;
+            case FADD:
+            case DADD: v = new FloatAddNode(result, x, y, isStrictFP); break;
+            case ISUB:
+            case LSUB: v = new IntegerSubNode(result, x, y); break;
+            case FSUB:
+            case DSUB: v = new FloatSubNode(result, x, y, isStrictFP); break;
+            case IMUL:
+            case LMUL: v = new IntegerMulNode(result, x, y); break;
+            case FMUL:
+            case DMUL: v = new FloatMulNode(result, x, y, isStrictFP); break;
+            case IDIV:
+            case LDIV: v = new IntegerDivNode(result, x, y); break;
+            case FDIV:
+            case DDIV: v = new FloatDivNode(result, x, y, isStrictFP); break;
+            case IREM:
+            case LREM: v = new IntegerRemNode(result, x, y); break;
+            case FREM:
+            case DREM: v = new FloatRemNode(result, x, y, isStrictFP); break;
+            default:
+                throw new GraalInternalError("should not reach");
+        }
+        ValueNode result1 = append(currentGraph.unique(v));
+        if (canTrap) {
+            append(currentGraph.add(new ValueAnchorNode(result1)));
+        }
+        frameState.push(result, result1);
+    }
+
+    private void genNegateOp(CiKind kind) {
+        frameState.push(kind, append(currentGraph.unique(new NegateNode(frameState.pop(kind)))));
+    }
+
+    private void genShiftOp(CiKind kind, int opcode) {
+        ValueNode s = frameState.ipop();
+        ValueNode x = frameState.pop(kind);
+        ShiftNode v;
+        switch(opcode){
+            case ISHL:
+            case LSHL: v = new LeftShiftNode(kind, x, s); break;
+            case ISHR:
+            case LSHR: v = new RightShiftNode(kind, x, s); break;
+            case IUSHR:
+            case LUSHR: v = new UnsignedRightShiftNode(kind, x, s); break;
+            default:
+                throw new GraalInternalError("should not reach");
+        }
+        frameState.push(kind, append(currentGraph.unique(v)));
+    }
+
+    private void genLogicOp(CiKind kind, int opcode) {
+        ValueNode y = frameState.pop(kind);
+        ValueNode x = frameState.pop(kind);
+        LogicNode v;
+        switch(opcode){
+            case IAND:
+            case LAND: v = new AndNode(kind, x, y); break;
+            case IOR:
+            case LOR: v = new OrNode(kind, x, y); break;
+            case IXOR:
+            case LXOR: v = new XorNode(kind, x, y); break;
+            default:
+                throw new GraalInternalError("should not reach");
+        }
+        frameState.push(kind, append(currentGraph.unique(v)));
+    }
+
+    private void genCompareOp(CiKind kind, boolean isUnorderedLess) {
+        ValueNode y = frameState.pop(kind);
+        ValueNode x = frameState.pop(kind);
+        frameState.ipush(append(currentGraph.unique(new NormalizeCompareNode(x, y, isUnorderedLess))));
+    }
+
+    private void genConvert(ConvertNode.Op opcode) {
+        ValueNode input = frameState.pop(opcode.from.stackKind());
+        frameState.push(opcode.to.stackKind(), append(currentGraph.unique(new ConvertNode(opcode, input))));
+    }
+
+    private void genIncrement() {
+        int index = stream().readLocalIndex();
+        int delta = stream().readIncrement();
+        ValueNode x = frameState.localAt(index);
+        ValueNode y = append(ConstantNode.forInt(delta, currentGraph));
+        frameState.storeLocal(index, append(currentGraph.unique(new IntegerAddNode(CiKind.Int, x, y))));
+    }
+
+    private void genGoto() {
+        appendGoto(createTarget(currentBlock.successors.get(0), frameState));
+        assert currentBlock.normalSuccessors == 1;
+    }
+
+    private void ifNode(ValueNode x, Condition cond, ValueNode y) {
+        assert !x.isDeleted() && !y.isDeleted();
+        double probability = profilingInfo.getBranchTakenProbability(bci());
+        if (probability < 0) {
+            Debug.log("missing probability in %s at bci %d", method, bci());
+            probability = 0.5;
+        }
+
+        CompareNode condition = currentGraph.unique(new CompareNode(x, cond, y));
+        FixedNode trueSuccessor = createTarget(currentBlock.successors.get(0), frameState);
+        FixedNode falseSuccessor = createTarget(currentBlock.successors.get(1), frameState);
+        if (trueSuccessor == falseSuccessor) {
+            appendGoto(trueSuccessor);
+        } else {
+            append(currentGraph.add(new IfNode(condition, trueSuccessor, falseSuccessor, probability)));
+        }
+
+        assert currentBlock.normalSuccessors == 2 : currentBlock.normalSuccessors;
+    }
+
+    private void genIfZero(Condition cond) {
+        ValueNode y = appendConstant(CiConstant.INT_0);
+        ValueNode x = frameState.ipop();
+        ifNode(x, cond, y);
+    }
+
+    private void genIfNull(Condition cond) {
+        ValueNode y = appendConstant(CiConstant.NULL_OBJECT);
+        ValueNode x = frameState.apop();
+        ifNode(x, cond, y);
+    }
+
+    private void genIfSame(CiKind kind, Condition cond) {
+        ValueNode y = frameState.pop(kind);
+        ValueNode x = frameState.pop(kind);
+        assert !x.isDeleted() && !y.isDeleted();
+        ifNode(x, cond, y);
+    }
+
+    private void genThrow(int bci) {
+        ValueNode exception = frameState.apop();
+        FixedGuardNode node = currentGraph.add(new FixedGuardNode(currentGraph.unique(new NullCheckNode(exception, false))));
+        append(node);
+        append(handleException(exception, bci));
+    }
+
+    private RiType lookupType(int cpi, int bytecode) {
+        eagerResolvingForSnippets(cpi, bytecode);
+        RiType result = constantPool.lookupType(cpi, bytecode);
+        assert !config.eagerResolvingForSnippets() || result instanceof RiResolvedType;
+        return result;
+    }
+
+    private RiMethod lookupMethod(int cpi, int opcode) {
+        eagerResolvingForSnippets(cpi, opcode);
+        RiMethod result = constantPool.lookupMethod(cpi, opcode);
+        assert !config.eagerResolvingForSnippets() || ((result instanceof RiResolvedMethod) && ((RiResolvedMethod) result).holder().isInitialized());
+        return result;
+    }
+
+    private RiField lookupField(int cpi, int opcode) {
+        eagerResolvingForSnippets(cpi, opcode);
+        RiField result = constantPool.lookupField(cpi, opcode);
+        assert !config.eagerResolvingForSnippets() || (result instanceof RiResolvedField && ((RiResolvedField) result).holder().isInitialized());
+        return result;
+    }
+
+    private Object lookupConstant(int cpi, int opcode) {
+        eagerResolving(cpi, opcode);
+        Object result = constantPool.lookupConstant(cpi);
+        assert !config.eagerResolving() || !(result instanceof RiType) || (result instanceof RiResolvedType);
+        return result;
+    }
+
+    private void eagerResolving(int cpi, int bytecode) {
+        if (config.eagerResolving()) {
+            constantPool.loadReferencedType(cpi, bytecode);
+        }
+    }
+
+    private void eagerResolvingForSnippets(int cpi, int bytecode) {
+        if (config.eagerResolvingForSnippets()) {
+            constantPool.loadReferencedType(cpi, bytecode);
+        }
+    }
+
+    private static final RiResolvedType[] EMPTY_TYPE_ARRAY = new RiResolvedType[0];
+
+    private RiResolvedType[] getTypeCheckHints(RiResolvedType type, int maxHints) {
+        if (!GraalOptions.UseTypeCheckHints || Util.isFinalClass(type)) {
+            return new RiResolvedType[] {type};
+        } else {
+            RiResolvedType uniqueSubtype = type.uniqueConcreteSubtype();
+            if (uniqueSubtype != null) {
+                return new RiResolvedType[] {uniqueSubtype};
+            } else {
+                RiTypeProfile typeProfile = profilingInfo.getTypeProfile(bci());
+                if (typeProfile != null) {
+                    double notRecordedTypes = typeProfile.getNotRecordedProbability();
+                    RiResolvedType[] types = typeProfile.getTypes();
+
+                    if (notRecordedTypes == 0 && types != null && types.length > 0 && types.length <= maxHints) {
+                        RiResolvedType[] hints = new RiResolvedType[types.length];
+                        int hintCount = 0;
+                        for (RiResolvedType hint : types) {
+                            if (hint.isSubtypeOf(type)) {
+                                hints[hintCount++] = hint;
+                            }
+                        }
+                        return Arrays.copyOf(hints, Math.min(maxHints, hintCount));
+                    }
+                }
+                return EMPTY_TYPE_ARRAY;
+            }
+        }
+    }
+
+    private void genCheckCast() {
+        int cpi = stream().readCPI();
+        RiType type = lookupType(cpi, CHECKCAST);
+        boolean initialized = type instanceof RiResolvedType;
+        if (initialized) {
+            ConstantNode typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, true);
+            ValueNode object = frameState.apop();
+            AnchorNode anchor = currentGraph.add(new AnchorNode());
+            append(anchor);
+            CheckCastNode checkCast;
+            RiResolvedType[] hints = getTypeCheckHints((RiResolvedType) type, 2);
+            checkCast = currentGraph.unique(new CheckCastNode(anchor, typeInstruction, (RiResolvedType) type, object, hints, Util.isFinalClass((RiResolvedType) type)));
+            append(currentGraph.add(new ValueAnchorNode(checkCast)));
+            frameState.apush(checkCast);
+        } else {
+            ValueNode object = frameState.apop();
+            append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new CompareNode(object, Condition.EQ, ConstantNode.forObject(null, runtime, currentGraph))))));
+            frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
+        }
+    }
+
+    private void genInstanceOf() {
+        int cpi = stream().readCPI();
+        RiType type = lookupType(cpi, INSTANCEOF);
+        ValueNode object = frameState.apop();
+        if (type instanceof RiResolvedType) {
+            RiResolvedType resolvedType = (RiResolvedType) type;
+            ConstantNode hub = appendConstant(resolvedType.getEncoding(RiType.Representation.ObjectHub));
+
+            RiResolvedType[] hints = getTypeCheckHints(resolvedType, 1);
+            InstanceOfNode instanceOfNode = new InstanceOfNode(hub, (RiResolvedType) type, object, hints, Util.isFinalClass(resolvedType), false);
+            frameState.ipush(append(MaterializeNode.create(currentGraph.unique(instanceOfNode), currentGraph)));
+        } else {
+            PlaceholderNode trueSucc = currentGraph.add(new PlaceholderNode());
+            DeoptimizeNode deopt = currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile));
+            IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new NullCheckNode(object, true)), trueSucc, deopt, 1));
+            append(ifNode);
+            lastInstr = trueSucc;
+            frameState.ipush(appendConstant(CiConstant.INT_0));
+        }
+    }
+
+    void genNewInstance(int cpi) {
+        RiType type = lookupType(cpi, NEW);
+        if (type instanceof RiResolvedType) {
+            NewInstanceNode n = currentGraph.add(new NewInstanceNode((RiResolvedType) type));
+            frameState.apush(append(n));
+        } else {
+            append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
+            frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
+        }
+    }
+
+    /**
+     * Gets the kind of array elements for the array type code that appears
+     * in a {@link Bytecodes#NEWARRAY} bytecode.
+     * @param code the array type code
+     * @return the kind from the array type code
+     */
+    public static CiKind arrayTypeCodeToKind(int code) {
+        // Checkstyle: stop
+        switch (code) {
+            case 4:  return CiKind.Boolean;
+            case 5:  return CiKind.Char;
+            case 6:  return CiKind.Float;
+            case 7:  return CiKind.Double;
+            case 8:  return CiKind.Byte;
+            case 9:  return CiKind.Short;
+            case 10: return CiKind.Int;
+            case 11: return CiKind.Long;
+            default: throw new IllegalArgumentException("unknown array type code: " + code);
+        }
+        // Checkstyle: resume
+    }
+
+    private void genNewTypeArray(int typeCode) {
+        CiKind kind = arrayTypeCodeToKind(typeCode);
+        RiResolvedType elementType = runtime.asRiType(kind);
+        NewTypeArrayNode nta = currentGraph.add(new NewTypeArrayNode(frameState.ipop(), elementType));
+        frameState.apush(append(nta));
+    }
+
+    private void genNewObjectArray(int cpi) {
+        RiType type = lookupType(cpi, ANEWARRAY);
+        ValueNode length = frameState.ipop();
+        if (type instanceof RiResolvedType) {
+            NewArrayNode n = currentGraph.add(new NewObjectArrayNode((RiResolvedType) type, length));
+            frameState.apush(append(n));
+        } else {
+            append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
+            frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
+        }
+
+    }
+
+    private void genNewMultiArray(int cpi) {
+        RiType type = lookupType(cpi, MULTIANEWARRAY);
+        int rank = stream().readUByte(bci() + 3);
+        ValueNode[] dims = new ValueNode[rank];
+        for (int i = rank - 1; i >= 0; i--) {
+            dims[i] = frameState.ipop();
+        }
+        if (type instanceof RiResolvedType) {
+            FixedWithNextNode n = currentGraph.add(new NewMultiArrayNode((RiResolvedType) type, dims));
+            frameState.apush(append(n));
+        } else {
+            append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
+            frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
+        }
+    }
+
+    private void genGetField(RiField field) {
+        emitExplicitExceptions(frameState.peek(0), null);
+
+        CiKind kind = field.kind(false);
+        ValueNode receiver = frameState.apop();
+        if ((field instanceof RiResolvedField) && ((RiResolvedField) field).holder().isInitialized()) {
+            LoadFieldNode load = currentGraph.add(new LoadFieldNode(receiver, (RiResolvedField) field));
+            appendOptimizedLoadField(kind, load);
+        } else {
+            append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
+            frameState.push(kind.stackKind(), append(ConstantNode.defaultForKind(kind, currentGraph)));
+        }
+    }
+
+    public static class ExceptionInfo {
+
+        public final FixedWithNextNode exceptionEdge;
+        public final ValueNode exception;
+
+        public ExceptionInfo(FixedWithNextNode exceptionEdge, ValueNode exception) {
+            this.exceptionEdge = exceptionEdge;
+            this.exception = exception;
+        }
+    }
+
+    private ExceptionInfo emitNullCheck(ValueNode receiver) {
+        PlaceholderNode trueSucc = currentGraph.add(new PlaceholderNode());
+        PlaceholderNode falseSucc = currentGraph.add(new PlaceholderNode());
+        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new NullCheckNode(receiver, false)), trueSucc, falseSucc, 1));
+
+        append(ifNode);
+        lastInstr = trueSucc;
+
+        if (GraalOptions.OmitHotExceptionStacktrace) {
+            ValueNode exception = ConstantNode.forObject(new NullPointerException(), runtime, currentGraph);
+            return new ExceptionInfo(falseSucc, exception);
+        } else {
+            RuntimeCallNode call = currentGraph.add(new RuntimeCallNode(CiRuntimeCall.CreateNullPointerException));
+            call.setStateAfter(frameState.duplicate(bci()));
+            falseSucc.setNext(call);
+            return new ExceptionInfo(call, call);
+        }
+    }
+
+    private ExceptionInfo emitBoundsCheck(ValueNode index, ValueNode length) {
+        PlaceholderNode trueSucc = currentGraph.add(new PlaceholderNode());
+        PlaceholderNode falseSucc = currentGraph.add(new PlaceholderNode());
+        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new CompareNode(index, Condition.BT, length)), trueSucc, falseSucc, 1));
+
+        append(ifNode);
+        lastInstr = trueSucc;
+
+        if (GraalOptions.OmitHotExceptionStacktrace) {
+            ValueNode exception = ConstantNode.forObject(new ArrayIndexOutOfBoundsException(), runtime, currentGraph);
+            return new ExceptionInfo(falseSucc, exception);
+        } else {
+            RuntimeCallNode call = currentGraph.add(new RuntimeCallNode(CiRuntimeCall.CreateOutOfBoundsException, new ValueNode[] {index}));
+            call.setStateAfter(frameState.duplicate(bci()));
+            falseSucc.setNext(call);
+            return new ExceptionInfo(call, call);
+        }
+    }
+
+    private void emitExplicitExceptions(ValueNode receiver, ValueNode outOfBoundsIndex) {
+        assert receiver != null;
+
+        if (canTrapBitSet.get(bci()) && GraalOptions.AllowExplicitExceptionChecks) {
+            ArrayList<ExceptionInfo> exceptions = new ArrayList<>(2);
+            exceptions.add(emitNullCheck(receiver));
+            if (outOfBoundsIndex != null) {
+                ArrayLengthNode length = currentGraph.add(new ArrayLengthNode(receiver));
+                append(length);
+                exceptions.add(emitBoundsCheck(outOfBoundsIndex, length));
+            }
+            final ExceptionInfo exception;
+            if (exceptions.size() == 1) {
+                exception = exceptions.get(0);
+            } else {
+                assert exceptions.size() > 1;
+                MergeNode merge = currentGraph.add(new MergeNode());
+                PhiNode phi = currentGraph.unique(new PhiNode(CiKind.Object, merge, PhiType.Value));
+                for (ExceptionInfo info : exceptions) {
+                    EndNode end = currentGraph.add(new EndNode());
+                    info.exceptionEdge.setNext(end);
+                    merge.addForwardEnd(end);
+                    phi.addInput(info.exception);
+                }
+                merge.setStateAfter(frameState.duplicate(bci()));
+                exception = new ExceptionInfo(merge, phi);
+            }
+
+            FixedNode entry = handleException(exception.exception, bci());
+            if (entry != null) {
+                exception.exceptionEdge.setNext(entry);
+            } else {
+                exception.exceptionEdge.setNext(createTarget(unwindBlock(bci()), frameState.duplicateWithException(bci(), exception.exception)));
+            }
+            Debug.metric("ExplicitExceptions").increment();
+        }
+    }
+
+    private void genPutField(RiField field) {
+        emitExplicitExceptions(frameState.peek(1), null);
+
+        ValueNode value = frameState.pop(field.kind(false).stackKind());
+        ValueNode receiver = frameState.apop();
+        if (field instanceof RiResolvedField && ((RiResolvedField) field).holder().isInitialized()) {
+            StoreFieldNode store = currentGraph.add(new StoreFieldNode(receiver, (RiResolvedField) field, value));
+            appendOptimizedStoreField(store);
+        } else {
+            append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
+        }
+    }
+
+    private void genGetStatic(RiField field) {
+        RiType holder = field.holder();
+        boolean isInitialized = (field instanceof RiResolvedField) && ((RiResolvedType) holder).isInitialized();
+        CiConstant constantValue = null;
+        if (isInitialized) {
+            constantValue = ((RiResolvedField) field).constantValue(null);
+        }
+        if (constantValue != null) {
+            frameState.push(constantValue.kind.stackKind(), appendConstant(constantValue));
+        } else {
+            ValueNode container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, isInitialized);
+            CiKind kind = field.kind(false);
+            if (container != null) {
+                LoadFieldNode load = currentGraph.add(new LoadFieldNode(container, (RiResolvedField) field));
+                appendOptimizedLoadField(kind, load);
+            } else {
+                // deopt will be generated by genTypeOrDeopt, not needed here
+                frameState.push(kind.stackKind(), append(ConstantNode.defaultForKind(kind, currentGraph)));
+            }
+        }
+    }
+
+    private void genPutStatic(RiField field) {
+        RiType holder = field.holder();
+        ValueNode container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, field instanceof RiResolvedField && ((RiResolvedType) holder).isInitialized());
+        ValueNode value = frameState.pop(field.kind(false).stackKind());
+        if (container != null) {
+            StoreFieldNode store = currentGraph.add(new StoreFieldNode(container, (RiResolvedField) field, value));
+            appendOptimizedStoreField(store);
+        } else {
+            // deopt will be generated by genTypeOrDeopt, not needed here
+        }
+    }
+
+    private ConstantNode genTypeOrDeopt(RiType.Representation representation, RiType holder, boolean initialized) {
+        if (initialized) {
+            return appendConstant(((RiResolvedType) holder).getEncoding(representation));
+        } else {
+            append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
+            return null;
+        }
+    }
+
+    private void appendOptimizedStoreField(StoreFieldNode store) {
+        append(store);
+    }
+
+    private void appendOptimizedLoadField(CiKind kind, LoadFieldNode load) {
+        // append the load to the instruction
+        ValueNode optimized = append(load);
+        frameState.push(kind.stackKind(), optimized);
+    }
+
+    private void genInvokeStatic(RiMethod target) {
+        if (target instanceof RiResolvedMethod) {
+            RiResolvedMethod resolvedTarget = (RiResolvedMethod) target;
+            RiResolvedType holder = resolvedTarget.holder();
+            if (!holder.isInitialized() && GraalOptions.ResolveClassBeforeStaticInvoke) {
+                genInvokeDeopt(target, false);
+            } else {
+                ValueNode[] args = frameState.popArguments(resolvedTarget.signature().argumentSlots(false), resolvedTarget.signature().argumentCount(false));
+                appendInvoke(InvokeKind.Static, resolvedTarget, args);
+            }
+        } else {
+            genInvokeDeopt(target, false);
+        }
+    }
+
+    private void genInvokeInterface(RiMethod target) {
+        if (target instanceof RiResolvedMethod) {
+            ValueNode[] args = frameState.popArguments(target.signature().argumentSlots(true), target.signature().argumentCount(true));
+            genInvokeIndirect(InvokeKind.Interface, (RiResolvedMethod) target, args);
+        } else {
+            genInvokeDeopt(target, true);
+        }
+    }
+
+    private void genInvokeVirtual(RiMethod target) {
+        if (target instanceof RiResolvedMethod) {
+            ValueNode[] args = frameState.popArguments(target.signature().argumentSlots(true), target.signature().argumentCount(true));
+            genInvokeIndirect(InvokeKind.Virtual, (RiResolvedMethod) target, args);
+        } else {
+            genInvokeDeopt(target, true);
+        }
+
+    }
+
+    private void genInvokeSpecial(RiMethod target) {
+        if (target instanceof RiResolvedMethod) {
+            assert target != null;
+            assert target.signature() != null;
+            ValueNode[] args = frameState.popArguments(target.signature().argumentSlots(true), target.signature().argumentCount(true));
+            invokeDirect((RiResolvedMethod) target, args);
+        } else {
+            genInvokeDeopt(target, true);
+        }
+    }
+
+    private void genInvokeDeopt(RiMethod unresolvedTarget, boolean withReceiver) {
+        append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
+        frameState.popArguments(unresolvedTarget.signature().argumentSlots(withReceiver), unresolvedTarget.signature().argumentCount(withReceiver));
+        CiKind kind = unresolvedTarget.signature().returnKind(false);
+        if (kind != CiKind.Void) {
+            frameState.push(kind.stackKind(), append(ConstantNode.defaultForKind(kind, currentGraph)));
+        }
+    }
+
+    private void genInvokeIndirect(InvokeKind invokeKind, RiResolvedMethod target, ValueNode[] args) {
+        ValueNode receiver = args[0];
+        // attempt to devirtualize the call
+        RiResolvedType klass = target.holder();
+
+        // 0. check for trivial cases
+        if (target.canBeStaticallyBound() && !isAbstract(target.accessFlags())) {
+            // check for trivial cases (e.g. final methods, nonvirtual methods)
+            invokeDirect(target, args);
+            return;
+        }
+        // 1. check if the exact type of the receiver can be determined
+        RiResolvedType exact = getExactType(klass, receiver);
+        if (exact != null) {
+            // either the holder class is exact, or the receiver object has an exact type
+            invokeDirect(exact.resolveMethodImpl(target), args);
+            return;
+        }
+        // devirtualization failed, produce an actual invokevirtual
+        appendInvoke(invokeKind, target, args);
+    }
+
+    private void invokeDirect(RiResolvedMethod target, ValueNode[] args) {
+        appendInvoke(InvokeKind.Special, target, args);
+    }
+
+    private void appendInvoke(InvokeKind invokeKind, RiResolvedMethod targetMethod, ValueNode[] args) {
+        CiKind resultType = targetMethod.signature().returnKind(false);
+        if (GraalOptions.DeoptALot) {
+            DeoptimizeNode deoptimize = currentGraph.add(new DeoptimizeNode(DeoptAction.None));
+            deoptimize.setMessage("invoke " + targetMethod.name());
+            append(deoptimize);
+            frameState.pushReturn(resultType, ConstantNode.defaultForKind(resultType, currentGraph));
+        } else {
+            MethodCallTargetNode callTarget = currentGraph.add(new MethodCallTargetNode(invokeKind, targetMethod, args, targetMethod.signature().returnType(method.holder())));
+            BeginNode exceptionEdge = handleException(null, bci());
+            ValueNode result;
+            if (exceptionEdge != null) {
+                InvokeWithExceptionNode invoke = currentGraph.add(new InvokeWithExceptionNode(callTarget, exceptionEdge, bci()));
+                result = append(invoke);
+                frameState.pushReturn(resultType, result);
+                Block nextBlock = currentBlock.successors.get(0);
+                invoke.setNext(createTarget(nextBlock, frameState));
+                invoke.setStateAfter(frameState.create(nextBlock.startBci));
+            } else {
+                result = appendWithBCI(currentGraph.add(new InvokeNode(callTarget, bci())));
+                frameState.pushReturn(resultType, result);
+            }
+        }
+    }
+
+    private RiResolvedType getExactType(RiResolvedType staticType, ValueNode receiver) {
+        RiResolvedType exact = staticType.exactType();
+        if (exact == null) {
+            exact = receiver.exactType();
+            if (exact == null) {
+                if (receiver.isConstant()) {
+                    exact = runtime.getTypeOf(receiver.asConstant());
+                }
+                if (exact == null) {
+                    RiResolvedType declared = receiver.declaredType();
+                    if (declared != null) {
+                        exact = declared.exactType();
+                    }
+                }
+            }
+        }
+        return exact;
+    }
+
+    private void callRegisterFinalizer() {
+        // append a call to the finalizer registration
+        append(currentGraph.add(new RegisterFinalizerNode(frameState.loadLocal(0))));
+    }
+
+    private void genReturn(ValueNode x) {
+        frameState.clearStack();
+        if (x != null) {
+            frameState.push(x.kind(), x);
+        }
+        appendGoto(createTarget(returnBlock(bci()), frameState));
+    }
+
+    private MonitorEnterNode genMonitorEnter(ValueNode x) {
+        MonitorEnterNode monitorEnter = currentGraph.add(new MonitorEnterNode(x));
+        appendWithBCI(monitorEnter);
+        return monitorEnter;
+    }
+
+    private MonitorExitNode genMonitorExit(ValueNode x) {
+        MonitorExitNode monitorExit = currentGraph.add(new MonitorExitNode(x));
+        appendWithBCI(monitorExit);
+        return monitorExit;
+    }
+
+    private void genJsr(int dest) {
+        Block successor = currentBlock.jsrSuccessor;
+        assert successor.startBci == dest : successor.startBci + " != " + dest + " @" + bci();
+        JsrScope scope = currentBlock.jsrScope;
+        if (!successor.jsrScope.pop().equals(scope)) {
+            throw new JsrNotSupportedBailout("unstructured control flow (internal limitation)");
+        }
+        if (successor.jsrScope.nextReturnAddress() != stream().nextBCI()) {
+            throw new JsrNotSupportedBailout("unstructured control flow (internal limitation)");
+        }
+        frameState.push(CiKind.Jsr, ConstantNode.forJsr(stream().nextBCI(), currentGraph));
+        appendGoto(createTarget(successor, frameState));
+    }
+
+    private void genRet(int localIndex) {
+        Block successor = currentBlock.retSuccessor;
+        ValueNode local = frameState.loadLocal(localIndex);
+        JsrScope scope = currentBlock.jsrScope;
+        int retAddress = scope.nextReturnAddress();
+        append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new CompareNode(local, Condition.EQ, ConstantNode.forJsr(retAddress, currentGraph))))));
+        if (!successor.jsrScope.equals(scope.pop())) {
+            throw new JsrNotSupportedBailout("unstructured control flow (ret leaves more than one scope)");
+        }
+        appendGoto(createTarget(successor, frameState));
+    }
+
+    private void genTableswitch() {
+        int bci = bci();
+        ValueNode value = frameState.ipop();
+        BytecodeTableSwitch ts = new BytecodeTableSwitch(stream(), bci);
+
+        int nofCases = ts.numberOfCases() + 1; // including default case
+        assert currentBlock.normalSuccessors == nofCases;
+
+        TableSwitchNode tableSwitch = currentGraph.add(new TableSwitchNode(value, ts.lowKey(), switchProbability(nofCases, bci)));
+        for (int i = 0; i < nofCases; ++i) {
+            tableSwitch.setBlockSuccessor(i, BeginNode.begin(createTarget(currentBlock.successors.get(i), frameState)));
+        }
+        append(tableSwitch);
+    }
+
+    private double[] switchProbability(int numberOfCases, int bci) {
+        double[] prob = profilingInfo.getSwitchProbabilities(bci);
+        if (prob != null) {
+            assert prob.length == numberOfCases;
+        } else {
+            Debug.log("Missing probability (switch) in %s at bci %d", method, bci);
+            prob = new double[numberOfCases];
+            for (int i = 0; i < numberOfCases; i++) {
+                prob[i] = 1.0d / numberOfCases;
+            }
+        }
+        return prob;
+    }
+
+    private void genLookupswitch() {
+        int bci = bci();
+        ValueNode value = frameState.ipop();
+        BytecodeLookupSwitch ls = new BytecodeLookupSwitch(stream(), bci);
+
+        int nofCases = ls.numberOfCases() + 1; // including default case
+        assert currentBlock.normalSuccessors == nofCases;
+
+        int[] keys = new int[nofCases - 1];
+        for (int i = 0; i < nofCases - 1; ++i) {
+            keys[i] = ls.keyAt(i);
+        }
+        LookupSwitchNode lookupSwitch = currentGraph.add(new LookupSwitchNode(value, keys, switchProbability(nofCases, bci)));
+        for (int i = 0; i < nofCases; ++i) {
+            lookupSwitch.setBlockSuccessor(i, BeginNode.begin(createTarget(currentBlock.successors.get(i), frameState)));
+        }
+        append(lookupSwitch);
+    }
+
+    private ConstantNode appendConstant(CiConstant constant) {
+        return ConstantNode.forCiConstant(constant, runtime, currentGraph);
+    }
+
+    private ValueNode append(FixedNode fixed) {
+        lastInstr.setNext(fixed);
+        lastInstr = null;
+        return fixed;
+    }
+
+    private ValueNode append(FixedWithNextNode x) {
+        return appendWithBCI(x);
+    }
+
+    private static ValueNode append(ValueNode v) {
+        return v;
+    }
+
+    private ValueNode appendWithBCI(FixedWithNextNode x) {
+        assert x.predecessor() == null : "instruction should not have been appended yet";
+        assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")";
+        lastInstr.setNext(x);
+        lastInstr = x;
+        return x;
+    }
+
+    private FixedNode createTarget(Block block, FrameStateAccess stateAfter) {
+        assert block != null && stateAfter != null;
+        assert block.isLoopHeader || block.firstInstruction == null || block.firstInstruction.next() == null :
+            "non-loop block must be iterated after all its predecessors. startBci=" + block.startBci + ", " + block.getClass().getSimpleName() + ", " + block.firstInstruction.next();
+
+        if (block.isExceptionEntry) {
+            assert stateAfter.stackSize() == 1;
+        }
+
+        if (block.firstInstruction == null) {
+            if (block.isLoopHeader) {
+                LoopBeginNode loop = currentGraph.add(new LoopBeginNode());
+                EndNode end = currentGraph.add(new EndNode());
+                loop.addForwardEnd(end);
+                PlaceholderNode p = currentGraph.add(new PlaceholderNode());
+                p.setNext(end);
+                block.firstInstruction = p;
+            } else {
+                block.firstInstruction = currentGraph.add(new PlaceholderNode());
+            }
+        }
+        LoopEndNode loopend = null;
+        StateSplit mergeAt = null;
+        if (block.isLoopHeader && isVisited(block)) { // backedge
+            loopend = currentGraph.add(new LoopEndNode(loopBegin(block)));
+            mergeAt = loopBegin(block);
+        } else {
+            mergeAt = (StateSplit) block.firstInstruction;
+        }
+
+        mergeOrClone(block, stateAfter, mergeAt);
+        addToWorkList(block);
+
+        FixedNode result = null;
+        if (loopend != null) {
+            result = loopend;
+        } else {
+            result = block.firstInstruction;
+        }
+
+        if (result instanceof MergeNode) {
+            EndNode end = currentGraph.add(new EndNode());
+            ((MergeNode) result).addForwardEnd(end);
+            result = end;
+        }
+        assert !(result instanceof MergeNode);
+        Debug.log("createTarget(%s, state) = %s", block, result);
+        return result;
+    }
+
+    private ValueNode synchronizedObject(FrameStateAccess state, RiResolvedMethod target) {
+        if (isStatic(target.accessFlags())) {
+            return append(ConstantNode.forCiConstant(target.holder().getEncoding(Representation.JavaClass), runtime, currentGraph));
+        } else {
+            return state.localAt(0);
+        }
+    }
+
+    private void iterateAllBlocks() {
+        Block block;
+        while ((block = removeFromWorkList()) != null) {
+            // remove blocks that have no predecessors by the time it their bytecodes are parsed
+            if (block.firstInstruction == null) {
+                markVisited(block);
+                continue;
+            }
+
+            if (!isVisited(block)) {
+                markVisited(block);
+                // now parse the block
+                if (block.isLoopHeader) {
+                    LoopBeginNode begin = loopBegin(block);
+                    FrameState preLoopState = ((StateSplit) block.firstInstruction).stateAfter();
+                    FrameState loopState = preLoopState.duplicate(preLoopState.bci);
+                    begin.setStateAfter(loopState);
+                    loopState.insertLoopPhis(begin);
+                    lastInstr = begin;
+                } else {
+                    lastInstr = block.firstInstruction;
+                }
+                frameState.initializeFrom(((StateSplit) lastInstr).stateAfter());
+                assert lastInstr.next() == null : "instructions already appended at block " + block.blockID;
+
+                if (block == returnBlock) {
+                    frameState.setRethrowException(false);
+                    createReturn();
+                } else if (block == unwindBlock) {
+                    frameState.setRethrowException(false);
+                    createUnwind();
+                } else if (block instanceof ExceptionBlock) {
+                    createExceptionDispatch((ExceptionBlock) block);
+                } else if (block instanceof DeoptBlock) {
+                    createDeopt();
+                } else {
+                    frameState.setRethrowException(false);
+                    iterateBytecodesForBlock(block);
+                }
+            }
+        }
+    }
+
+    private void connectLoopEndToBegin() {
+        for (LoopBeginNode begin : currentGraph.getNodes(LoopBeginNode.class)) {
+            if (begin.loopEnds().isEmpty()) {
+//              This can happen with degenerated loops like this one:
+//              for (;;) {
+//                  try {
+//                      break;
+//                  } catch (UnresolvedException iioe) {
+//                  }
+//              }
+
+                // Remove the loop begin or transform it into a merge.
+                assert begin.forwardEndCount() > 0;
+                currentGraph.reduceDegenerateLoopBegin(begin);
+            } else {
+                begin.stateAfter().simplifyLoopState();
+            }
+        }
+    }
+
+    private static LoopBeginNode loopBegin(Block block) {
+        LoopBeginNode loopBegin = (LoopBeginNode) ((EndNode) block.firstInstruction.next()).merge();
+        return loopBegin;
+    }
+
+    private void createDeopt() {
+        append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateReprofile)));
+    }
+
+    private void createUnwind() {
+        synchronizedEpilogue(FrameState.AFTER_EXCEPTION_BCI);
+        UnwindNode unwindNode = currentGraph.add(new UnwindNode(frameState.apop()));
+        append(unwindNode);
+    }
+
+    private void createReturn() {
+        if (method.isConstructor() && method.holder().superType() == null) {
+            callRegisterFinalizer();
+        }
+        CiKind returnKind = method.signature().returnKind(false).stackKind();
+        ValueNode x = returnKind == CiKind.Void ? null : frameState.pop(returnKind);
+        assert frameState.stackSize() == 0;
+
+        // TODO (gd) remove this when FloatingRead is fixed
+        if (Modifier.isSynchronized(method.accessFlags())) {
+            append(currentGraph.add(new ValueAnchorNode(x)));
+            assert !frameState.rethrowException();
+        }
+
+        synchronizedEpilogue(FrameState.AFTER_BCI);
+        ReturnNode returnNode = currentGraph.add(new ReturnNode(x));
+        append(returnNode);
+    }
+
+    private void synchronizedEpilogue(int bci) {
+        if (Modifier.isSynchronized(method.accessFlags())) {
+            MonitorExitNode monitorExit = genMonitorExit(methodSynchronizedObject);
+            monitorExit.setStateAfter(frameState.create(bci));
+            assert !frameState.rethrowException();
+        }
+    }
+
+    private void createExceptionDispatch(ExceptionBlock block) {
+        if (block.handler == null) {
+            assert frameState.stackSize() == 1 : "only exception object expected on stack, actual size: " + frameState.stackSize();
+            createUnwind();
+        } else {
+            assert frameState.stackSize() == 1 : frameState;
+
+            RiType catchType = block.handler.catchType();
+            if (config.eagerResolving()) {
+                catchType = lookupType(block.handler.catchTypeCPI(), INSTANCEOF);
+            }
+            boolean initialized = (catchType instanceof RiResolvedType);
+            if (initialized && config.getSkippedExceptionTypes() != null) {
+                RiResolvedType resolvedCatchType = (RiResolvedType) catchType;
+                for (RiResolvedType skippedType : config.getSkippedExceptionTypes()) {
+                    initialized &= !resolvedCatchType.isSubtypeOf(skippedType);
+                    if (!initialized) {
+                        break;
+                    }
+                }
+            }
+
+            ConstantNode typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, catchType, initialized);
+            if (typeInstruction != null) {
+                Block nextBlock = block.successors.size() == 1 ? unwindBlock(block.deoptBci) : block.successors.get(1);
+                FixedNode catchSuccessor = createTarget(block.successors.get(0), frameState);
+                FixedNode nextDispatch = createTarget(nextBlock, frameState);
+                ValueNode exception = frameState.stackAt(0);
+                IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new InstanceOfNode(typeInstruction, (RiResolvedType) catchType, exception, false)), catchSuccessor, nextDispatch, 0.5));
+                append(ifNode);
+            }
+        }
+    }
+
+    private void appendGoto(FixedNode target) {
+        if (lastInstr != null) {
+            lastInstr.setNext(target);
+        }
+    }
+
+    private static boolean isBlockEnd(Node n) {
+        return trueSuccessorCount(n) > 1 || n instanceof ReturnNode || n instanceof UnwindNode || n instanceof DeoptimizeNode;
+    }
+
+    private static int trueSuccessorCount(Node n) {
+        if (n == null) {
+            return 0;
+        }
+        int i = 0;
+        for (Node s : n.successors()) {
+            if (Util.isFixed(s)) {
+                i++;
+            }
+        }
+        return i;
+    }
+
+    private void iterateBytecodesForBlock(Block block) {
+        assert frameState != null;
+
+        currentBlock = block;
+
+        int endBCI = stream.endBCI();
+
+        stream.setBCI(block.startBci);
+        int bci = block.startBci;
+        while (bci < endBCI) {
+            // read the opcode
+            int opcode = stream.currentBC();
+            traceState();
+            traceInstruction(bci, opcode, bci == block.startBci);
+            processBytecode(bci, opcode);
+
+            if (lastInstr == null || isBlockEnd(lastInstr) || lastInstr.next() != null) {
+                break;
+            }
+
+            stream.next();
+            bci = stream.currentBCI();
+            if (lastInstr instanceof StateSplit) {
+                StateSplit stateSplit = (StateSplit) lastInstr;
+                if (stateSplit.stateAfter() == null && stateSplit.needsStateAfter()) {
+                    stateSplit.setStateAfter(frameState.create(bci));
+                }
+            }
+            if (bci < endBCI) {
+                if (bci > block.endBci) {
+                    assert !block.successors.get(0).isExceptionEntry;
+                    assert block.normalSuccessors == 1;
+                    // we fell through to the next block, add a goto and break
+                    appendGoto(createTarget(block.successors.get(0), frameState));
+                    break;
+                }
+            }
+        }
+    }
+
+    private void traceState() {
+        if (GraalOptions.TraceBytecodeParserLevel >= TRACELEVEL_STATE && !TTY.isSuppressed()) {
+            log.println(String.format("|   state [nr locals = %d, stack depth = %d, method = %s]", frameState.localsSize(), frameState.stackSize(), method));
+            for (int i = 0; i < frameState.localsSize(); ++i) {
+                ValueNode value = frameState.localAt(i);
+                log.println(String.format("|   local[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind().javaName, value));
+            }
+            for (int i = 0; i < frameState.stackSize(); ++i) {
+                ValueNode value = frameState.stackAt(i);
+                log.println(String.format("|   stack[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind().javaName, value));
+            }
+        }
+    }
+
+    private void processBytecode(int bci, int opcode) {
+        int cpi;
+
+        // Checkstyle: stop
+        switch (opcode) {
+            case NOP            : /* nothing to do */ break;
+            case ACONST_NULL    : frameState.apush(appendConstant(CiConstant.NULL_OBJECT)); break;
+            case ICONST_M1      : frameState.ipush(appendConstant(CiConstant.INT_MINUS_1)); break;
+            case ICONST_0       : frameState.ipush(appendConstant(CiConstant.INT_0)); break;
+            case ICONST_1       : frameState.ipush(appendConstant(CiConstant.INT_1)); break;
+            case ICONST_2       : frameState.ipush(appendConstant(CiConstant.INT_2)); break;
+            case ICONST_3       : frameState.ipush(appendConstant(CiConstant.INT_3)); break;
+            case ICONST_4       : frameState.ipush(appendConstant(CiConstant.INT_4)); break;
+            case ICONST_5       : frameState.ipush(appendConstant(CiConstant.INT_5)); break;
+            case LCONST_0       : frameState.lpush(appendConstant(CiConstant.LONG_0)); break;
+            case LCONST_1       : frameState.lpush(appendConstant(CiConstant.LONG_1)); break;
+            case FCONST_0       : frameState.fpush(appendConstant(CiConstant.FLOAT_0)); break;
+            case FCONST_1       : frameState.fpush(appendConstant(CiConstant.FLOAT_1)); break;
+            case FCONST_2       : frameState.fpush(appendConstant(CiConstant.FLOAT_2)); break;
+            case DCONST_0       : frameState.dpush(appendConstant(CiConstant.DOUBLE_0)); break;
+            case DCONST_1       : frameState.dpush(appendConstant(CiConstant.DOUBLE_1)); break;
+            case BIPUSH         : frameState.ipush(appendConstant(CiConstant.forInt(stream.readByte()))); break;
+            case SIPUSH         : frameState.ipush(appendConstant(CiConstant.forInt(stream.readShort()))); break;
+            case LDC            : // fall through
+            case LDC_W          : // fall through
+            case LDC2_W         : genLoadConstant(stream.readCPI(), opcode); break;
+            case ILOAD          : loadLocal(stream.readLocalIndex(), CiKind.Int); break;
+            case LLOAD          : loadLocal(stream.readLocalIndex(), CiKind.Long); break;
+            case FLOAD          : loadLocal(stream.readLocalIndex(), CiKind.Float); break;
+            case DLOAD          : loadLocal(stream.readLocalIndex(), CiKind.Double); break;
+            case ALOAD          : loadLocal(stream.readLocalIndex(), CiKind.Object); break;
+            case ILOAD_0        : // fall through
+            case ILOAD_1        : // fall through
+            case ILOAD_2        : // fall through
+            case ILOAD_3        : loadLocal(opcode - ILOAD_0, CiKind.Int); break;
+            case LLOAD_0        : // fall through
+            case LLOAD_1        : // fall through
+            case LLOAD_2        : // fall through
+            case LLOAD_3        : loadLocal(opcode - LLOAD_0, CiKind.Long); break;
+            case FLOAD_0        : // fall through
+            case FLOAD_1        : // fall through
+            case FLOAD_2        : // fall through
+            case FLOAD_3        : loadLocal(opcode - FLOAD_0, CiKind.Float); break;
+            case DLOAD_0        : // fall through
+            case DLOAD_1        : // fall through
+            case DLOAD_2        : // fall through
+            case DLOAD_3        : loadLocal(opcode - DLOAD_0, CiKind.Double); break;
+            case ALOAD_0        : // fall through
+            case ALOAD_1        : // fall through
+            case ALOAD_2        : // fall through
+            case ALOAD_3        : loadLocal(opcode - ALOAD_0, CiKind.Object); break;
+            case IALOAD         : genLoadIndexed(CiKind.Int   ); break;
+            case LALOAD         : genLoadIndexed(CiKind.Long  ); break;
+            case FALOAD         : genLoadIndexed(CiKind.Float ); break;
+            case DALOAD         : genLoadIndexed(CiKind.Double); break;
+            case AALOAD         : genLoadIndexed(CiKind.Object); break;
+            case BALOAD         : genLoadIndexed(CiKind.Byte  ); break;
+            case CALOAD         : genLoadIndexed(CiKind.Char  ); break;
+            case SALOAD         : genLoadIndexed(CiKind.Short ); break;
+            case ISTORE         : storeLocal(CiKind.Int, stream.readLocalIndex()); break;
+            case LSTORE         : storeLocal(CiKind.Long, stream.readLocalIndex()); break;
+            case FSTORE         : storeLocal(CiKind.Float, stream.readLocalIndex()); break;
+            case DSTORE         : storeLocal(CiKind.Double, stream.readLocalIndex()); break;
+            case ASTORE         : storeLocal(CiKind.Object, stream.readLocalIndex()); break;
+            case ISTORE_0       : // fall through
+            case ISTORE_1       : // fall through
+            case ISTORE_2       : // fall through
+            case ISTORE_3       : storeLocal(CiKind.Int, opcode - ISTORE_0); break;
+            case LSTORE_0       : // fall through
+            case LSTORE_1       : // fall through
+            case LSTORE_2       : // fall through
+            case LSTORE_3       : storeLocal(CiKind.Long, opcode - LSTORE_0); break;
+            case FSTORE_0       : // fall through
+            case FSTORE_1       : // fall through
+            case FSTORE_2       : // fall through
+            case FSTORE_3       : storeLocal(CiKind.Float, opcode - FSTORE_0); break;
+            case DSTORE_0       : // fall through
+            case DSTORE_1       : // fall through
+            case DSTORE_2       : // fall through
+            case DSTORE_3       : storeLocal(CiKind.Double, opcode - DSTORE_0); break;
+            case ASTORE_0       : // fall through
+            case ASTORE_1       : // fall through
+            case ASTORE_2       : // fall through
+            case ASTORE_3       : storeLocal(CiKind.Object, opcode - ASTORE_0); break;
+            case IASTORE        : genStoreIndexed(CiKind.Int   ); break;
+            case LASTORE        : genStoreIndexed(CiKind.Long  ); break;
+            case FASTORE        : genStoreIndexed(CiKind.Float ); break;
+            case DASTORE        : genStoreIndexed(CiKind.Double); break;
+            case AASTORE        : genStoreIndexed(CiKind.Object); break;
+            case BASTORE        : genStoreIndexed(CiKind.Byte  ); break;
+            case CASTORE        : genStoreIndexed(CiKind.Char  ); break;
+            case SASTORE        : genStoreIndexed(CiKind.Short ); break;
+            case POP            : // fall through
+            case POP2           : // fall through
+            case DUP            : // fall through
+            case DUP_X1         : // fall through
+            case DUP_X2         : // fall through
+            case DUP2           : // fall through
+            case DUP2_X1        : // fall through
+            case DUP2_X2        : // fall through
+            case SWAP           : stackOp(opcode); break;
+            case IADD           : // fall through
+            case ISUB           : // fall through
+            case IMUL           : genArithmeticOp(CiKind.Int, opcode, false); break;
+            case IDIV           : // fall through
+            case IREM           : genArithmeticOp(CiKind.Int, opcode, true); break;
+            case LADD           : // fall through
+            case LSUB           : // fall through
+            case LMUL           : genArithmeticOp(CiKind.Long, opcode, false); break;
+            case LDIV           : // fall through
+            case LREM           : genArithmeticOp(CiKind.Long, opcode, true); break;
+            case FADD           : // fall through
+            case FSUB           : // fall through
+            case FMUL           : // fall through
+            case FDIV           : // fall through
+            case FREM           : genArithmeticOp(CiKind.Float, opcode, false); break;
+            case DADD           : // fall through
+            case DSUB           : // fall through
+            case DMUL           : // fall through
+            case DDIV           : // fall through
+            case DREM           : genArithmeticOp(CiKind.Double, opcode, false); break;
+            case INEG           : genNegateOp(CiKind.Int); break;
+            case LNEG           : genNegateOp(CiKind.Long); break;
+            case FNEG           : genNegateOp(CiKind.Float); break;
+            case DNEG           : genNegateOp(CiKind.Double); break;
+            case ISHL           : // fall through
+            case ISHR           : // fall through
+            case IUSHR          : genShiftOp(CiKind.Int, opcode); break;
+            case IAND           : // fall through
+            case IOR            : // fall through
+            case IXOR           : genLogicOp(CiKind.Int, opcode); break;
+            case LSHL           : // fall through
+            case LSHR           : // fall through
+            case LUSHR          : genShiftOp(CiKind.Long, opcode); break;
+            case LAND           : // fall through
+            case LOR            : // fall through
+            case LXOR           : genLogicOp(CiKind.Long, opcode); break;
+            case IINC           : genIncrement(); break;
+            case I2L            : genConvert(ConvertNode.Op.I2L); break;
+            case I2F            : genConvert(ConvertNode.Op.I2F); break;
+            case I2D            : genConvert(ConvertNode.Op.I2D); break;
+            case L2I            : genConvert(ConvertNode.Op.L2I); break;
+            case L2F            : genConvert(ConvertNode.Op.L2F); break;
+            case L2D            : genConvert(ConvertNode.Op.L2D); break;
+            case F2I            : genConvert(ConvertNode.Op.F2I); break;
+            case F2L            : genConvert(ConvertNode.Op.F2L); break;
+            case F2D            : genConvert(ConvertNode.Op.F2D); break;
+            case D2I            : genConvert(ConvertNode.Op.D2I); break;
+            case D2L            : genConvert(ConvertNode.Op.D2L); break;
+            case D2F            : genConvert(ConvertNode.Op.D2F); break;
+            case I2B            : genConvert(ConvertNode.Op.I2B); break;
+            case I2C            : genConvert(ConvertNode.Op.I2C); break;
+            case I2S            : genConvert(ConvertNode.Op.I2S); break;
+            case LCMP           : genCompareOp(CiKind.Long, false); break;
+            case FCMPL          : genCompareOp(CiKind.Float, true); break;
+            case FCMPG          : genCompareOp(CiKind.Float, false); break;
+            case DCMPL          : genCompareOp(CiKind.Double, true); break;
+            case DCMPG          : genCompareOp(CiKind.Double, false); break;
+            case IFEQ           : genIfZero(Condition.EQ); break;
+            case IFNE           : genIfZero(Condition.NE); break;
+            case IFLT           : genIfZero(Condition.LT); break;
+            case IFGE           : genIfZero(Condition.GE); break;
+            case IFGT           : genIfZero(Condition.GT); break;
+            case IFLE           : genIfZero(Condition.LE); break;
+            case IF_ICMPEQ      : genIfSame(CiKind.Int, Condition.EQ); break;
+            case IF_ICMPNE      : genIfSame(CiKind.Int, Condition.NE); break;
+            case IF_ICMPLT      : genIfSame(CiKind.Int, Condition.LT); break;
+            case IF_ICMPGE      : genIfSame(CiKind.Int, Condition.GE); break;
+            case IF_ICMPGT      : genIfSame(CiKind.Int, Condition.GT); break;
+            case IF_ICMPLE      : genIfSame(CiKind.Int, Condition.LE); break;
+            case IF_ACMPEQ      : genIfSame(CiKind.Object, Condition.EQ); break;
+            case IF_ACMPNE      : genIfSame(CiKind.Object, Condition.NE); break;
+            case GOTO           : genGoto(); break;
+            case JSR            : genJsr(stream.readBranchDest()); break;
+            case RET            : genRet(stream.readLocalIndex()); break;
+            case TABLESWITCH    : genTableswitch(); break;
+            case LOOKUPSWITCH   : genLookupswitch(); break;
+            case IRETURN        : genReturn(frameState.ipop()); break;
+            case LRETURN        : genReturn(frameState.lpop()); break;
+            case FRETURN        : genReturn(frameState.fpop()); break;
+            case DRETURN        : genReturn(frameState.dpop()); break;
+            case ARETURN        : genReturn(frameState.apop()); break;
+            case RETURN         : genReturn(null); break;
+            case GETSTATIC      : cpi = stream.readCPI(); genGetStatic(lookupField(cpi, opcode)); break;
+            case PUTSTATIC      : cpi = stream.readCPI(); genPutStatic(lookupField(cpi, opcode)); break;
+            case GETFIELD       : cpi = stream.readCPI(); genGetField(lookupField(cpi, opcode)); break;
+            case PUTFIELD       : cpi = stream.readCPI(); genPutField(lookupField(cpi, opcode)); break;
+            case INVOKEVIRTUAL  : cpi = stream.readCPI(); genInvokeVirtual(lookupMethod(cpi, opcode)); break;
+            case INVOKESPECIAL  : cpi = stream.readCPI(); genInvokeSpecial(lookupMethod(cpi, opcode)); break;
+            case INVOKESTATIC   : cpi = stream.readCPI(); genInvokeStatic(lookupMethod(cpi, opcode)); break;
+            case INVOKEINTERFACE: cpi = stream.readCPI(); genInvokeInterface(lookupMethod(cpi, opcode)); break;
+            case NEW            : genNewInstance(stream.readCPI()); break;
+            case NEWARRAY       : genNewTypeArray(stream.readLocalIndex()); break;
+            case ANEWARRAY      : genNewObjectArray(stream.readCPI()); break;
+            case ARRAYLENGTH    : genArrayLength(); break;
+            case ATHROW         : genThrow(stream.currentBCI()); break;
+            case CHECKCAST      : genCheckCast(); break;
+            case INSTANCEOF     : genInstanceOf(); break;
+            case MONITORENTER   : genMonitorEnter(frameState.apop()); break;
+            case MONITOREXIT    : genMonitorExit(frameState.apop()); break;
+            case MULTIANEWARRAY : genNewMultiArray(stream.readCPI()); break;
+            case IFNULL         : genIfNull(Condition.EQ); break;
+            case IFNONNULL      : genIfNull(Condition.NE); break;
+            case GOTO_W         : genGoto(); break;
+            case JSR_W          : genJsr(stream.readFarBranchDest()); break;
+            case BREAKPOINT:
+                throw new CiBailout("concurrent setting of breakpoint");
+            default:
+                throw new CiBailout("Unsupported opcode " + opcode + " (" + nameOf(opcode) + ") [bci=" + bci + "]");
+        }
+        // Checkstyle: resume
+    }
+
+    private void traceInstruction(int bci, int opcode, boolean blockStart) {
+        if (GraalOptions.TraceBytecodeParserLevel >= TRACELEVEL_INSTRUCTIONS && !TTY.isSuppressed()) {
+            StringBuilder sb = new StringBuilder(40);
+            sb.append(blockStart ? '+' : '|');
+            if (bci < 10) {
+                sb.append("  ");
+            } else if (bci < 100) {
+                sb.append(' ');
+            }
+            sb.append(bci).append(": ").append(Bytecodes.nameOf(opcode));
+            for (int i = bci + 1; i < stream.nextBCI(); ++i) {
+                sb.append(' ').append(stream.readUByte(i));
+            }
+            if (!currentBlock.jsrScope.isEmpty()) {
+                sb.append(' ').append(currentBlock.jsrScope);
+            }
+            log.println(sb.toString());
+        }
+    }
+
+    private void genArrayLength() {
+        frameState.ipush(append(currentGraph.add(new ArrayLengthNode(frameState.apop()))));
+    }
+
+    /**
+     * Adds a block to the worklist, if it is not already in the worklist.
+     * This method will keep the worklist topologically stored (i.e. the lower
+     * DFNs are earlier in the list).
+     * @param block the block to add to the work list
+     */
+    private void addToWorkList(Block block) {
+        if (!isOnWorkList(block)) {
+            markOnWorkList(block);
+            sortIntoWorkList(block);
+        }
+    }
+
+    private void sortIntoWorkList(Block top) {
+        workList.offer(top);
+    }
+
+    /**
+     * Removes the next block from the worklist. The list is sorted topologically, so the
+     * block with the lowest depth first number in the list will be removed and returned.
+     * @return the next block from the worklist; {@code null} if there are no blocks
+     * in the worklist
+     */
+    private Block removeFromWorkList() {
+        return workList.poll();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/JsrNotSupportedBailout.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.java;
+
+import com.oracle.max.cri.ci.*;
+
+
+public class JsrNotSupportedBailout extends CiBailout{
+    private static final long serialVersionUID = -7476925652727154272L;
+
+    public JsrNotSupportedBailout(String reason) {
+        super(reason);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/JsrScope.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,83 @@
+/*
+ * 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.max.graal.java;
+
+public class JsrScope {
+
+    public static final JsrScope EMPTY_SCOPE = new JsrScope();
+
+    private final long scope;
+
+    private JsrScope(long scope) {
+        this.scope = scope;
+    }
+
+    public JsrScope() {
+        this.scope = 0;
+    }
+
+    public int nextReturnAddress() {
+        return (int) (scope & 0xffff);
+    }
+
+    public JsrScope push(int jsrReturnBci) {
+        if ((scope & 0xffff000000000000L) != 0) {
+            throw new JsrNotSupportedBailout("only four jsr nesting levels are supported");
+        }
+        return new JsrScope((scope << 16) | jsrReturnBci);
+    }
+
+    public boolean isEmpty() {
+        return scope == 0;
+    }
+
+    public JsrScope pop() {
+        return new JsrScope(scope >>> 16);
+    }
+
+    @Override
+    public int hashCode() {
+        return (int) (scope ^ (scope >>> 32));
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        return obj != null && getClass() == obj.getClass() && scope == ((JsrScope) obj).scope;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        long tmp = scope;
+        sb.append(" [");
+        while (tmp != 0) {
+            sb.append(", ").append(tmp & 0xffff);
+            tmp = tmp >>> 16;
+        }
+        sb.append(']');
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/package-info.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2010, 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.max.graal.java;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/ConvertJTT.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2012, 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.max.graal.jtt;
+
+import java.io.*;
+import java.nio.charset.*;
+import java.nio.file.*;
+import java.util.*;
+
+/**
+ * Simple Utility to convert java tester tests from the proprietary test format into JUnit - tests.
+ */
+public class ConvertJTT {
+
+    public static void main(String[] args) throws IOException {
+        String targetPath = "graalvm/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/jtt";
+        String sourcePath = "maxine/com.oracle.max.vm/test/jtt";
+
+        File target = new File(targetPath);
+        for (File dir : new File(sourcePath).listFiles()) {
+            if (dir.isDirectory()) {
+                String packageName = dir.getName();
+                if (packageName.equals("exbytecode") || packageName.equals("max")) {
+                    continue;
+                }
+                File targetDir = new File(target, packageName);
+                for (File file : dir.listFiles()) {
+                    if (file.getName().endsWith(".java")) {
+                        targetDir.mkdirs();
+                        try {
+                            processFile(file.toPath(), new File(targetDir, file.getName()).toPath(), packageName);
+                        } catch (RuntimeException e) {
+                            e.printStackTrace();
+                            System.out.println("in file " + file.getAbsolutePath());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public static class Run {
+
+        public String input;
+        public String output;
+
+        public Run(String input, String output) {
+            this.input = input;
+            this.output = output;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%16s = %s", input, output);
+        }
+    }
+
+    private static void processFile(Path file, Path target, String packageName) throws IOException {
+        List<String> lines = Files.readAllLines(file, Charset.forName("UTF-8"));
+        Iterator<String> iter = lines.iterator();
+
+        ArrayList<String> output = new ArrayList<>();
+        ArrayList<Run> runs = new ArrayList<>();
+
+        String line;
+        boolean javaHarness = false;
+        while (iter.hasNext()) {
+            line = iter.next();
+            if (line.startsWith(" * Copyright (c) ")) {
+                output.add(" * Copyright (c) " + line.substring(17, 21) + ", 2012, Oracle and/or its affiliates. All rights reserved.");
+            } else if (line.contains("@Runs:")) {
+                line = line.substring(line.indexOf("@Runs:") + 6).trim();
+                if (line.endsWith(";")) {
+                    line = line.substring(0, line.length() - 1);
+                }
+                String[] runStrings;
+                if (charCount(line, ';') == charCount(line, '=') - 1) {
+                    runStrings = line.split(";");
+                } else if (charCount(line, ',') == charCount(line, '=') - 1) {
+                    runStrings = line.split(",");
+                } else if (charCount(line, ',', ';') == charCount(line, '=') - 1) {
+                    runStrings = line.split("[,;]");
+                } else {
+                    throw new RuntimeException("invalid run line: " + line);
+                }
+                for (String runString : runStrings) {
+                    String[] split = runString.split("=");
+                    if (split.length != 2) {
+                        throw new RuntimeException("invalid run string: " + runString);
+                    }
+                    Run run = new Run(split[0].trim(), split[1].trim());
+                    runs.add(run);
+                }
+            } else if (line.contains("@Harness:")) {
+                if (line.contains("@Harness: java")) {
+                    javaHarness = true;
+                }
+            } else if (line.startsWith("package jtt.")) {
+                output.add("package com.oracle.max.graal.jtt." + packageName + ";");
+                output.add("");
+                output.add("import org.junit.*;");
+            } else if (line.contains("@NEVER_INLINE")) {
+                output.add("// " + line);
+            } else if (line.startsWith("import com.sun.max.annotate.")) {
+                // do nothing
+            } else if (line.equals("}")) {
+                if (runs != null) {
+                    int n = 0;
+                    for (Run run : runs) {
+                        processRun(output, run, n++);
+                    }
+                    runs = null;
+                }
+                output.add(line);
+            } else {
+// line = line.replace(oldClassName, newClassName);
+                line = line.replace(" jtt.", " com.oracle.max.graal.jtt.");
+                output.add(line);
+            }
+        }
+        if (!javaHarness) {
+            throw new RuntimeException("no java harness");
+        }
+        if (runs != null) {
+            throw new RuntimeException("no ending brace found");
+        }
+
+        Files.write(target, output, Charset.forName("UTF-8"));
+    }
+
+    private static void processRun(ArrayList<String> output, Run run, int n) {
+        if (run.output.startsWith("!")) {
+            output.add("    @Test(expected = " + run.output.substring(1).replace("jtt.", "com.oracle.max.graal.jtt.").replace('$', '.') + ".class)");
+            output.add("    public void run" + n + "() throws Throwable {");
+            output.add("        test(" + parameters(run.input) + ");");
+            output.add("    }");
+            output.add("");
+        } else {
+            output.add("    @Test");
+            output.add("    public void run" + n + "() throws Throwable {");
+            String result = parameters(run.output);
+            if (result.endsWith("f") || result.endsWith("d") || result.endsWith("F") || result.endsWith("D")) {
+                output.add("        Assert.assertEquals(" + result + ", test(" + parameters(run.input) + "), 0);");
+            } else {
+                output.add("        Assert.assertEquals(" + result + ", test(" + parameters(run.input) + "));");
+            }
+            output.add("    }");
+            output.add("");
+        }
+    }
+
+    private static String parameters(String params) {
+        if (params.startsWith("(")) {
+            StringBuilder str = new StringBuilder();
+            String[] split = params.substring(1, params.length() - 1).split(",");
+            for (int i = 0; i < split.length; i++) {
+                str.append(i == 0 ? "" : ", ").append(parameters(split[i].trim()));
+            }
+            return str.toString();
+        } else if (params.startsWith("`")) {
+            return params.substring(1);
+        } else {
+            if (params.length() <= 1) {
+                return params;
+            } else {
+                if (params.endsWith("s")) {
+                    return "((short) " + params.substring(0, params.length() - 1) + ")";
+                } else if (params.endsWith("c")) {
+                    return "((char) " + params.substring(0, params.length() - 1) + ")";
+                } else if (params.endsWith("b")) {
+                    return "((byte) " + params.substring(0, params.length() - 1) + ")";
+                }
+            }
+            return params.replace("jtt.", "com.oracle.max.graal.jtt.");
+        }
+    }
+
+    private static int charCount(String str, char ch1) {
+        int count = 0;
+        for (int i = 0; i < str.length(); i++) {
+            if (str.charAt(i) == ch1) {
+                count++;
+            }
+        }
+        return count;
+    }
+
+    private static int charCount(String str, char ch1, char ch2) {
+        int count = 0;
+        for (int i = 0; i < str.length(); i++) {
+            if (str.charAt(i) == ch1 || str.charAt(i) == ch2) {
+                count++;
+            }
+        }
+        return count;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_aaload.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_aaload {
+
+    static Object[] array = {null, null, ""};
+
+    public static Object test(int arg) {
+        return array[arg];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(null, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(null, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("", test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_aaload_1.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_aaload_1 {
+
+    static Object[][] array = {{null}, {null}, {""}};
+
+    public static Object test(int arg) {
+        return array[arg][0];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(null, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(null, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("", test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_aastore.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_aastore {
+
+    static Object[] param = {new Object(), null, "h"};
+    static Object[] array1 = {null, null, null};
+    static String[] array2 = {null, null, null};
+
+    public static int test(boolean a, int indx) {
+        Object[] array = a ? array1 : array2;
+        Object val;
+        val = param[indx];
+        array[indx] = val;
+        return indx;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(true, 0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(true, 1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(true, 2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1, test(false, 1));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(2, test(false, 2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_aload_0.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_aload_0 {
+
+    public static Object test(Object arg) {
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(null, test(null));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("x", test("x"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_aload_1.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_aload_1 {
+
+    @SuppressWarnings("unused")
+    public static Object test(int i, Object arg) {
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(null, test(1, null));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("x", test(1, "x"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_aload_2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_aload_2 {
+
+    @SuppressWarnings("unused")
+    public static Object test(int i, int j, Object arg) {
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(null, test(1, 1, null));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("x", test(1, 1, "x"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_aload_3.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_aload_3 {
+
+    @SuppressWarnings("unused")
+    public static Object test(int i, int j, int k, Object arg) {
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("x", test(1, 1, 1, "x"));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(null, test(1, 1, 1, null));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_anewarray.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_anewarray {
+
+    @SuppressWarnings("unused")
+    public static int test(int a) {
+        final BC_anewarray[] v = new BC_anewarray[3];
+        if (v != null) {
+            return a;
+        }
+        return -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_areturn.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_areturn {
+
+    public static Object test(Object a) {
+        return a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(null, test(null));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("", test(""));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("this", test("this"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_arraylength.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_arraylength {
+
+    static int[] array1 = {1, 2, 3};
+    static char[] array2 = {'a', 'b', 'c', 'd'};
+    static Object[] array3 = new Object[5];
+    static Object[][] array4 = new Object[5][5];
+
+    public static int test(int arg) {
+        if (arg == 1) {
+            return array1.length;
+        }
+        if (arg == 2) {
+            return array2.length;
+        }
+        if (arg == 3) {
+            return array3.length;
+        }
+        if (arg == 4) {
+            return array4[0].length;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3, test(1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(4, test(2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(5, test(3));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(5, test(4));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(42, test(5));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_athrow.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_athrow {
+
+    static Throwable throwable = new Throwable();
+
+    public static int test(int arg) throws Throwable {
+        if (arg == 2) {
+            throw throwable;
+        }
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test(expected = java.lang.Throwable.class)
+    public void run2() throws Throwable {
+        test(2);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(3, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_baload.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_baload {
+
+    static boolean[] array = {true, false, true, false};
+
+    public static boolean test(int arg) {
+        return array[arg];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_bastore.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_bastore {
+
+    static boolean[] array = {false, false, false, false};
+
+    public static boolean test(int arg, boolean val) {
+        array[arg] = val;
+        return array[arg];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0, true));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1, false));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2, true));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3, false));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_caload.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_caload {
+
+    static char[] array = {'\000', 'a', ' ', 10000};
+
+    public static char test(int arg) {
+        return array[arg];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((char) 0), test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((char) 97), test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((char) 32), test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(((char) 10000), test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_castore.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_castore {
+
+    static char[] array = {0, 0, 0, 0};
+
+    public static char test(int arg, char val) {
+        array[arg] = val;
+        return array[arg];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((char) 97), test(0, ((char) 97)));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((char) 65), test(1, ((char) 65)));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((char) 42), test(2, ((char) 42)));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(((char) 120), test(3, ((char) 120)));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_checkcast01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_checkcast01 {
+
+    static Object object2 = new Object();
+    static Object object3 = "";
+    static Object object4 = new BC_checkcast01();
+
+    public static int test(int arg) {
+        Object obj;
+        if (arg == 2) {
+            obj = object2;
+        } else if (arg == 3) {
+            obj = object3;
+        } else if (arg == 4) {
+            obj = object4;
+        } else {
+            obj = null;
+        }
+        final BC_checkcast01 bc = (BC_checkcast01) obj;
+        if (bc != null) {
+            return arg;
+        }
+        return -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-1, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(4, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_checkcast02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_checkcast02 {
+
+    static Object[] o1 = {new Object()};
+    static String[] o2 = {""};
+    static BC_checkcast02[] o3 = {new BC_checkcast02()};
+
+    public static int test(int arg) {
+        Object obj = null;
+        if (arg == 0) {
+            obj = o1;
+        }
+        if (arg == 1) {
+            obj = o2;
+        }
+        if (arg == 2) {
+            obj = o3;
+        }
+        Object[] r = (Object[]) obj;
+        return r == null ? -1 : -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-1, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-1, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_d2f.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_d2f {
+
+    public static float test(double d) {
+        return (float) d;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.0f, test(0.0d), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1.0f, test(1.0d), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1.06f, test(-1.06d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_d2i01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_d2i01 {
+
+    public static int test(double d) {
+        return (int) d;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0.0d));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1.0d));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1, test(-1.06d));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-156, test(-156.82743d));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_d2i02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_d2i02 {
+
+    private static double[] inputs = {-1.3e44d, Double.NEGATIVE_INFINITY, Double.NaN, Double.POSITIVE_INFINITY, 1.3e44d};
+
+    public static int test(int i) {
+        return (int) inputs[i];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-2147483648, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-2147483648, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(2147483647, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(2147483647, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_d2l01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_d2l01 {
+
+    public static long test(double d) {
+        return (long) d;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(0.0d));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1L, test(1.0d));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1L, test(-1.06d));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-156L, test(-156.82743d));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_d2l02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_d2l02 {
+
+    private static double[] inputs = {-1.3e44d, Double.NEGATIVE_INFINITY, Double.NaN, Double.POSITIVE_INFINITY, 1.3e44d};
+
+    public static long test(int i) {
+        return (long) inputs[i];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-9223372036854775808L, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-9223372036854775808L, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0L, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(9223372036854775807L, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(9223372036854775807L, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_dadd.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_dadd {
+
+    public static double test(double a, double b) {
+        return a + b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.0d, test(0.0d, 0.0d), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2.0d, test(1.0d, 1.0d), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(307.54d, test(253.11d, 54.43d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_daload.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_daload {
+
+    static double[] array = {0.0, -1.1, 4.32, 6.06};
+
+    public static double test(int arg) {
+        return array[arg];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.0d, test(0), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1.1d, test(1), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(4.32d, test(2), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(6.06d, test(3), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_dastore.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_dastore {
+
+    static double[] array = {0, 0, 0, 0};
+
+    public static double test(int arg, double val) {
+        array[arg] = val;
+        return array[arg];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.01d, test(0, 0.01d), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1.4d, test(1, -1.4d), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0.01d, test(2, 0.01d), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-1.4d, test(3, -1.4d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_dcmp01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_dcmp01 {
+
+    public static boolean test(double a, double b) {
+        return a < b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0d, -0.1d));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(78.00d, 78.001d));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_dcmp02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_dcmp02 {
+
+    public static boolean test(double a) {
+        return (a / a) < 0.0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-1.0d));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1.0d));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(0.0d));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(-0.0d));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_dcmp03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_dcmp03 {
+
+    public static boolean test(double a) {
+        return (a / a) > 0.0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-1.0d));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1.0d));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(0.0d));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(-0.0d));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_dcmp04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_dcmp04 {
+
+    public static boolean test(double a) {
+        return (a / a) <= 0.0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-1.0d));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1.0d));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(0.0d));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(-0.0d));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_dcmp05.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_dcmp05 {
+
+    public static boolean test(double a) {
+        return (a / a) >= 0.0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-1.0d));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1.0d));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(0.0d));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_dcmp06.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_dcmp06 {
+
+    public static boolean test(double a) {
+        return 0.0 < (a / a);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-1.0d));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1.0d));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(0.0d));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_dcmp07.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_dcmp07 {
+
+    public static boolean test(double a) {
+        return 0.0 > (a / a);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-1.0d));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1.0d));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(0.0d));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_dcmp08.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_dcmp08 {
+
+    public static boolean test(double a) {
+        return 0.0 <= (a / a);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-1.0d));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1.0d));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(0.0d));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_dcmp09.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_dcmp09 {
+
+    public static boolean test(double a) {
+        return 0.0 >= (a / a);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-1.0d));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1.0d));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(0.0d));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_dcmp10.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_dcmp10 {
+
+    public static boolean test(int x) {
+        double a = 0;
+        double b = 0;
+        switch (x) {
+            case 0:
+                a = Double.POSITIVE_INFINITY;
+                b = 1;
+                break;
+            case 1:
+                a = 1;
+                b = Double.POSITIVE_INFINITY;
+                break;
+            case 2:
+                a = Double.NEGATIVE_INFINITY;
+                b = 1;
+                break;
+            case 3:
+                a = 1;
+                b = Double.NEGATIVE_INFINITY;
+                break;
+            case 4:
+                a = Double.NEGATIVE_INFINITY;
+                b = Double.NEGATIVE_INFINITY;
+                break;
+            case 5:
+                a = Double.NEGATIVE_INFINITY;
+                b = Double.POSITIVE_INFINITY;
+                break;
+            case 6:
+                a = Double.NaN;
+                b = Double.POSITIVE_INFINITY;
+                break;
+            case 7:
+                a = 1;
+                b = Double.NaN;
+                break;
+            case 8:
+                a = 1;
+                b = -0.0d / 0.0d;
+                break;
+        }
+        return a <= b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(false, test(7));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(false, test(8));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ddiv.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ddiv {
+
+    public static double test(double a, double b) {
+        return a / b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(31.1D, test(311.0D, 10D), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_dmul.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_dmul {
+
+    public static double test(double a, double b) {
+        return a * b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3110.0D, test(311.0D, 10D), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(22.4D, test(11.2D, 2.0D), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_dneg.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_dneg {
+
+    public static double test(double a, double b, int which) {
+        double result1 = -a;
+        double result2 = -b;
+        double result = 0.0;
+        if (which == 0) {
+            result = result1;
+        } else {
+            result = result2;
+        }
+        return result;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-0.0d, test(0.0d, 1.0d, 0), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1.01d, test(-1.01d, -2.01d, 0), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-7263.8734d, test(7263.8734d, 8263.8734d, 0), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-1.0d, test(0.0d, 1.0d, 1), 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(2.01d, test(-1.01d, -2.01d, 1), 0);
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(-8263.8734d, test(7263.8734d, 8263.8734d, 1), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_dneg2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_dneg2 {
+
+// @NEVER_INLINE
+    public static double test(double a) {
+        return 1 / (-a);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(java.lang.Double.POSITIVE_INFINITY, test(-0.0d), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(java.lang.Double.NEGATIVE_INFINITY, test(0.0d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_drem.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+public class BC_drem {
+
+    public static double test(double a, double b) {
+        return a % b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1.0D, test(311.0D, 10D), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1.2D, test(11.2D, 2.0D), 0.000000000000001);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_dreturn.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_dreturn {
+
+    public static double test(double a) {
+        return a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.0d, test(0.0d), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1.1d, test(1.1d), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1.4d, test(-1.4d), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(256.33d, test(256.33d), 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(1000.001d, test(1000.001d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_dsub.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_dsub {
+
+    public static double test(double a, double b) {
+        return a - b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.0d, test(0.0d, 0.0d), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0.0d, test(1.0d, 1.0d), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(198.68d, test(253.11d, 54.43d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_dsub2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_dsub2 {
+
+    public static double test(double a) {
+        return 1.0 / (0.0 - a);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(java.lang.Double.POSITIVE_INFINITY, test(0.0d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_f2d.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_f2d {
+
+    public static double test(float d) {
+        return d;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.0d, test(0.0f), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1.0d, test(1.0f), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-2.00d, test(-2.00f), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_f2i01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_f2i01 {
+
+    public static int test(float d) {
+        return (int) d;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0.0f));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1.0f));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1, test(-1.06f));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-156, test(-156.82743f));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_f2i02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_f2i02 {
+
+    private static float[] inputs = {-1.3e22f, Float.NEGATIVE_INFINITY, Float.NaN, Float.POSITIVE_INFINITY, 1.3e22f};
+
+    public static int test(int i) {
+        return (int) inputs[i];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-2147483648, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-2147483648, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(2147483647, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(2147483647, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_f2l01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_f2l01 {
+
+    public static long test(float d) {
+        return (long) d;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(0.0f));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1L, test(1.0f));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1L, test(-1.06f));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-156L, test(-156.82743f));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_f2l02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_f2l02 {
+
+    private static float[] inputs = {-1.3e22f, Float.NEGATIVE_INFINITY, Float.NaN, Float.POSITIVE_INFINITY, 1.3e22f};
+
+    public static long test(int i) {
+        return (long) inputs[i];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-9223372036854775808L, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-9223372036854775808L, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0L, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(9223372036854775807L, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(9223372036854775807L, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_fadd.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_fadd {
+
+    public static float test(float a, float b) {
+        return a + b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.0f, test(0.0f, 0.0f), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2.0f, test(1.0f, 1.0f), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(307.54f, test(253.11f, 54.43f), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_faload.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_faload {
+
+    static float[] array = {0.0f, -1.1f, 4.32f, 6.06f};
+
+    public static float test(int arg) {
+        return array[arg];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.0f, test(0), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1.1f, test(1), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(4.32f, test(2), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(6.06f, test(3), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_fastore.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_fastore {
+
+    static float[] array = {0, 0, 0, 0};
+
+    public static float test(int arg, float val) {
+        array[arg] = val;
+        return array[arg];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.01f, test(0, 0.01f), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1.4f, test(1, -1.4f), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0.01f, test(2, 0.01f), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-1.4f, test(3, -1.4f), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_fcmp01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_fcmp01 {
+
+    public static boolean test(float a, float b) {
+        return a < b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0f, -0.1f));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(78.00f, 78.001f));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_fcmp02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_fcmp02 {
+
+    public static boolean test(float a) {
+        return (a / a) < 0.0f;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-1.0f));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1.0f));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(0.0f));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_fcmp03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_fcmp03 {
+
+    public static boolean test(float a) {
+        return (a / a) > 0.0f;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-1.0f));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1.0f));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(0.0f));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_fcmp04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_fcmp04 {
+
+    public static boolean test(float a) {
+        return (a / a) <= 0.0f;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-1.0f));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1.0f));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(0.0f));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_fcmp05.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_fcmp05 {
+
+    public static boolean test(float a) {
+        return (a / a) >= 0.0f;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-1.0f));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1.0f));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(0.0f));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_fcmp06.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_fcmp06 {
+
+    public static boolean test(float a) {
+        return 0.0f < (a / a);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-1.0f));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1.0f));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(0.0f));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_fcmp07.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_fcmp07 {
+
+    public static boolean test(float a) {
+        return 0.0f > (a / a);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-1.0f));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1.0f));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(0.0f));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_fcmp08.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_fcmp08 {
+
+    public static boolean test(float a) {
+        return 0.0f <= (a / a);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-1.0f));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1.0f));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(0.0f));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_fcmp09.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_fcmp09 {
+
+    public static boolean test(float a) {
+        return 0.0f >= (a / a);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-1.0f));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1.0f));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(0.0f));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_fcmp10.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_fcmp10 {
+
+    public static boolean test(int x) {
+        float a = 0;
+        float b = 0;
+        switch (x) {
+            case 0:
+                a = Float.POSITIVE_INFINITY;
+                b = 1;
+                break;
+            case 1:
+                a = 1;
+                b = Float.POSITIVE_INFINITY;
+                break;
+            case 2:
+                a = Float.NEGATIVE_INFINITY;
+                b = 1;
+                break;
+            case 3:
+                a = 1;
+                b = Float.NEGATIVE_INFINITY;
+                break;
+            case 4:
+                a = Float.NEGATIVE_INFINITY;
+                b = Float.NEGATIVE_INFINITY;
+                break;
+            case 5:
+                a = Float.NEGATIVE_INFINITY;
+                b = Float.POSITIVE_INFINITY;
+                break;
+            case 6:
+                a = Float.NaN;
+                b = Float.POSITIVE_INFINITY;
+                break;
+            case 7:
+                a = 1;
+                b = Float.NaN;
+                break;
+            case 8:
+                a = 1;
+                b = -0.0f / 0.0f;
+                break;
+        }
+        return a <= b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(false, test(7));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(false, test(8));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_fdiv.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_fdiv {
+
+    public static float test(float a, float b) {
+        return a / b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(31.1f, test(311.0f, 10f), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_fload.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_fload {
+
+    public static float test(float arg) {
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-1f, test(-1f), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1.01f, test(-1.01f), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_fload_2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_fload_2 {
+
+    @SuppressWarnings("unused")
+    public static float test(float i, float arg) {
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-1f, test(0f, -1f), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1.01f, test(0f, -1.01f), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_fmul.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_fmul {
+
+    public static float test(float a, float b) {
+        return a * b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3110.0f, test(311.0f, 10f), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(22.4f, test(11.2f, 2.0f), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_fneg.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_fneg {
+
+    public static float test(float a) {
+        return -a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-0.0f, test(0.0f), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1.01f, test(-1.01f), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-7263.8734f, test(7263.8734f), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_frem.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+public class BC_frem {
+
+    public static float test(float a, float b) {
+        return a % b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1.0f, test(311.0f, 10f), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0.5f, test(12.5f, 6.0f), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_freturn.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_freturn {
+
+    public static float test(float a) {
+        return a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.0f, test(0.0f), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1.1f, test(1.1f), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1.4f, test(-1.4f), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(256.33f, test(256.33f), 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(1000.001f, test(1000.001f), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_fsub.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_fsub {
+
+    public static float test(float a, float b) {
+        return a - b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.0f, test(0.0f, 0.0f), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0.0f, test(1.0f, 1.0f), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(198.68f, test(253.11f, 54.43f), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_getfield.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_getfield {
+
+    private static BC_getfield object = new BC_getfield();
+
+    private int field = 13;
+
+    public static int test() {
+        return object.field;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(13, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_getstatic_b.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_getstatic_b {
+
+    private static byte field = 11;
+
+    public static byte test() {
+        return field;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((byte) 11), test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_getstatic_c.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_getstatic_c {
+
+    private static char field = 11;
+
+    public static char test() {
+        return field;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((char) 11), test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_getstatic_d.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_getstatic_d {
+
+    private static double field = 11;
+
+    public static double test() {
+        return field;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11d, test(), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_getstatic_f.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_getstatic_f {
+
+    private static float field = 11;
+
+    public static float test() {
+        return field;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11f, test(), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_getstatic_i.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_getstatic_i {
+
+    private static int field = 11;
+
+    public static int test() {
+        return field;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_getstatic_l.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_getstatic_l {
+
+    private static long field = 11;
+
+    public static long test() {
+        return field;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11L, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_getstatic_s.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_getstatic_s {
+
+    private static short field = 11;
+
+    public static short test() {
+        return field;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((short) 11), test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_getstatic_z.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_getstatic_z {
+
+    private static boolean field = true;
+
+    public static boolean test() {
+        return field;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_i2b.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_i2b {
+
+    public static byte test(int a) {
+        return (byte) a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((byte) -1), test(-1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((byte) 2), test(2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((byte) -1), test(255));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(((byte) -128), test(128));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_i2c.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_i2c {
+
+    public static char test(int a) {
+        return (char) a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((char) 65535), test(-1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((char) 645), test(645));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((char) 65535), test(65535));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_i2d.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_i2d {
+
+    public static double test(int a) {
+        return a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.0d, test(0), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1.0d, test(1), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-34.0d, test(-34), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_i2f.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_i2f {
+
+    public static float test(int a) {
+        return a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.0f, test(0), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1.0f, test(1), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-34.0f, test(-34), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_i2l.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_i2l {
+
+    public static long test(int a) {
+        return a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1L, test(1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2L, test(2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(3L, test(3));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-1L, test(-1));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-2147483647L, test(-2147483647));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(-2147483648L, test(-2147483648));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(2147483647L, test(2147483647));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_i2s.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_i2s {
+
+    public static short test(int a) {
+        return (short) a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((short) -1), test(-1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((short) 34), test(34));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((short) -1), test(65535));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(((short) -32768), test(32768));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iadd.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iadd {
+
+    public static int test(int a, int b) {
+        return a + b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3, test(1, 2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(0, -1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(100, test(33, 67));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0, test(1, -1));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-2147483647, test(-2147483648, 1));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(-2147483648, test(2147483647, 1));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(2147483647, test(-2147483647, -2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iadd2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iadd2 {
+
+    public static int test(byte a, byte b) {
+        return a + b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3, test(((byte) 1), ((byte) 2)));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(((byte) 0), ((byte) -1)));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(100, test(((byte) 33), ((byte) 67)));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0, test(((byte) 1), ((byte) -1)));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-127, test(((byte) -128), ((byte) 1)));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(128, test(((byte) 127), ((byte) 1)));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iadd3.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iadd3 {
+
+    public static int test(short a, short b) {
+        return a + b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3, test(((short) 1), ((short) 2)));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(((short) 0), ((short) -1)));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(100, test(((short) 33), ((short) 67)));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0, test(((short) 1), ((short) -1)));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-127, test(((short) -128), ((short) 1)));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(128, test(((short) 127), ((short) 1)));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(-32767, test(((short) -32768), ((short) 1)));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(32768, test(((short) 32767), ((short) 1)));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iaload.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iaload {
+
+    static int[] array = {0, -1, 4, 1000000000};
+
+    public static int test(int arg) {
+        return array[arg];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(4, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1000000000, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iand.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iand {
+
+    public static int test(int a, int b) {
+        return a & b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(1, 2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0, test(0, -1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(31, test(31, 63));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(4, test(6, 4));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0, test(-2147483648, 1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iastore.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iastore {
+
+    static int[] array = {0, 0, 0, 0};
+
+    public static int test(int arg, int val) {
+        array[arg] = val;
+        return array[arg];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0, 0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(1, -1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(11, test(2, 11));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-14, test(3, -14));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iconst.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iconst {
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return 0;
+        }
+        if (arg == 1) {
+            return 1;
+        }
+        if (arg == 2) {
+            return 2;
+        }
+        if (arg == 3) {
+            return 3;
+        }
+        if (arg == 4) {
+            return 4;
+        }
+        if (arg == 5) {
+            return 5;
+        }
+        return 375;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(3, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(4, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(5, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(375, test(6));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_idiv.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_idiv {
+
+    public static int test(int a, int b) {
+        return a / b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(1, 2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-2, test(2, -1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(64, test(256, 4));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(19, test(135, 7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_idiv2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_idiv2 {
+
+    public static int test(int a, int b) {
+        return a / b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-2147483648, test(-2147483648, -1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-2147483648, test(-2147483648, 1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ifeq.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ifeq {
+
+    public static int test(int a) {
+        int n = 0;
+        if (a == 0) {
+            n += 1;
+        } else {
+            n -= 1;
+        }
+        if (a != 0) {
+            n -= 1;
+        } else {
+            n += 1;
+        }
+        return n;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(2, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-2, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ifeq_2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ifeq_2 {
+
+    public static boolean test(int a) {
+        return a == 0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ifeq_3.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ifeq_3 {
+
+    public static boolean test(int a) {
+        return a != 0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ifge.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ifge {
+
+    public static int test(int a) {
+        int n = 0;
+        if (a >= 0) {
+            n += 1;
+        } else {
+            n -= 1;
+        }
+        if (a < 0) {
+            n -= 1;
+        } else {
+            n += 1;
+        }
+        return n;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(2, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-2, test(-1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ifge_2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ifge_2 {
+
+    public static boolean test(int a, int b) {
+        return a >= b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0, 1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1, 0));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(1, 1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(0, -100));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(-1, 0));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(-12, -12));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ifge_3.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ifge_3 {
+
+    public static boolean test(int a, int b) {
+        return a < b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0, 1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1, 0));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(1, 1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(0, -100));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(-1, 0));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(-12, -12));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ifgt.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ifgt {
+
+    public static int test(int a) {
+        int n = 0;
+        if (a > 0) {
+            n += 1;
+        } else {
+            n -= 1;
+        }
+        if (a <= 0) {
+            n -= 1;
+        } else {
+            n += 1;
+        }
+        return n;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-2, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-2, test(-1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ificmplt1.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ificmplt1 {
+
+    public static int test(int a) {
+        return a < 1 ? 12 : 13;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(12, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(13, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(13, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ificmplt2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ificmplt2 {
+
+    public static int test(int a) {
+        return a > 1 ? 13 : 12;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(12, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(12, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(13, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ificmpne1.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ificmpne1 {
+
+    public static int test(int a) {
+        return a == 1 ? 12 : 13;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(13, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(12, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(13, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ificmpne2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ificmpne2 {
+
+    public static int test(int a) {
+        return a != 1 ? 13 : 12;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(13, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(12, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(13, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ifle.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ifle {
+
+    public static int test(int a) {
+        int n = 0;
+        if (a <= 0) {
+            n += 1;
+        } else {
+            n -= 1;
+        }
+        if (a > 0) {
+            n -= 1;
+        } else {
+            n += 1;
+        }
+        return n;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(2, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-2, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(-1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iflt.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iflt {
+
+    public static int test(int a) {
+        int n = 0;
+        if (a < 0) {
+            n += 1;
+        } else {
+            n -= 1;
+        }
+        if (a >= 0) {
+            n -= 1;
+        } else {
+            n += 1;
+        }
+        return n;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-2, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-2, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(-1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ifne.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ifne {
+
+    public static int test(int a) {
+        int n = 0;
+        if (a != 0) {
+            n += 1;
+        } else {
+            n -= 1;
+        }
+        if (a == 0) {
+            n -= 1;
+        } else {
+            n += 1;
+        }
+        return n;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-2, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ifnonnull.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ifnonnull {
+
+    public static int test(Object a) {
+        int n = 0;
+        if (a == null) {
+            n += 1;
+        } else {
+            n -= 1;
+        }
+        if (a != null) {
+            n -= 1;
+        } else {
+            n += 1;
+        }
+        return n;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(2, test(null));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-2, test(""));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ifnonnull_2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ifnonnull_2 {
+
+    public static boolean test(Object a) {
+        return a != null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(null));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(""));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ifnonnull_3.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ifnonnull_3 {
+
+    public static int test(Object a) {
+        if (a != null) {
+            return 1;
+        }
+        return 2;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(2, test(null));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(""));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ifnull.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ifnull {
+
+    public static int test(Object a) {
+        int n = 0;
+        if (a != null) {
+            n += 1;
+        } else {
+            n -= 1;
+        }
+        if (a == null) {
+            n -= 1;
+        } else {
+            n += 1;
+        }
+        return n;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-2, test(null));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2, test(""));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ifnull_2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ifnull_2 {
+
+    public static boolean test(Object a) {
+        return a == null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(null));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(""));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ifnull_3.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ifnull_3 {
+
+    public static int test(Object a) {
+        if (a == null) {
+            return 1;
+        }
+        return 2;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1, test(null));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2, test(""));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iinc_1.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iinc_1 {
+
+    public static int test(int a) {
+        int arg = a;
+        arg += 1;
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(2, test(1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(3, test(2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(5, test(4));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0, test(-1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iinc_2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iinc_2 {
+
+    public static int test(int a) {
+        int arg = a;
+        arg += 2;
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3, test(1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(4, test(2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(6, test(4));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0, test(-2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iinc_3.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iinc_3 {
+
+    public static int test(int a) {
+        int arg = a;
+        arg += 51;
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(52, test(1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(53, test(2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(55, test(4));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(50, test(-1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iinc_4.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iinc_4 {
+
+    public static int test(int a) {
+        int arg = a;
+        arg += 512;
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(513, test(1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(514, test(2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(516, test(4));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(511, test(-1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iload_0.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iload_0 {
+
+    public static int test(int arg) {
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(-1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1000345, test(1000345));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iload_0_1.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iload_0_1 {
+
+    public static int test(int arg) {
+        return arg + 1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0, test(-1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(3, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1000346, test(1000345));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iload_0_2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iload_0_2 {
+
+    public static int test(int arg) {
+        int i = arg;
+        return i;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(-1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1000345, test(1000345));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iload_1.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iload_1 {
+
+    @SuppressWarnings("unused")
+    public static int test(int i, int arg) {
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(1, 0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(1, -1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(1, 2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1000345, test(1, 1000345));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iload_1_1.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iload_1_1 {
+
+    public static int test(int i) {
+        int arg = 0;
+        return i + arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(-1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1000345, test(1000345));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iload_2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iload_2 {
+
+    @SuppressWarnings("unused")
+    public static int test(int i, int j, int arg) {
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(1, 1, 0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(1, 1, -1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(1, 1, 2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1000345, test(1, 1, 1000345));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iload_3.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iload_3 {
+
+    @SuppressWarnings("unused")
+    public static int test(int i, int j, int k, int arg) {
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(1, 1, 1, 0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(1, 1, 1, -1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(1, 1, 1, 2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1000345, test(1, 1, 1, 1000345));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_imul.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_imul {
+
+    public static int test(int a, int b) {
+        return a * b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(2, test(1, 2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0, test(0, -1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2211, test(33, 67));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-1, test(1, -1));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-2147483648, test(-2147483648, 1));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(-2147483647, test(2147483647, -1));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(-2147483648, test(-2147483648, -1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ineg.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ineg {
+
+    public static int test(int a) {
+        return -a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(-1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-7263, test(7263));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-2147483648, test(-2147483648));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_instanceof.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_instanceof {
+
+    static Object object2 = new Object();
+    static Object object3 = "";
+    static Object object4 = new BC_instanceof();
+
+    public static boolean test(int arg) {
+        Object obj;
+        if (arg == 2) {
+            obj = object2;
+        } else if (arg == 3) {
+            obj = object3;
+        } else if (arg == 4) {
+            obj = object4;
+        } else {
+            obj = null;
+        }
+        return obj instanceof BC_instanceof;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_invokeinterface.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_invokeinterface {
+
+    public interface ITest {
+
+        int id(int a);
+    }
+
+    static class IClass implements ITest {
+
+        public int id(int a) {
+            return a;
+        }
+    }
+
+    static ITest object = new IClass();
+
+    public static int test(int a) {
+        return object.id(a);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(3, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-4, test(-4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_invokespecial.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_invokespecial {
+
+    static BC_invokespecial object = new BC_invokespecial();
+
+    public static int test(int a) {
+        return object.id(a);
+    }
+
+    @SuppressWarnings("static-method")
+    private int id(int i) {
+        return i;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(3, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-4, test(-4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_invokespecial2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_invokespecial2 {
+
+    static BC_invokespecial2 object = new BC_invokespecial2();
+
+    public static int test(int a) {
+        return 3 + object.id(a);
+    }
+
+    @SuppressWarnings("static-method")
+    private int id(int i) {
+        return 4 + i;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(7, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(8, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(9, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(10, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(3, test(-4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_invokestatic.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_invokestatic {
+
+    public static int test(int a) {
+        return id(a);
+    }
+
+    public static int id(int i) {
+        return i;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(3, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-4, test(-4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_invokevirtual.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_invokevirtual {
+
+    static BC_invokevirtual object = new BC_invokevirtual();
+
+    public static int test(int a) {
+        return object.id(a);
+    }
+
+    public int id(int i) {
+        return i;
+    }
+
+    public static void main(String[] args) {
+        test(0);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(3, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-4, test(-4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ior.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ior {
+
+    public static int test(int a, int b) {
+        return a | b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3, test(1, 2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(0, -1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(63, test(31, 63));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(6, test(6, 4));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-2147483647, test(-2147483648, 1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_irem.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_irem {
+
+    public static int test(int a, int b) {
+        return a % b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1, test(1, 2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0, test(2, -1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0, test(256, 4));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(2, test(135, 7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_irem2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_irem2 {
+
+    public static int test(int a, int b) {
+        return a % b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(-2147483648, -1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0, test(-2147483648, 1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_irem3.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_irem3 {
+
+    public static int test(int a) {
+        return a % 1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(-1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0, test(1000));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0, test(-2147483648));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0, test(2147483647));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ireturn.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ireturn {
+
+    public static int test(int a) {
+        return a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1, test(-1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(256, test(256));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ishl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ishl {
+
+    public static int test(int a, int b) {
+        return a << b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(4, test(1, 2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0, test(0, -1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(62, test(31, 1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(96, test(6, 4));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0, test(-2147483648, 1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ishr.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ishr {
+
+    public static int test(int a, int b) {
+        return a >> b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(1, 2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(16, test(67, 2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(15, test(31, 1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0, test(6, 4));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-32768, test(-2147483648, 16));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_isub.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_isub {
+
+    public static int test(int a, int b) {
+        return a - b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3, test(1, -2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(0, 1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(100, test(33, -67));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0, test(1, 1));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-2147483647, test(-2147483648, -1));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(-2147483648, test(2147483647, -1));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(2147483647, test(-2147483647, 2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_iushr.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_iushr {
+
+    public static int test(int a, int b) {
+        return a >>> b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(1, 2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(16, test(67, 2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(15, test(31, 1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0, test(6, 4));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(32768, test(-2147483648, 16));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ixor.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ixor {
+
+    public static int test(int a, int b) {
+        return a ^ b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3, test(1, 2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(0, -1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(32, test(31, 63));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(2, test(6, 4));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-2147483647, test(-2147483648, 1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_l2d.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_l2d {
+
+    public static double test(long a) {
+        return a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.0D, test(0L), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1.0D, test(1L), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-74652389.00D, test(-74652389L), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_l2f.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_l2f {
+
+    public static float test(long a) {
+        return a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.0f, test(0L), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1.0f, test(1L), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-74652389.00f, test(-74652389L), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_l2i.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ * TODO: test roundoff behavior
+ */
+public class BC_l2i {
+
+    public static int test(long a) {
+        return (int) a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1, test(1L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2, test(2L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(3, test(3L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-1, test(-1L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-2147483647, test(-2147483647L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(-2147483648, test(-2147483648L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(2147483647, test(2147483647L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_l2i_2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_l2i_2 {
+
+    static Object[] array = {null};
+
+    public static Object test(long a) {
+        long arg = a;
+        arg = arg << 32;
+        return array[(int) arg];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(null, test(1L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(null, test(123456789L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ladd.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ladd {
+
+    public static long test(long a, long b) {
+        return a + b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3L, test(1L, 2L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1L, test(0L, -1L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(100L, test(33L, 67L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0L, test(1L, -1L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-2147483647L, test(-2147483648L, 1L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(2147483648L, test(2147483647L, 1L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(-2147483649L, test(-2147483647L, -2L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ladd2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ladd2 {
+
+    public static long test(int a, int b) {
+        return a + (long) b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3L, test(1, 2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1L, test(0, -1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(100L, test(33, 67));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0L, test(1, -1));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-2147483647L, test(-2147483648, 1));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(2147483648L, test(2147483647, 1));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(-2147483649L, test(-2147483647, -2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_laload.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_laload {
+
+    static long[] array = {0L, -1L, 4L, 1000000000000L};
+
+    public static long test(int arg) {
+        return array[arg];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1L, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(4L, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1000000000000L, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_land.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_land {
+
+    public static long test(long a, long b) {
+        return a & b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(1L, 2L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0L, test(0L, -1L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(31L, test(31L, 63L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(4L, test(6L, 4L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0L, test(-2147483648L, 1L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lastore.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lastore {
+
+    static long[] array = {0, 0, 0, 0};
+
+    public static long test(int arg, long val) {
+        final long[] array2 = arg == -2 ? null : BC_lastore.array;
+        array2[arg] = val;
+        return array2[arg];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(0, 0L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1L, test(1, -1L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(11L, test(2, 11L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-14L, test(3, -14L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lcmp.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lcmp {
+
+    public static boolean test(long a, long b) {
+        return a < b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0L, -1L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(77L, 78L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(-1L, 0L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ldc_01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ldc_01 {
+
+    public static int test() {
+        return -123;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-123, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ldc_02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ldc_02 {
+
+    public static float test() {
+        return -2.4f;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-2.4f, test(), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ldc_03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ldc_03 {
+
+    public static long test() {
+        return -123L;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-123L, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ldc_04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ldc_04 {
+
+    public static String test() {
+        return "xyz";
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("xyz", test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ldc_05.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ldc_05 {
+
+    public static double test() {
+        return -2.33d;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-2.33d, test(), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ldc_06.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ldc_06 {
+
+    public static String test() {
+        return test2().getName();
+    }
+
+    static Class<BC_ldc_06> test2() {
+        return BC_ldc_06.class;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("com.oracle.max.graal.jtt.bytecode.BC_ldc_06", test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ldiv.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ldiv {
+
+    public static long test(long a, long b) {
+        return a / b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(1L, 2L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-2L, test(2L, -1L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(64L, test(256L, 4L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(19L, test(135L, 7L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_ldiv2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ldiv2 {
+
+    public static long test(long a, long b) {
+        return a / b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-9223372036854775808L, test(-9223372036854775808L, -1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-9223372036854775808L, test(-9223372036854775808L, 1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lload_0.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lload_0 {
+
+    public static long test(long arg) {
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1L, test(1L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-3L, test(-3L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(10000L, test(10000L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lload_01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+@SuppressWarnings("unused")
+public class BC_lload_01 {
+
+    public static long test(int i) {
+        return test1(null);
+    }
+
+    public static int test1(Object o0) {
+        long x = 1;
+        return 0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0L, test(-3));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0L, test(100));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lload_1.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lload_1 {
+
+    @SuppressWarnings("unused")
+    public static long test(int i, long arg) {
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1L, test(1, 1L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-3L, test(1, -3L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(10000L, test(1, 10000L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lload_2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lload_2 {
+
+    @SuppressWarnings("unused")
+    public static long test(int i, int j, long arg) {
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1L, test(1, 1, 1L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-3L, test(1, 1, -3L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(10000L, test(1, 1, 10000L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lload_3.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lload_3 {
+
+    @SuppressWarnings("unused")
+    public static long test(int i, int j, int k, long arg) {
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1L, test(1, 1, 1, 1L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-3L, test(1, 1, 1, -3L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(10000L, test(1, 1, 1, 10000L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lmul.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lmul {
+
+    public static long test(long a, long b) {
+        return a * b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(2L, test(1L, 2L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0L, test(0L, -1L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2211L, test(33L, 67L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-1L, test(1L, -1L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-2147483648L, test(-2147483648L, 1L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(-2147483647L, test(2147483647L, -1L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(2147483648L, test(-2147483648L, -1L));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(1000000000000L, test(1000000L, 1000000L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lneg.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lneg {
+
+    public static long test(long a) {
+        return -a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(0L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1L, test(-1L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-7263L, test(7263L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(2147483648L, test(-2147483648L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lookupswitch01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lookupswitch01 {
+
+    public static int test(int a) {
+        switch (a) {
+            case 67:
+                return 0;
+            case 97:
+                return 1;
+            case 107:
+                return 2;
+            case 133:
+                return 3;
+            case 212:
+                return 4;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(42, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(42, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(42, test(66));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0, test(67));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(42, test(68));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(42, test(96));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(1, test(97));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(42, test(98));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(42, test(106));
+    }
+
+    @Test
+    public void run9() throws Throwable {
+        Assert.assertEquals(2, test(107));
+    }
+
+    @Test
+    public void run10() throws Throwable {
+        Assert.assertEquals(42, test(108));
+    }
+
+    @Test
+    public void run11() throws Throwable {
+        Assert.assertEquals(42, test(132));
+    }
+
+    @Test
+    public void run12() throws Throwable {
+        Assert.assertEquals(3, test(133));
+    }
+
+    @Test
+    public void run13() throws Throwable {
+        Assert.assertEquals(42, test(134));
+    }
+
+    @Test
+    public void run14() throws Throwable {
+        Assert.assertEquals(42, test(211));
+    }
+
+    @Test
+    public void run15() throws Throwable {
+        Assert.assertEquals(4, test(212));
+    }
+
+    @Test
+    public void run16() throws Throwable {
+        Assert.assertEquals(42, test(213));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lookupswitch02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lookupswitch02 {
+
+    public static int test(int a) {
+        final int b = a;
+        switch (b) {
+            case 67:
+                return 0;
+            case 97:
+                return 1;
+            case 107:
+                return 2;
+            case 133:
+                return 3;
+            case 212:
+                return 4;
+            case -122:
+                return 5;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(42, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(42, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(42, test(66));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0, test(67));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(42, test(68));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(42, test(96));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(1, test(97));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(42, test(98));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(42, test(106));
+    }
+
+    @Test
+    public void run9() throws Throwable {
+        Assert.assertEquals(2, test(107));
+    }
+
+    @Test
+    public void run10() throws Throwable {
+        Assert.assertEquals(42, test(108));
+    }
+
+    @Test
+    public void run11() throws Throwable {
+        Assert.assertEquals(42, test(132));
+    }
+
+    @Test
+    public void run12() throws Throwable {
+        Assert.assertEquals(3, test(133));
+    }
+
+    @Test
+    public void run13() throws Throwable {
+        Assert.assertEquals(42, test(134));
+    }
+
+    @Test
+    public void run14() throws Throwable {
+        Assert.assertEquals(42, test(211));
+    }
+
+    @Test
+    public void run15() throws Throwable {
+        Assert.assertEquals(4, test(212));
+    }
+
+    @Test
+    public void run16() throws Throwable {
+        Assert.assertEquals(42, test(213));
+    }
+
+    @Test
+    public void run17() throws Throwable {
+        Assert.assertEquals(42, test(-121));
+    }
+
+    @Test
+    public void run18() throws Throwable {
+        Assert.assertEquals(5, test(-122));
+    }
+
+    @Test
+    public void run19() throws Throwable {
+        Assert.assertEquals(42, test(-123));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lookupswitch03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lookupswitch03 {
+
+    public static int test(int a) {
+        final int b = a + 10;
+        switch (b) {
+            case 77:
+                return 0;
+            case 107:
+                return 1;
+            case 117:
+                return 2;
+            case 143:
+                return 3;
+            case 222:
+                return 4;
+            case -112:
+                return 5;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(42, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(42, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(42, test(66));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0, test(67));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(42, test(68));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(42, test(96));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(1, test(97));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(42, test(98));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(42, test(106));
+    }
+
+    @Test
+    public void run9() throws Throwable {
+        Assert.assertEquals(2, test(107));
+    }
+
+    @Test
+    public void run10() throws Throwable {
+        Assert.assertEquals(42, test(108));
+    }
+
+    @Test
+    public void run11() throws Throwable {
+        Assert.assertEquals(42, test(132));
+    }
+
+    @Test
+    public void run12() throws Throwable {
+        Assert.assertEquals(3, test(133));
+    }
+
+    @Test
+    public void run13() throws Throwable {
+        Assert.assertEquals(42, test(134));
+    }
+
+    @Test
+    public void run14() throws Throwable {
+        Assert.assertEquals(42, test(211));
+    }
+
+    @Test
+    public void run15() throws Throwable {
+        Assert.assertEquals(4, test(212));
+    }
+
+    @Test
+    public void run16() throws Throwable {
+        Assert.assertEquals(42, test(213));
+    }
+
+    @Test
+    public void run17() throws Throwable {
+        Assert.assertEquals(42, test(-121));
+    }
+
+    @Test
+    public void run18() throws Throwable {
+        Assert.assertEquals(5, test(-122));
+    }
+
+    @Test
+    public void run19() throws Throwable {
+        Assert.assertEquals(42, test(-123));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lookupswitch04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lookupswitch04 {
+
+    public static int test(int a) {
+        final int b = a + 8;
+        final int c = b + 2;
+        switch (c) {
+            case 77:
+                return 0;
+            case 107:
+                return 1;
+            case 117:
+                return 2;
+            case 143:
+                return 3;
+            case 222:
+                return 4;
+            case -112:
+                return 5;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(42, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(42, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(42, test(66));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0, test(67));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(42, test(68));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(42, test(96));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(1, test(97));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(42, test(98));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(42, test(106));
+    }
+
+    @Test
+    public void run9() throws Throwable {
+        Assert.assertEquals(2, test(107));
+    }
+
+    @Test
+    public void run10() throws Throwable {
+        Assert.assertEquals(42, test(108));
+    }
+
+    @Test
+    public void run11() throws Throwable {
+        Assert.assertEquals(42, test(132));
+    }
+
+    @Test
+    public void run12() throws Throwable {
+        Assert.assertEquals(3, test(133));
+    }
+
+    @Test
+    public void run13() throws Throwable {
+        Assert.assertEquals(42, test(134));
+    }
+
+    @Test
+    public void run14() throws Throwable {
+        Assert.assertEquals(42, test(211));
+    }
+
+    @Test
+    public void run15() throws Throwable {
+        Assert.assertEquals(4, test(212));
+    }
+
+    @Test
+    public void run16() throws Throwable {
+        Assert.assertEquals(42, test(213));
+    }
+
+    @Test
+    public void run17() throws Throwable {
+        Assert.assertEquals(42, test(-121));
+    }
+
+    @Test
+    public void run18() throws Throwable {
+        Assert.assertEquals(5, test(-122));
+    }
+
+    @Test
+    public void run19() throws Throwable {
+        Assert.assertEquals(42, test(-123));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lookupswitch05.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lookupswitch05 {
+
+    public static Object test(int a) {
+        switch (a) {
+            default:
+                return new String();
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("", test(0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lor.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lor {
+
+    public static long test(long a, long b) {
+        return a | b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3L, test(1L, 2L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1L, test(0L, -1L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(63L, test(31L, 63L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(6L, test(6L, 4L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-2147483647L, test(-2147483648L, 1L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lrem.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lrem {
+
+    public static long test(long a, long b) {
+        return a % b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1L, test(1L, 2L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0L, test(2L, -1L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0L, test(256L, 4L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(2L, test(135L, 7L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lrem2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lrem2 {
+
+    public static long test(long a, long b) {
+        return a % b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(-9223372036854775808L, -1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0L, test(-9223372036854775808L, 1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lreturn.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lreturn {
+
+    public static long test(long a) {
+        return a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(0L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1L, test(1L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1L, test(-1L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(256L, test(256L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(1000000000000L, test(1000000000000L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lshl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lshl {
+
+    public static long test(long a, int b) {
+        return a << b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(4L, test(1L, 2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0L, test(0L, -1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(62L, test(31L, 1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(96L, test(6L, 4));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-4294967296L, test(-2147483648L, 1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lshr.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lshr {
+
+    public static long test(long a, int b) {
+        return a >> b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(1L, 2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(16L, test(67L, 2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(15L, test(31L, 1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0L, test(6L, 4));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-32768L, test(-2147483648L, 16));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lsub.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lsub {
+
+    public static long test(long a, long b) {
+        return a - b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3L, test(1L, -2L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1L, test(0L, 1L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(100L, test(33L, -67L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0L, test(1L, 1L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-2147483647L, test(-2147483648L, -1L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(2147483648L, test(2147483647L, -1L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(-2147483649L, test(-2147483647L, 2L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lushr.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lushr {
+
+    public static long test(long a, int b) {
+        return a >>> b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(1L, 2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(16L, test(67L, 2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(15L, test(31L, 1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0L, test(6L, 4));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(281474976677888L, test(-2147483648L, 16));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_lxor.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lxor {
+
+    public static long test(long a, long b) {
+        return a ^ b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3L, test(1L, 2L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1L, test(0L, -1L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(32L, test(31L, 63L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(2L, test(6L, 4L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-2147483647L, test(-2147483648L, 1L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_monitorenter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_monitorenter {
+
+    static BC_monitorenter object = new BC_monitorenter();
+
+    public static int test(int arg) {
+        synchronized (object) {
+            return arg;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-2, test(-2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_monitorenter02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2010, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_monitorenter02 {
+
+    static BC_monitorenter02 object = new BC_monitorenter02();
+
+    public static int test(int arg, int arg2) {
+        int result = arg;
+        synchronized (object) {
+            result = arg / arg2;
+        }
+        synchronized (object) {
+            result = arg / arg2;
+        }
+        return result;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0, 1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1, 1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-2, test(-2, 1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_multianewarray01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_multianewarray01 {
+
+    public static int test(int a) {
+        final BC_multianewarray01[][] v = new BC_multianewarray01[3][3];
+        return v != null ? a : -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_multianewarray02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_multianewarray02 {
+
+    public static int test(int a) {
+        final BC_multianewarray02[][][][] v = new BC_multianewarray02[3][3][3][3];
+        return v != null ? a : -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_multianewarray03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_multianewarray03 {
+
+    public static int test(int a) {
+        final BC_multianewarray03[][][][] v = new BC_multianewarray03[a][a][a][a];
+        return v.length + v[0].length + v[0][0].length + v[0][0][0].length;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(4, test(1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(8, test(2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(12, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_multianewarray04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_multianewarray04 {
+
+    public static int test(int a) {
+        int i = 1;
+
+        i += test_byte(a);
+        i += test_boolean(a);
+        i += test_char(a);
+        i += test_short(a);
+        i += test_int(a);
+        i += test_float(a);
+        i += test_long(a);
+        i += test_double(a);
+
+        return i;
+    }
+
+    private static int test_double(int a) {
+        double[][] b2 = new double[a][a];
+        double[][][] b3 = new double[a][a][a];
+        double[][][][] b4 = new double[a][a][a][a];
+        double[][][][][] b5 = new double[a][a][a][a][a];
+        double[][][][][][] b6 = new double[a][a][a][a][a][a];
+        return b2.length + b3.length + b4.length + b5.length + b6.length;
+    }
+
+    private static int test_long(int a) {
+        long[][] b2 = new long[a][a];
+        long[][][] b3 = new long[a][a][a];
+        long[][][][] b4 = new long[a][a][a][a];
+        long[][][][][] b5 = new long[a][a][a][a][a];
+        long[][][][][][] b6 = new long[a][a][a][a][a][a];
+        return b2.length + b3.length + b4.length + b5.length + b6.length;
+    }
+
+    private static int test_float(int a) {
+        float[][] b2 = new float[a][a];
+        float[][][] b3 = new float[a][a][a];
+        float[][][][] b4 = new float[a][a][a][a];
+        float[][][][][] b5 = new float[a][a][a][a][a];
+        float[][][][][][] b6 = new float[a][a][a][a][a][a];
+        return b2.length + b3.length + b4.length + b5.length + b6.length;
+    }
+
+    private static int test_int(int a) {
+        int[][] b2 = new int[a][a];
+        int[][][] b3 = new int[a][a][a];
+        int[][][][] b4 = new int[a][a][a][a];
+        int[][][][][] b5 = new int[a][a][a][a][a];
+        int[][][][][][] b6 = new int[a][a][a][a][a][a];
+        return b2.length + b3.length + b4.length + b5.length + b6.length;
+    }
+
+    private static int test_short(int a) {
+        short[][] b2 = new short[a][a];
+        short[][][] b3 = new short[a][a][a];
+        short[][][][] b4 = new short[a][a][a][a];
+        short[][][][][] b5 = new short[a][a][a][a][a];
+        short[][][][][][] b6 = new short[a][a][a][a][a][a];
+        return b2.length + b3.length + b4.length + b5.length + b6.length;
+    }
+
+    private static int test_char(int a) {
+        char[][] b2 = new char[a][a];
+        char[][][] b3 = new char[a][a][a];
+        char[][][][] b4 = new char[a][a][a][a];
+        char[][][][][] b5 = new char[a][a][a][a][a];
+        char[][][][][][] b6 = new char[a][a][a][a][a][a];
+        return b2.length + b3.length + b4.length + b5.length + b6.length;
+    }
+
+    private static int test_boolean(int a) {
+        boolean[][] b2 = new boolean[a][a];
+        boolean[][][] b3 = new boolean[a][a][a];
+        boolean[][][][] b4 = new boolean[a][a][a][a];
+        boolean[][][][][] b5 = new boolean[a][a][a][a][a];
+        boolean[][][][][][] b6 = new boolean[a][a][a][a][a][a];
+        return b2.length + b3.length + b4.length + b5.length + b6.length;
+    }
+
+    private static int test_byte(int a) {
+        byte[][] b2 = new byte[a][a];
+        byte[][][] b3 = new byte[a][a][a];
+        byte[][][][] b4 = new byte[a][a][a][a];
+        byte[][][][][] b5 = new byte[a][a][a][a][a];
+        byte[][][][][][] b6 = new byte[a][a][a][a][a][a];
+        return b2.length + b3.length + b4.length + b5.length + b6.length;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(41, test(1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(81, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_new.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_new {
+
+    @SuppressWarnings("unused")
+    public static int test(int a) {
+        new BC_new();
+        return a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_newarray.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_newarray {
+
+    public static int test(int a) {
+        if (new boolean[3] == null) {
+            return -1;
+        }
+        if (new char[3] == null) {
+            return -1;
+        }
+        if (new float[3] == null) {
+            return -1;
+        }
+        if (new double[3] == null) {
+            return -1;
+        }
+        if (new byte[3] == null) {
+            return -1;
+        }
+        if (new short[3] == null) {
+            return -1;
+        }
+        if (new int[3] == null) {
+            return -1;
+        }
+        if (new long[3] == null) {
+            return -1;
+        }
+
+        return a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_putfield.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_putfield {
+
+    private static BC_putfield object = new BC_putfield();
+
+    private int field;
+
+    public static int test(int arg) {
+        object.field = arg;
+        return object.field;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-4, test(-4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_putstatic.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_putstatic {
+
+    private static int field;
+
+    public static int test(int a) {
+        field = a;
+        return field;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(3, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-4, test(-4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_saload.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_saload {
+
+    static short[] array = {0, -1, 4, 10000};
+
+    public static short test(int arg) {
+        return array[arg];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((short) 0), test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((short) -1), test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((short) 4), test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(((short) 10000), test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_sastore.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_sastore {
+
+    static short[] array = {0, 0, 0, 0};
+
+    public static short test(int arg, short val) {
+        array[arg] = val;
+        return array[arg];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((short) 0), test(0, ((short) 0)));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((short) -1), test(1, ((short) -1)));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((short) 11), test(2, ((short) 11)));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(((short) -14), test(3, ((short) -14)));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_tableswitch.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_tableswitch {
+
+    public static int test(int a) {
+        switch (a) {
+            case 0:
+                return 10;
+            case 1:
+                return 20;
+            case 2:
+                return 30;
+            case 4:
+                return 40;
+            case 5:
+                return 50;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(42, test(-1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(10, test(0));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(20, test(1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(30, test(2));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(42, test(3));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(40, test(4));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(50, test(5));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(42, test(6));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_tableswitch2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_tableswitch2 {
+
+    public static int test(int a) {
+        switch (a) {
+            case 5:
+                return 55;
+            case 6:
+                return 66;
+            case 7:
+                return 77;
+        }
+        return 11;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11, test(-1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11, test(0));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(11, test(1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(55, test(5));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(66, test(6));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(77, test(7));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(11, test(8));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_tableswitch3.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_tableswitch3 {
+
+    public static int test(int a) {
+        switch (a) {
+            case -2:
+                return 22;
+            case -1:
+                return 11;
+            case 0:
+                return 33;
+            case 1:
+                return 77;
+        }
+        return 99;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11, test(-1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(22, test(-2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(99, test(-3));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(99, test(-4));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(77, test(1));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(99, test(2));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(99, test(10));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_tableswitch4.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_tableswitch4 {
+
+    public static int test(int a) {
+        switch (a) {
+            case -5:
+                return 55;
+            case -4:
+                return 44;
+            case -3:
+                return 33;
+        }
+        return 11;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11, test(-1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11, test(0));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(11, test(1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(55, test(-5));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(44, test(-4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(33, test(-3));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(11, test(-8));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_wide01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_wide01 {
+
+    @SuppressWarnings("unused")
+    public static int test(int arg) {
+
+        // Checkstyle: stop
+        long i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15;
+        long j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
+        long k0, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15;
+        long l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15;
+        long m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15;
+        long n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15;
+        long o0, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15;
+        long p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15;
+        long q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, q13, q14, q15;
+        long r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15;
+        // Checkstyle: resume
+
+        int i255 = 10;
+        return arg + i255 + 1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(12, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/bytecode/BC_wide02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_wide02 {
+
+    @SuppressWarnings("unused")
+    public static int test(int arg) {
+
+        // Checkstyle: stop
+        long i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15;
+        long j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
+        long k0, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15;
+        long l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15;
+        long m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15;
+        long n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15;
+        long o0, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15;
+        long p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15;
+        long q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, q13, q14, q15;
+        long r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15;
+        // Checkstyle: resume
+
+        int i255 = 9;
+        i255++;
+        return arg + i255 + 1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(12, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_aaload0.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_aaload0 {
+
+    static Object[] array = {null, null, ""};
+
+    public static Object test(int arg) {
+        final Object[] obj = arg == -2 ? null : array;
+        return obj[arg];
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run0() throws Throwable {
+        test(-2);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(-1);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(null, test(0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_aaload1.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_aaload1 {
+
+    static Object[] array = {null, null, ""};
+
+    public static Object test(int arg) {
+        final Object[] obj = arg == -2 ? null : array;
+        try {
+            return obj[arg];
+        } catch (NullPointerException e) {
+            return null;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(null, test(-2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(-1);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(null, test(0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_aastore0.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_aastore0 {
+
+    static Object[] param = {new Object(), null, "h"};
+    static Object[] arr = {null, null, null};
+    static String[] arr2 = {null, null, null};
+
+    public static int test(boolean a, int indx) {
+        Object[] array = a ? arr : arr2;
+        Object val;
+        if (indx == -2) {
+            array = null;
+            val = null;
+        } else {
+            val = param[indx];
+        }
+        array[indx] = val;
+        return indx;
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run0() throws Throwable {
+        test(true, -2);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(true, -1);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0, test(true, 0));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1, test(true, 1));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(2, test(true, 2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run5() throws Throwable {
+        test(true, 3);
+    }
+
+    @Test(expected = java.lang.ArrayStoreException.class)
+    public void run6() throws Throwable {
+        test(false, 0);
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(1, test(false, 1));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(2, test(false, 2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run9() throws Throwable {
+        test(false, 3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_aastore1.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_aastore1 {
+
+    static Object[] param = {new Object(), null, "h"};
+    static Object[] arr = {null, null, null};
+    static String[] arr2 = {null, null, null};
+
+    public static int test(boolean a, int indx) {
+        try {
+            Object[] array = a ? arr : arr2;
+            Object val;
+            if (indx == -2) {
+                array = null;
+                val = null;
+            } else {
+                val = param[indx];
+            }
+            array[indx] = val;
+            return indx;
+        } catch (NullPointerException e) {
+            return 5;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(5, test(true, -2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(true, -1);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0, test(true, 0));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1, test(true, 1));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(2, test(true, 2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run5() throws Throwable {
+        test(true, 3);
+    }
+
+    @Test(expected = java.lang.ArrayStoreException.class)
+    public void run6() throws Throwable {
+        test(false, 0);
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(1, test(false, 1));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(2, test(false, 2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run9() throws Throwable {
+        test(false, 3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_anewarray.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_anewarray {
+
+    @SuppressWarnings("unused")
+    public static int test(int a) {
+        final BC_anewarray[] v = new BC_anewarray[a];
+        if (v != null) {
+            return a;
+        }
+        return -1;
+    }
+
+    @Test(expected = java.lang.NegativeArraySizeException.class)
+    public void run0() throws Throwable {
+        test(-1);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_arraylength.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_arraylength {
+
+    static int[] arr = {1, 2, 3};
+    static char[] arr2 = {'a', 'b', 'c', 'd'};
+    static Object[] arr3 = new Object[5];
+
+    @SuppressWarnings("all")
+    public static int test(int arg) {
+        if (arg == 0) {
+            int[] array = null;
+            return array.length;
+        }
+        if (arg == 1) {
+            return arr.length;
+        }
+        if (arg == 2) {
+            return arr2.length;
+        }
+        if (arg == 3) {
+            return arr3.length;
+        }
+        return 42;
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run0() throws Throwable {
+        test(0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(3, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(4, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(5, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(42, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_athrow0.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_athrow0 {
+
+    static Throwable throwable = new Throwable();
+
+    public static int test(int arg) throws Throwable {
+        if (arg == 2) {
+            throw throwable;
+        }
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test(expected = java.lang.Throwable.class)
+    public void run1() throws Throwable {
+        test(2);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_athrow1.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_athrow1 {
+
+    static Throwable throwable = new Throwable();
+
+    public static int test(int arg) throws Throwable {
+        if (arg == 2) {
+            throw throwable;
+        }
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test(expected = java.lang.Throwable.class)
+    public void run2() throws Throwable {
+        test(2);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(3, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_athrow2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_athrow2 {
+
+    static Throwable throwable = new Throwable();
+
+    public static int test(int arg) throws Throwable {
+        if (arg == 2) {
+            throw throwable;
+        } else if (arg == 3) {
+            throw null;
+        }
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test(expected = java.lang.Throwable.class)
+    public void run1() throws Throwable {
+        test(2);
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run2() throws Throwable {
+        test(3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_athrow3.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_athrow3 {
+
+    static Throwable throwable = new Throwable();
+
+    public static int test(int arg) throws Throwable {
+        if (arg == 2) {
+            throw2();
+        } else if (arg == 3) {
+            throw1();
+        }
+        return arg;
+    }
+
+    private static void throw2() throws Throwable {
+        throw throwable;
+    }
+
+    private static void throw1() throws Throwable {
+        throw null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test(expected = java.lang.Throwable.class)
+    public void run1() throws Throwable {
+        test(2);
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run2() throws Throwable {
+        test(3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_baload.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_baload {
+
+    static boolean[] arr = {true, false, true, false};
+
+    public static boolean test(int arg) {
+        final boolean[] array = arg == -2 ? null : arr;
+        return array[arg];
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run0() throws Throwable {
+        test(-2);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(-1);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(4);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_bastore.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_bastore {
+
+    static boolean[] arr = {false, false, false, false};
+
+    public static boolean test(int arg, boolean val) {
+        final boolean[] array = arg == -2 ? null : arr;
+        array[arg] = val;
+        return array[arg];
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run0() throws Throwable {
+        test(-2, true);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(-1, false);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(0, true));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(4, true);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_caload.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_caload {
+
+    static char[] arr = {'\000', 'a', ' ', 10000};
+
+    public static char test(int arg) {
+        final char[] array = arg == -2 ? null : arr;
+        return array[arg];
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run0() throws Throwable {
+        test(-2);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(-1);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((char) 0), test(0));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(4);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_castore.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_castore {
+
+    static char[] arr = {0, 0, 0, 0};
+
+    public static char test(int arg, char val) {
+        final char[] array = arg == -2 ? null : arr;
+        array[arg] = val;
+        return array[arg];
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run0() throws Throwable {
+        test(-2, ((char) 97));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(-1, ((char) 99));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((char) 97), test(0, ((char) 97)));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(4, ((char) 97));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_checkcast.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_checkcast {
+
+    static Object object2 = new Object();
+    static Object object3 = "";
+    static Object object4 = new BC_checkcast();
+
+    public static int test(int arg) {
+        Object obj = null;
+        if (arg == 2) {
+            obj = object2;
+        }
+        if (arg == 3) {
+            obj = object3;
+        }
+        if (arg == 4) {
+            obj = object4;
+        }
+        final BC_checkcast bc = (BC_checkcast) obj;
+        if (bc == null) {
+            return arg;
+        }
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test(expected = java.lang.ClassCastException.class)
+    public void run1() throws Throwable {
+        test(2);
+    }
+
+    @Test(expected = java.lang.ClassCastException.class)
+    public void run2() throws Throwable {
+        test(3);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(4, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_checkcast1.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_checkcast1 {
+
+    static Object object2 = new Object();
+    static Object object3 = "";
+    static Object object4 = new BC_checkcast1();
+
+    public static int test(int arg) {
+        Object obj = null;
+        if (arg == 2) {
+            obj = object2;
+        }
+        if (arg == 3) {
+            obj = object3;
+        }
+        if (arg == 4) {
+            obj = object4;
+        }
+        final BC_checkcast1 bc = (BC_checkcast1) obj;
+        if (bc == null) {
+            return arg;
+        }
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test(expected = java.lang.ClassCastException.class)
+    public void run1() throws Throwable {
+        test(2);
+    }
+
+    @Test(expected = java.lang.ClassCastException.class)
+    public void run2() throws Throwable {
+        test(3);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(4, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_checkcast2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_checkcast2 {
+
+    static Object object2 = new Object();
+    static Object object3 = "";
+    static Object object4 = new com.oracle.max.graal.jtt.except.BC_checkcast2();
+
+    public static int test(int arg) {
+        Object obj;
+        if (arg == 2) {
+            obj = object2;
+        } else if (arg == 3) {
+            obj = object3;
+        } else if (arg == 4) {
+            obj = object4;
+        } else {
+            obj = null;
+        }
+        final BC_checkcast2 bc = (BC_checkcast2) obj;
+        if (bc != null) {
+            return arg;
+        }
+        return -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-1, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(1));
+    }
+
+    @Test(expected = java.lang.ClassCastException.class)
+    public void run2() throws Throwable {
+        test(2);
+    }
+
+    @Test(expected = java.lang.ClassCastException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(4, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_checkcast3.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_checkcast3 {
+
+    static Object[] o1 = {new Object()};
+    static String[] o2 = {""};
+    static BC_checkcast3[] o3 = {new BC_checkcast3()};
+
+    public static int test(int arg) {
+        Object obj = null;
+        if (arg == 0) {
+            obj = o1;
+        }
+        if (arg == 1) {
+            obj = o2;
+        }
+        if (arg == 2) {
+            obj = o3;
+        }
+        Object[] r = (BC_checkcast3[]) obj;
+        return r == null ? -1 : -1;
+    }
+
+    @Test(expected = java.lang.ClassCastException.class)
+    public void run0() throws Throwable {
+        test(0);
+    }
+
+    @Test(expected = java.lang.ClassCastException.class)
+    public void run1() throws Throwable {
+        test(1);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-1, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_checkcast4.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+@SuppressWarnings("static-method")
+public final class BC_checkcast4 {
+
+    static Object object2 = new Object();
+    static Object object3 = "";
+    static Object object4 = new BC_checkcast4();
+
+    public static int test(int arg) {
+        Object obj;
+        if (arg == 2) {
+            obj = object2;
+        } else if (arg == 3) {
+            obj = object3;
+        } else if (arg == 4) {
+            obj = object4;
+        } else {
+            obj = null;
+        }
+        final BC_checkcast4 bc = (BC_checkcast4) obj;
+        if (bc != null) {
+            return arg;
+        }
+        return -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-1, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(1));
+    }
+
+    @Test(expected = java.lang.ClassCastException.class)
+    public void run2() throws Throwable {
+        test(2);
+    }
+
+    @Test(expected = java.lang.ClassCastException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(4, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_checkcast5.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2010, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_checkcast5 {
+
+    static Object object2 = new Object();
+    static Object object3 = "";
+    static Object object4 = new BC_checkcast5();
+
+    public static int test(int arg) {
+        Object obj;
+        if (arg == 2) {
+            obj = object2;
+        } else if (arg == 3) {
+            obj = object3;
+        } else if (arg == 4) {
+            obj = object4;
+        } else {
+            obj = null;
+        }
+        try {
+            final BC_checkcast5 bc = (BC_checkcast5) obj;
+            if (bc != null) {
+                return arg;
+            }
+        } catch (ClassCastException e) {
+            return -5;
+        }
+        return -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-1, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-5, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-5, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(4, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_checkcast6.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2010, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+@SuppressWarnings("static-method")
+public final class BC_checkcast6 {
+
+    static Object object2 = new Object();
+    static Object object3 = "";
+    static Object object4 = new BC_checkcast6();
+
+    public static int test(int arg) {
+        Object obj;
+        if (arg == 2) {
+            obj = object2;
+        } else if (arg == 3) {
+            obj = object3;
+        } else if (arg == 4) {
+            obj = object4;
+        } else {
+            obj = null;
+        }
+        try {
+            final BC_checkcast6 bc = (BC_checkcast6) obj;
+            if (bc != null) {
+                return arg;
+            }
+        } catch (ClassCastException e) {
+            return -5;
+        }
+        return -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-1, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-5, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-5, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(4, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_daload.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_daload {
+
+    static double[] arr = {0.0, -1.1, 4.32, 6.06};
+
+    public static double test(int arg) {
+        final double[] array = arg == -2 ? null : arr;
+        return array[arg];
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run0() throws Throwable {
+        test(-2);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(-1);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0.0d, test(0), 0);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(4);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_dastore.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_dastore {
+
+    static double[] arr = {0, 0, 0, 0};
+
+    public static double test(int arg, double val) {
+        final double[] array = arg == -2 ? null : arr;
+        array[arg] = val;
+        return array[arg];
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run0() throws Throwable {
+        test(-2, 0.01d);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(-1, -1.4d);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0.01d, test(0, 0.01d), 0);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(4, 0.01d);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_faload.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_faload {
+
+    static float[] arr = {0.0f, -1.1f, 4.32f, 6.06f};
+
+    public static float test(int arg) {
+        final float[] array = arg == -2 ? null : arr;
+        return array[arg];
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run0() throws Throwable {
+        test(-2);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(-1);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0.0f, test(0), 0);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(4);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_fastore.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_fastore {
+
+    static float[] arr = {0, 0, 0, 0};
+
+    public static float test(int arg, float val) {
+        final float[] array = arg == -2 ? null : arr;
+        array[arg] = val;
+        return array[arg];
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run0() throws Throwable {
+        test(-2, 0.01f);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(-1, -1.4f);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0.01f, test(0, 0.01f), 0);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(4, 0.01f);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_getfield.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_getfield {
+
+    private static BC_getfield object = new BC_getfield();
+
+    private int field = 13;
+
+    public static int test(int arg) {
+        final BC_getfield obj = (arg == 3) ? null : object;
+        return obj.field;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(13, test(0));
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run1() throws Throwable {
+        test(3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_iaload.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_iaload {
+
+    static int[] arr = {0, -1, 4, 1000000000};
+
+    public static int test(int arg) {
+        final int[] array = arg == -2 ? null : arr;
+        return array[arg];
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run0() throws Throwable {
+        test(-2);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(-1);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(4);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_iastore.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_iastore {
+
+    static int[] arr = {0, 0, 0, 0};
+
+    public static int test(int arg, int val) {
+        final int[] array = arg == -2 ? null : arr;
+        array[arg] = val;
+        return array[arg];
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run0() throws Throwable {
+        test(-2, 0);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(-1, 3);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0, test(0, 0));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(4, 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_idiv.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_idiv {
+
+    public static int test(int a, int b) {
+        return a / b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(1, 2));
+    }
+
+    @Test(expected = java.lang.ArithmeticException.class)
+    public void run1() throws Throwable {
+        test(11, 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_idiv2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ */
+
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_idiv2 {
+
+    public static int test(int a, int b) {
+        try {
+            return a / b;
+        } catch (Exception e) {
+            return -11;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(1, 2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-11, test(11, 0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_invokespecial01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+@SuppressWarnings("static-method")
+public class BC_invokespecial01 {
+
+    private static final BC_invokespecial01 obj = new BC_invokespecial01();
+
+    public static boolean test(int arg) {
+        BC_invokespecial01 object = null;
+        if (arg == 0) {
+            object = obj;
+        }
+        return object.method();
+    }
+
+    private boolean method() {
+        return true;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run1() throws Throwable {
+        test(1);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_invokevirtual01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_invokevirtual01 {
+
+    private static final BC_invokevirtual01 obj = new BC_invokevirtual01();
+
+    public static boolean test(int arg) {
+        BC_invokevirtual01 object = null;
+        if (arg == 0) {
+            object = obj;
+        }
+        return object.method();
+    }
+
+    public boolean method() {
+        return true;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run1() throws Throwable {
+        test(1);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_invokevirtual02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+@SuppressWarnings("static-method")
+public class BC_invokevirtual02 {
+
+    private static final BC_invokevirtual02 obj = new BC_invokevirtual02();
+
+    public static boolean test(int arg) {
+        BC_invokevirtual02 object = null;
+        if (arg == 0) {
+            object = obj;
+        }
+        return object.method();
+    }
+
+    public final boolean method() {
+        return true;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run1() throws Throwable {
+        test(1);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_irem.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_irem {
+
+    public static int test(int a, int b) {
+        return a % b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1, test(1, 2));
+    }
+
+    @Test(expected = java.lang.ArithmeticException.class)
+    public void run1() throws Throwable {
+        test(11, 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_laload.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_laload {
+
+    static long[] arr = {0L, -1L, 4L, 1000000000000L};
+
+    public static long test(int arg) {
+        final long[] array = arg == -2 ? null : arr;
+        return array[arg];
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run0() throws Throwable {
+        test(-2);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(-1);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0L, test(0));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(4);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_lastore.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_lastore {
+
+    static long[] arr = {0, 0, 0, 0};
+
+    public static long test(int arg, long val) {
+        final long[] array = arg == -2 ? null : arr;
+        array[arg] = val;
+        return array[arg];
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run0() throws Throwable {
+        test(-2, 0L);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(-1, 3L);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0L, test(0, 0L));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(4, 0L);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_ldiv.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_ldiv {
+
+    public static long test(long a, long b) {
+        return a / b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(1L, 2L));
+    }
+
+    @Test(expected = java.lang.ArithmeticException.class)
+    public void run1() throws Throwable {
+        test(11L, 0L);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_ldiv2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ */
+
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_ldiv2 {
+
+    public static long test(long a, long b) {
+        try {
+            return a / b;
+        } catch (Exception e) {
+            return -11;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(1L, 2L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-11L, test(11L, 0L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_lrem.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_lrem {
+
+    public static long test(long a, long b) {
+        return a % b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1L, test(1L, 2L));
+    }
+
+    @Test(expected = java.lang.ArithmeticException.class)
+    public void run1() throws Throwable {
+        test(11L, 0L);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_monitorenter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_monitorenter {
+
+    static com.oracle.max.graal.jtt.bytecode.BC_monitorenter object = new com.oracle.max.graal.jtt.bytecode.BC_monitorenter();
+
+    public static boolean test(boolean arg) {
+        final Object o = arg ? object : null;
+        synchronized (o) {
+            return arg;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(true));
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run1() throws Throwable {
+        test(false);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_multianewarray.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_multianewarray {
+
+    @SuppressWarnings("unused")
+    public static int test(int a, int b) {
+        final BC_multianewarray[][] v = new BC_multianewarray[a][b];
+        if (v != null) {
+            return a;
+        }
+        return -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0, 0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1, 1));
+    }
+
+    @Test(expected = java.lang.NegativeArraySizeException.class)
+    public void run2() throws Throwable {
+        test(-1, 0);
+    }
+
+    @Test(expected = java.lang.NegativeArraySizeException.class)
+    public void run3() throws Throwable {
+        test(0, -1);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_newarray.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_newarray {
+
+    public static int test(int a) {
+        if (new boolean[a] == null) {
+            return -1;
+        }
+        if (new char[a] == null) {
+            return -1;
+        }
+        if (new float[a] == null) {
+            return -1;
+        }
+        if (new double[a] == null) {
+            return -1;
+        }
+        if (new byte[a] == null) {
+            return -1;
+        }
+        if (new short[a] == null) {
+            return -1;
+        }
+        if (new int[a] == null) {
+            return -1;
+        }
+        if (new long[a] == null) {
+            return -1;
+        }
+
+        return a;
+    }
+
+    @Test(expected = java.lang.NegativeArraySizeException.class)
+    public void run0() throws Throwable {
+        test(-1);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_putfield.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_putfield {
+
+    private static BC_putfield object = new BC_putfield();
+
+    private int field;
+
+    public static int test(int arg) {
+        final BC_putfield obj = arg == 3 ? null : object;
+        obj.field = arg;
+        return obj.field;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run1() throws Throwable {
+        test(3);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-4, test(-4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_saload.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_saload {
+
+    static short[] arr = {0, -1, 4, 10000};
+
+    public static short test(int arg) {
+        final short[] array = arg == -2 ? null : arr;
+        return array[arg];
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run0() throws Throwable {
+        test(-2);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(-1);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((short) 0), test(0));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(4);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/BC_sastore.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class BC_sastore {
+
+    static short[] arr = {0, 0, 0, 0};
+
+    public static short test(int arg, short val) {
+        final short[] array = arg == -2 ? null : arr;
+        array[arg] = val;
+        return array[arg];
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run0() throws Throwable {
+        test(-2, ((short) 0));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(-1, ((short) 3));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((short) 0), test(0, ((short) 0)));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(4, ((short) 0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_Loop01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_Loop01 {
+
+    public static int test(int arg) {
+        int accum = 0;
+        for (int i = 0; i < arg; i++) {
+            try {
+                accum += div(20, i);
+            } catch (ArithmeticException e) {
+                accum -= 100;
+            }
+        }
+        return accum;
+    }
+
+    static int div(int a, int b) {
+        return a / (b % 3);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-170, test(4));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-150, test(5));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-140, test(6));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-240, test(7));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-700, test(30));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_Loop02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_Loop02 {
+
+    public static int test(int arg) {
+        int accum = 0;
+        for (int i = 0; i < arg; i++) {
+            try {
+                accum += div(20, i);
+            } catch (IllegalArgumentException e) {
+                accum -= 100;
+            }
+        }
+        return accum;
+    }
+
+    static int div(int a, int b) {
+        if (b % 3 == 0) {
+            throw new IllegalArgumentException();
+        }
+        return a / (b % 3);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-170, test(4));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-150, test(5));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-140, test(6));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-240, test(7));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-700, test(30));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_Loop03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_Loop03 {
+
+    public static int test(int arg) {
+        int accum = 0;
+        for (int i = 0; i < arg; i++) {
+            try {
+                accum += div(20, i);
+            } catch (Catch_Loop03_Exception1 e) {
+                accum -= 100;
+            }
+        }
+        return accum;
+    }
+
+    static int div(int a, int b) {
+        if (b % 3 == 0) {
+            throw new Catch_Loop03_Exception1();
+        }
+        return a / (b % 3);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-170, test(4));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-150, test(5));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-140, test(6));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-240, test(7));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-700, test(30));
+    }
+
+}
+
+@SuppressWarnings("serial")
+class Catch_Loop03_Exception1 extends RuntimeException {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_NASE_1.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_NASE_1 {
+
+    @SuppressWarnings("unused")
+    public static int test(int a) {
+        try {
+            int[] v = new int[a];
+            if (v != null) {
+                return v.length;
+            }
+            return -1;
+        } catch (NegativeArraySizeException e) {
+            return 100;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(100, test(-1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(100, test(-34));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(20, test(20));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_NASE_2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_NASE_2 {
+
+    @SuppressWarnings("unused")
+    public static int test(int a) {
+        try {
+            Catch_NASE_2[] v = new Catch_NASE_2[a];
+            if (v != null) {
+                return v.length;
+            }
+            return -1;
+        } catch (NegativeArraySizeException e) {
+            return 100;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(100, test(-1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(100, test(-34));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(20, test(20));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_NPE_00.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_NPE_00 {
+
+    public static int test(int a) {
+        int[] array = a > 0 ? new int[3] : null;
+        try {
+            return array.length;
+        } catch (NullPointerException npe) {
+            return -1;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-1, test(-3));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(0));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(3, test(1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(3, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_NPE_01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_NPE_01 {
+
+    public static int test(int a) {
+        try {
+            if (a >= 0) {
+                throw new NullPointerException();
+            }
+        } catch (NullPointerException npe) {
+            return a;
+        }
+        return -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1, test(-2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_NPE_02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_NPE_02 {
+
+    public static int test(int a) {
+        try {
+            throwNPE(a);
+        } catch (NullPointerException npe) {
+            return a;
+        }
+        return -1;
+    }
+
+    private static void throwNPE(int a) {
+        if (a >= 0) {
+            throw new NullPointerException();
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1, test(-2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_NPE_03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_NPE_03 {
+
+    @SuppressWarnings("all")
+    public static int test(int a) {
+        try {
+            if (a >= 0) {
+                final Object o = null;
+                return o.hashCode();
+            }
+        } catch (NullPointerException npe) {
+            return a;
+        }
+        return -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1, test(-2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_NPE_04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_NPE_04 {
+
+    private int field = 45;
+
+    @SuppressWarnings("all")
+    public static int test(int a) {
+        try {
+            if (a >= 0) {
+                final Catch_NPE_04 obj = null;
+                return obj.field;
+            }
+        } catch (NullPointerException npe) {
+            return a;
+        }
+        return -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1, test(-2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_NPE_05.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_NPE_05 {
+
+    private int field = 45;
+
+    public static int test(int a) {
+        try {
+            return throwNPE(a);
+        } catch (NullPointerException npe) {
+            return a;
+        }
+    }
+
+    @SuppressWarnings("all")
+    private static int throwNPE(int a) {
+        if (a >= 0) {
+            final Catch_NPE_05 obj = null;
+            return obj.field;
+        }
+        return -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1, test(-2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_NPE_06.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_NPE_06 {
+
+    public static int test(String string) {
+        try {
+            return string.hashCode();
+        } catch (NullPointerException npe) {
+            return -1;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(""));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(null));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_NPE_07.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+
+public class Catch_NPE_07 {
+
+    @SuppressWarnings("serial")
+    public static class MyThrowable extends Throwable {
+    }
+
+    @SuppressWarnings("unused")
+    public static int foo(Throwable t) {
+        try {
+            throw t;
+        } catch (Throwable t1) {
+            if (t1 == null) {
+                return -1;
+            }
+            if (t1 instanceof NullPointerException) {
+                return 0;
+            }
+            if (t1 instanceof MyThrowable) {
+                return 1;
+            }
+            return -2;
+        }
+    }
+
+    public static int test(int i) {
+        Throwable t = (i == 0) ? null : new MyThrowable();
+        try {
+            return foo(t);
+        } catch (Throwable t1) {
+            return -3;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_NPE_08.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_NPE_08 {
+
+    public static int test(int a) {
+        try {
+            throwNPE(a);
+        } catch (NullPointerException npe) {
+            return a;
+        }
+        return -1;
+    }
+
+    @SuppressWarnings("unused")
+    private static void throwNPE(int a) {
+        throw null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-2, test(-2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_NPE_09.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_NPE_09 {
+
+    public static int test(int a) {
+        int r = 0;
+        try {
+            r = 0;
+            throwNPE(a);
+            r = 1;
+            throwNPE(a - 1);
+        } catch (NullPointerException e) {
+            return r + 10;
+        }
+        return r;
+    }
+
+    private static void throwNPE(int a) {
+        if (a == 0) {
+            throw null;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(1, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_NPE_10.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_NPE_10 {
+
+    public static int test(int a) {
+        int r = 0;
+        try {
+            r = 0;
+            if (a == 0) {
+                throw null;
+            }
+            r = 1;
+            if (a - 1 == 0) {
+                throw null;
+            }
+        } catch (NullPointerException e) {
+            return r + 10;
+        }
+        return r;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(1, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_NPE_11.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_NPE_11 {
+
+    public static int test(int a) {
+        int r = 0;
+        try {
+            r = 0;
+            throwE(a);
+            r = 1;
+            throwE(a - 1);
+        } catch (ArithmeticException e) {
+            return r + 10;
+        }
+        return r;
+    }
+
+    private static int throwE(int a) {
+        return 1 / a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(1, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_StackOverflowError_01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_StackOverflowError_01 {
+
+    private static void recurse() {
+        recurse();
+    }
+
+    public static int test() throws StackOverflowError {
+        recurse();
+        return -1;
+    }
+
+    @Test(expected = java.lang.StackOverflowError.class)
+    public void run0() throws Throwable {
+        test();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_StackOverflowError_02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_StackOverflowError_02 {
+
+    private static void recurse() {
+        recurse();
+    }
+
+    public static int test() {
+        try {
+            recurse();
+        } catch (StackOverflowError stackOverflowError) {
+            // tests that the guard page was reset and a second SOE can be handled
+            recurse();
+        }
+        return -1;
+    }
+
+    @Test(expected = java.lang.StackOverflowError.class)
+    public void run0() throws Throwable {
+        test();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_StackOverflowError_03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/**
+ * Some basic checking of the stack trace produced after a StackOverflowError.
+ */
+public class Catch_StackOverflowError_03 {
+
+    private static final int PASS = 0;
+    private static final int FAIL = 1;
+
+    private static void recurseA() {
+        recurseB();
+    }
+
+    private static void recurseB() {
+        recurseA();
+    }
+
+    public static int test() {
+        try {
+            recurseA();
+        } catch (StackOverflowError stackOverflowError) {
+            // Check that a method does not appear to be calling itself in the stack trace
+            // and check that recurse* is only called by either recurse* or test
+            StackTraceElement[] elements = null;
+            elements = stackOverflowError.getStackTrace();
+            if (elements.length == 0) {
+                // Not much we can do about this perfectly legal situation
+                return PASS;
+            }
+            String lastMethodName = elements[0].getMethodName();
+            for (int i = 1; i < elements.length; ++i) {
+                String methodName = elements[i].getMethodName();
+
+                // Skip top-of-stack until we find a method with name "recurse*".
+                if (!methodName.startsWith("recurse")) {
+                    continue;
+                }
+
+                // We reached the test method => done.
+                if (methodName.equals("test")) {
+                    break;
+                }
+
+                // Stack elements must alternate between recurseA and recurseB
+                if (lastMethodName.equals(methodName) || (!methodName.equals("recurseA") && !methodName.equals("recurseB"))) {
+                    return FAIL;
+                }
+
+                lastMethodName = methodName;
+            }
+
+            return PASS;
+        }
+
+        return FAIL;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_Two01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_Two01 {
+
+    public static String test(int arg) {
+        try {
+            throwSomething(arg);
+        } catch (NullPointerException e) {
+            return e.getClass().getName();
+        } catch (ArithmeticException e) {
+            return e.getClass().getName();
+        }
+        return "none";
+    }
+
+    private static void throwSomething(int arg) {
+        if (arg == 0) {
+            throw new NullPointerException();
+        }
+        if (arg == 1) {
+            throw new ArithmeticException();
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("java.lang.NullPointerException", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("java.lang.ArithmeticException", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("none", test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_Two02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_Two02 {
+
+    public static String test(int arg) {
+        try {
+            throwSomething(arg + 10);
+        } catch (NullPointerException e) {
+            return e.getClass().getName();
+        } catch (ArithmeticException e) {
+            return e.getClass().getName();
+        }
+        return "none" + (arg + 10);
+    }
+
+    private static void throwSomething(int arg) {
+        if (arg == 10) {
+            throw new NullPointerException();
+        }
+        if (arg == 11) {
+            throw new ArithmeticException();
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("java.lang.NullPointerException", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("java.lang.ArithmeticException", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("none13", test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_Two03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_Two03 {
+
+    public static String test(int arg) {
+        int r = 0;
+        try {
+            r = 1;
+            throwSomething(r + arg);
+            r = 2;
+            throwSomething(r + arg);
+            r = 3;
+            throwSomething(r + arg);
+            r = 4;
+        } catch (NullPointerException e) {
+            return e.getClass().getName() + r;
+        } catch (ArithmeticException e) {
+            return e.getClass().getName() + r;
+        }
+        return "none" + r;
+    }
+
+    private static void throwSomething(int arg) {
+        if (arg == 5) {
+            throw new NullPointerException();
+        }
+        if (arg == 6) {
+            throw new ArithmeticException();
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("none4", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("none4", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("java.lang.NullPointerException3", test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_Unresolved.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_Unresolved {
+
+    public static boolean executed;
+
+    public static int test(int arg) {
+        executed = false;
+        try {
+            helper1(arg);
+            helper2(arg);
+        } catch (Catch_Unresolved_Exception1 e) {
+            return 1;
+        } catch (Catch_Unresolved_Exception2 e) {
+            return 2;
+        }
+        return 0;
+    }
+
+    private static void helper1(int arg) {
+        if (executed) {
+            throw new IllegalStateException("helper1 may only be called once");
+        }
+        executed = true;
+        if (arg == 1) {
+            throw new Catch_Unresolved_Exception1();
+        } else if (arg == 2) {
+            throw new Catch_Unresolved_Exception2();
+        }
+    }
+
+    private static void helper2(int arg) {
+        if (arg != 0) {
+            throw new IllegalStateException("helper2 can only be called if arg==0");
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+}
+
+@SuppressWarnings("serial")
+class Catch_Unresolved_Exception1 extends RuntimeException {
+}
+
+@SuppressWarnings("serial")
+class Catch_Unresolved_Exception2 extends RuntimeException {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_Unresolved01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_Unresolved01 {
+
+    public static boolean executed;
+
+    public static int test(int arg) {
+        executed = false;
+        try {
+            helper1(arg);
+        } catch (Catch_Unresolved_Exception3 e) {
+            return 1;
+        } catch (Catch_Unresolved_Exception4 e) {
+            return 2;
+        }
+        return 0;
+    }
+
+    private static void helper1(int arg) {
+        if (executed) {
+            throw new IllegalStateException("helper1 may only be called once");
+        }
+        executed = true;
+        if (arg == 1) {
+            throw new Catch_Unresolved_Exception3();
+        } else if (arg == 2) {
+            throw new Catch_Unresolved_Exception4();
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+}
+
+@SuppressWarnings("serial")
+class Catch_Unresolved_Exception3 extends RuntimeException {
+}
+
+@SuppressWarnings("serial")
+class Catch_Unresolved_Exception4 extends RuntimeException {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_Unresolved02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_Unresolved02 {
+
+    public static boolean executed;
+    public static int value;
+
+    public static int test(int arg) {
+        executed = false;
+        int result = 0;
+        try {
+            result = value + helper1(arg) + helper2(arg);
+        } catch (Catch_Unresolved02_Exception1 e) {
+            return 1 + result;
+        } catch (Catch_Unresolved02_Exception2 e) {
+            return 2 + result;
+        }
+        return result;
+    }
+
+    private static int helper1(int arg) {
+        if (executed) {
+            throw new IllegalStateException("helper1 may only be called once");
+        }
+        executed = true;
+        if (arg == 1) {
+            throw new Catch_Unresolved02_Exception1();
+        } else if (arg == 2) {
+            throw new Catch_Unresolved02_Exception2();
+        }
+        return 0;
+    }
+
+    private static int helper2(int arg) {
+        if (arg != 0) {
+            throw new IllegalStateException("helper2 can only be called if arg==0");
+        }
+        return 0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+}
+
+@SuppressWarnings("serial")
+class Catch_Unresolved02_Exception1 extends RuntimeException {
+}
+
+@SuppressWarnings("serial")
+class Catch_Unresolved02_Exception2 extends RuntimeException {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Catch_Unresolved03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Catch_Unresolved03 {
+
+    public static boolean executed;
+    public static int value;
+
+    public static int test(int arg) {
+        executed = false;
+        int result = 0;
+        try {
+            result = value + helper1(arg) + helper2(arg);
+        } catch (Catch_Unresolved03_Exception1 e) {
+            if (arg == 1) {
+                return 1;
+            }
+            return new Catch_Unresolved03_UnresolvedClass().value();
+        }
+        return result;
+    }
+
+    private static int helper1(int arg) {
+        if (executed) {
+            throw new IllegalStateException("helper1 may only be called once");
+        }
+        executed = true;
+        if (arg == 1 || arg == 2) {
+            throw new Catch_Unresolved03_Exception1();
+        }
+        return 0;
+    }
+
+    private static int helper2(int arg) {
+        if (arg != 0) {
+            throw new IllegalStateException("helper2 can only be called if arg==0");
+        }
+        return 0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+}
+
+@SuppressWarnings("serial")
+class Catch_Unresolved03_Exception1 extends RuntimeException {
+}
+
+class Catch_Unresolved03_UnresolvedClass {
+
+    public int value() {
+        return 2;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Except_Locals.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class Except_Locals {
+
+    public static int test(String a, String b) {
+        int x = 0;
+        try {
+            x = 1;
+            a.toString();
+            x = 2;
+            b.toString();
+        } catch (NullPointerException e) {
+            // System.out.println(x);
+            return x;
+        }
+        return -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1, test(null, null));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2, test("", null));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1, test("", ""));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Except_Synchronized01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Except_Synchronized01 {
+
+    static final Except_Synchronized01 object = new Except_Synchronized01();
+
+    final int x = 1;
+
+    public static int test(int i) throws Exception {
+        if (i == 0) {
+            return 0;
+        }
+        return object.test2(i);
+    }
+
+    @SuppressWarnings("all")
+    public synchronized int test2(int i) throws Exception {
+        try {
+            Except_Synchronized01 object = null;
+            return object.x;
+        } catch (NullPointerException e) {
+            return 2;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Except_Synchronized02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class Except_Synchronized02 {
+
+    static final Except_Synchronized02 object = new Except_Synchronized02();
+
+    final int x = 1;
+
+    public static int test(int i) throws Exception {
+        if (i == 0) {
+            return 0;
+        }
+        return object.test2(i);
+    }
+
+    @SuppressWarnings("all")
+    public synchronized int test2(int i) throws Exception {
+        while (true) {
+            try {
+                Except_Synchronized02 object = null;
+                return object.x;
+            } catch (NullPointerException e) {
+                return 2;
+            }
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Except_Synchronized03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Except_Synchronized03 {
+
+    static final Except_Synchronized03 object = new Except_Synchronized03();
+
+    int x = 1;
+
+    public static int test(int i) throws Exception {
+        if (i == 0) {
+            return 0;
+        }
+        return object.test2(i);
+    }
+
+    @SuppressWarnings("all")
+    public synchronized int test2(int i) throws Exception {
+        while (true) {
+            try {
+                synchronized (this) {
+                    Except_Synchronized03 object = null;
+                    return object.x;
+                }
+            } catch (NullPointerException e) {
+                return 2;
+            }
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Except_Synchronized04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class Except_Synchronized04 {
+
+    static final Except_Synchronized04 object = new Except_Synchronized04();
+
+    final int x = 1;
+
+    public static int test(int i) throws Exception {
+        if (i == 0) {
+            return 0;
+        }
+        return object.test2(i);
+    }
+
+    @SuppressWarnings("all")
+    public int test2(int i) throws Exception {
+        try {
+            synchronized (Except_Synchronized04.class) {
+                Except_Synchronized04 object = null;
+                return object.x;
+            }
+        } catch (NullPointerException e) {
+            return 2;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Except_Synchronized05.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public class Except_Synchronized05 {
+
+    Object field;
+
+    public static int test(int arg) {
+        Except_Synchronized05 obj = new Except_Synchronized05();
+        int a = obj.bar(arg) != null ? 1 : 0;
+        int b = obj.baz(arg) != null ? 1 : 0;
+        return a + b;
+    }
+
+    public synchronized Object bar(int arg) {
+        try {
+            String f = foo1(arg);
+            if (f == null) {
+                field = new Object();
+            }
+        } catch (NullPointerException e) {
+            // do nothing
+        }
+        return field;
+    }
+
+    public Object baz(int arg) {
+        synchronized (this) {
+            try {
+                String f = foo1(arg);
+                if (f == null) {
+                    field = new Object();
+                }
+            } catch (NullPointerException e) {
+                // do nothing
+            }
+            return field;
+        }
+    }
+
+    private String foo1(int arg) {
+        if (arg == 0) {
+            throw null;
+        }
+        return null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Finally01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Finally01 {
+
+    @SuppressWarnings("all")
+    public static int test(int arg) {
+        try {
+            return 0;
+        } finally {
+            return -1;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-1, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Finally02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class Finally02 {
+
+    public static int test() {
+        try {
+            a();
+        } finally {
+            b();
+        }
+
+        return c();
+    }
+
+// @NEVER_INLINE
+    static int a() {
+        return 0;
+    }
+
+// @NEVER_INLINE
+    static int b() {
+        return -3;
+    }
+
+    static int c() {
+        return -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-1, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/StackTrace_AIOOBE_00.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class StackTrace_AIOOBE_00 {
+
+    private static int[] array = new int[3];
+
+    public static int test(int a) {
+        try {
+            return array[a];
+        } catch (ArrayIndexOutOfBoundsException npe) {
+            for (StackTraceElement e : npe.getStackTrace()) {
+                if (e.getClassName().equals(StackTrace_AIOOBE_00.class.getName()) && e.getMethodName().equals("test")) {
+                    return -1;
+                }
+            }
+        }
+        return -2;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1, test(-2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-1, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/StackTrace_CCE_00.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class StackTrace_CCE_00 {
+
+    static Object object2 = new Object();
+    static Object object3 = "";
+    static Object object4 = new StackTrace_CCE_00();
+
+    public static int test(int arg) {
+        Object obj = null;
+        if (arg == 2) {
+            obj = object2;
+        }
+        if (arg == 3) {
+            obj = object3;
+        }
+        if (arg == 4) {
+            obj = object4;
+        }
+        try {
+            final StackTrace_CCE_00 bc = (StackTrace_CCE_00) obj;
+            if (bc == null) {
+                return arg;
+            }
+            return arg;
+        } catch (ClassCastException npe) {
+            for (StackTraceElement e : npe.getStackTrace()) {
+                if (e.getClassName().equals(StackTrace_CCE_00.class.getName()) && e.getMethodName().equals("test")) {
+                    return -100;
+                }
+            }
+            return -200;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-100, test(2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-100, test(3));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(4, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/StackTrace_NPE_00.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class StackTrace_NPE_00 {
+
+    public static int test(int a) {
+        int[] array = a > 0 ? new int[3] : null;
+        try {
+            return array.length;
+        } catch (NullPointerException npe) {
+            for (StackTraceElement e : npe.getStackTrace()) {
+                if (e.getClassName().equals(StackTrace_NPE_00.class.getName())) {
+                    return -1;
+                }
+            }
+            return -2;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-1, test(-3));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(0));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(3, test(1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(3, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/StackTrace_NPE_01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class StackTrace_NPE_01 {
+
+    @SuppressWarnings("all")
+    public static int test(int a) {
+        try {
+            if (a >= 0) {
+                final Object o = null;
+                return o.hashCode();
+            }
+        } catch (NullPointerException npe) {
+            for (StackTraceElement e : npe.getStackTrace()) {
+                if (e.getClassName().equals(StackTrace_NPE_01.class.getName()) && e.getMethodName().equals("test")) {
+                    return a;
+                }
+            }
+        }
+        return -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1, test(-2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/StackTrace_NPE_02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class StackTrace_NPE_02 {
+
+    private static String[] trace = {"test1", "test"};
+
+    public static int test(int a) {
+        try {
+            if (a >= 0) {
+                return test1();
+            }
+        } catch (NullPointerException npe) {
+            String thisClass = StackTrace_NPE_02.class.getName();
+            StackTraceElement[] stackTrace = npe.getStackTrace();
+            for (int i = 0; i < stackTrace.length; i++) {
+                StackTraceElement e = stackTrace[i];
+                if (e.getClassName().equals(thisClass)) {
+                    for (int j = 0; j < trace.length; j++) {
+                        StackTraceElement f = stackTrace[i + j];
+                        if (!f.getClassName().equals(thisClass)) {
+                            return -2;
+                        }
+                        if (!f.getMethodName().equals(trace[j])) {
+                            return -3;
+                        }
+                    }
+                    return 0;
+                }
+            }
+        }
+        return -1;
+    }
+
+    @SuppressWarnings("all")
+    private static int test1() {
+        final Object o = null;
+        return o.hashCode();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1, test(-2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/StackTrace_NPE_03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+/*
+ */
+public class StackTrace_NPE_03 {
+
+    private static String[] trace = {"test2", "test1", "test"};
+
+    public static int test(int a) {
+        try {
+            if (a >= 0) {
+                return test1();
+            }
+        } catch (NullPointerException npe) {
+            String thisClass = StackTrace_NPE_03.class.getName();
+            StackTraceElement[] stackTrace = npe.getStackTrace();
+            for (int i = 0; i < stackTrace.length; i++) {
+                StackTraceElement e = stackTrace[i];
+                if (e.getClassName().equals(thisClass)) {
+                    for (int j = 0; j < trace.length; j++) {
+                        StackTraceElement f = stackTrace[i + j];
+                        if (!f.getClassName().equals(thisClass)) {
+                            return -2;
+                        }
+                        if (!f.getMethodName().equals(trace[j])) {
+                            return -3;
+                        }
+                    }
+                    return 0;
+                }
+            }
+        }
+        return -1;
+    }
+
+    private static int test1() {
+        return test2();
+    }
+
+    private static int test2() {
+        throw new NullPointerException();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1, test(-2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Throw_InCatch01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class Throw_InCatch01 {
+
+    public static boolean test(int i) throws Exception {
+        if (i == 0) {
+            return true;
+        }
+        try {
+            throw new Exception();
+        } catch (Exception e) {
+            throw e;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test(expected = java.lang.Exception.class)
+    public void run1() throws Throwable {
+        test(1);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Throw_InCatch02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class Throw_InCatch02 {
+
+    public static boolean test(int i) throws Exception {
+        if (i == 0) {
+            return true;
+        }
+        try {
+            throwE();
+        } catch (Exception e) {
+            throwE(e);
+        }
+        return false;
+    }
+
+    private static void throwE(Exception e) throws Exception {
+        throw e;
+    }
+
+    private static void throwE() throws Exception {
+        throw new Exception();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test(expected = java.lang.Exception.class)
+    public void run1() throws Throwable {
+        test(1);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Throw_InCatch03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class Throw_InCatch03 {
+
+    public static boolean test(int i) throws Exception {
+        if (i == 0) {
+            return true;
+        }
+        try {
+            throwE();
+        } catch (Exception e) {
+            throw e;
+        }
+        return false;
+    }
+
+    private static void throwE() throws Exception {
+        throw new Exception();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test(expected = java.lang.Exception.class)
+    public void run1() throws Throwable {
+        test(1);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Throw_InNested.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2010, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class Throw_InNested {
+
+    public static int test(int i) throws Exception {
+        return 42 + test2(i);
+    }
+
+    public static int test2(int i) throws Exception {
+        try {
+            return test3(i);
+        } catch (Exception e) {
+            return 5;
+        }
+    }
+
+    private static int test3(int i) {
+        if (i == 0) {
+            throw new RuntimeException();
+        }
+        return i;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(47, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(43, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Throw_NPE_01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class Throw_NPE_01 {
+
+    public static int test(int i) throws Exception {
+        int a = test2(i);
+        a = a + 1;
+        return a;
+    }
+
+    public static int test2(int i) {
+        if (i < 0) {
+            throw null;
+        }
+        return i;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2, test(1));
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run2() throws Throwable {
+        test(-1);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Throw_Synchronized01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class Throw_Synchronized01 {
+
+    public static synchronized boolean test(int i) throws Exception {
+        return i == 0 || test2(i);
+    }
+
+    @SuppressWarnings("unused")
+    public static boolean test2(int i) throws Exception {
+        throw new Exception();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test(expected = java.lang.Exception.class)
+    public void run1() throws Throwable {
+        test(1);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Throw_Synchronized02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class Throw_Synchronized02 {
+
+    public static synchronized boolean test(int i) throws Exception {
+        if (i == 0) {
+            return true;
+        }
+        throw new Exception();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test(expected = java.lang.Exception.class)
+    public void run1() throws Throwable {
+        test(1);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Throw_Synchronized03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class Throw_Synchronized03 {
+
+    public static synchronized boolean test(int i) throws Exception {
+        if (i == 0) {
+            return true;
+        }
+        return test2(i);
+    }
+
+    @SuppressWarnings("unused")
+    public static synchronized boolean test2(int i) throws Exception {
+        throw new Exception();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test(expected = java.lang.Exception.class)
+    public void run1() throws Throwable {
+        test(1);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Throw_Synchronized04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class Throw_Synchronized04 {
+
+    static final Throw_Synchronized04 object = new Throw_Synchronized04();
+
+    public static boolean test(int i) throws Exception {
+        if (i == 0) {
+            return true;
+        }
+        return object.test2(i);
+    }
+
+    @SuppressWarnings("unused")
+    public synchronized boolean test2(int i) throws Exception {
+        throw new Exception();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test(expected = java.lang.Exception.class)
+    public void run1() throws Throwable {
+        test(1);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/except/Throw_Synchronized05.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ */
+package com.oracle.max.graal.jtt.except;
+
+import org.junit.*;
+
+public class Throw_Synchronized05 {
+
+    static final Throw_Synchronized05 object = new Throw_Synchronized05();
+
+    public static boolean test(int i) throws Exception {
+        if (i == 0) {
+            return true;
+        }
+        return object.test2(i);
+    }
+
+    @SuppressWarnings("unused")
+    public synchronized boolean test2(int i) throws Exception {
+        try {
+            throw new Exception();
+        } catch (Exception e) {
+            // do nothing and then rethrow
+            throw e;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test(expected = java.lang.Exception.class)
+    public void run1() throws Throwable {
+        test(1);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_allocate01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_allocate01 {
+
+    public static int test(int count) {
+        int sum = 0;
+        for (int i = 0; i < count; i++) {
+            sum += i;
+        }
+        return sum;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(1, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(3, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(3160, test(80));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_allocate02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_allocate02 {
+
+    public static int test(int count) {
+        int sum = 0;
+        for (int i = 0; i < count; i++) {
+            final Integer j = new Integer(i);
+            sum += j;
+        }
+        return sum;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(4950, test(100));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_allocate03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_allocate03 {
+
+    public static int test(int count) {
+        @SuppressWarnings("unused")
+        final int sum = 0;
+        String text = "";
+        for (int i = 0; i < count; i++) {
+            text += '.';
+        }
+        return text.length();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(100, test(100));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_allocate04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_allocate04 {
+
+    public static int test(int count) {
+        int[] a = new int[count];
+
+        for (int i = 0; i < a.length; i++) {
+            a[i] = i;
+        }
+
+        int i = 0;
+        int iwrap = count - 1;
+        int sum = 0;
+
+        while (i < count) {
+            sum += (a[i] + a[iwrap]) / 2;
+            iwrap = i;
+            i++;
+        }
+        return sum;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3120, test(80));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_array01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_array01 {
+
+    public static int[] array = new int[40];
+
+    public static int test(int count) {
+        int sum = 0;
+        for (int i = 0; i < count; i++) {
+            array[i] = i;
+            sum += array[i];
+        }
+        return sum;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(780, test(40));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_array02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_array02 {
+
+    public static byte[] b = new byte[40];
+    public static char[] c = new char[40];
+    public static short[] s = new short[40];
+    public static int[] iArray = new int[40];
+    public static long[] l = new long[40];
+    public static float[] f = new float[40];
+    public static double[] d = new double[40];
+
+    public static int test(int count) {
+        int sum = 0;
+        for (int x = 0; x < count; x++) {
+            b[x] = (byte) x;
+            c[x] = (char) x;
+            s[x] = (short) x;
+            iArray[x] = x;
+            l[x] = x;
+            f[x] = x;
+            d[x] = x;
+            sum += b[x] + c[x] + s[x] + iArray[x] + l[x] + f[x] + d[x];
+        }
+        return sum;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(5460, test(40));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_array03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_array03 {
+
+    public static byte[] b = new byte[40];
+    public static char[] c = new char[40];
+
+    public static int test(int count) {
+        int sum = 0;
+        for (int i = 0; i < count; i++) {
+            sum += b.length + c.length;
+        }
+        return sum;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3200, test(40));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_array04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_array04 {
+
+    public static byte[] b = new byte[40];
+    public static char[] c = new char[40];
+
+    public static int test(int count) {
+        int sum = 0;
+
+        for (int i = 0; i < b.length; i++) {
+            b[i] = (byte) i;
+            c[i] = (char) i;
+        }
+
+        for (int j = 0; j < 10; j++) {
+            try {
+                for (int i = 0; i < count; i++) {
+                    sum += b[i] + c[i];
+                }
+            } catch (IndexOutOfBoundsException e) {
+                sum += j;
+            }
+        }
+
+        return sum;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(15645, test(80));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_control01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_control01 {
+
+    public static int test(int count) {
+        int i1 = 1;
+        int i2 = 2;
+        int i3 = 3;
+        int i4 = 4;
+
+        for (int i = 0; i < count; i++) {
+            i1 = i2;
+            i2 = i3;
+            i3 = i4;
+            i4 = i1;
+
+            i1 = i2;
+            i2 = i3;
+            i3 = i4;
+            i4 = i1;
+
+            i1 = i2;
+            i2 = i3;
+            i3 = i4;
+            i4 = i1;
+
+            i1 = i2;
+            i2 = i3;
+            i3 = i4;
+            i4 = i1;
+        }
+
+        return i1 + i2 * 10 + i3 * 100 + i4 * 1000;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(2432, test(40));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(3243, test(80));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_control02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_control02 {
+
+    public static int test(int count) {
+        int sum = 0;
+        for (int i = 0; i < count; i++) {
+            switch (i) {
+                case 30:
+                    sum += 30;
+                    break;
+                case 31:
+                    sum += 31;
+                    break;
+                case 32:
+                    sum += 32;
+                    break;
+                case 33:
+                    sum += 33;
+                    break;
+                case 34:
+                    sum += 34;
+                    break;
+                case 35:
+                    sum += 35;
+                    break;
+                case 36:
+                    sum += 36;
+                    break;
+                case 37:
+                    sum += 37;
+                    break;
+                case 38:
+                    sum += 38;
+                    break;
+                case 39:
+                    sum += 39;
+                    break;
+                case 40:
+                    sum += 40;
+                    break;
+                case 41:
+                    sum += 41;
+                    break;
+                case 42:
+                    sum += 42;
+                    break;
+                default:
+                    sum += 1;
+                    break;
+            }
+        }
+        return sum;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(515, test(60));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(555, test(100));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_convert01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_convert01 {
+
+    public static int test(int count) {
+        double sum = 0;
+        for (int i = 0; i < count; i++) {
+            sum = (int) sum + i;
+        }
+        return (int) sum;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(4950, test(100));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_count.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ * Runs: 10 = 55; 20 = 210; 30 = 465; 40 = 820;
+ */
+@SuppressWarnings("unused")
+public class HP_count {
+
+    public static int test(int count) {
+        float unusedFloat = 0;
+        double dub = 0;
+        int sum = 0;
+        double unusedDouble = 0;
+        for (int i = 0; i <= count; i++) {
+            if (i > 20) {
+                sum += i;
+            } else {
+                sum += i;
+            }
+            dub += sum;
+        }
+        return sum;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(820, test(40));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_dead01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_dead01 {
+
+    public static int test(int count) {
+        int sum = 0;
+        for (int i = 0; i <= count; i++) {
+            int a = i + i;
+            int b = i / 2 * i - 10;
+            @SuppressWarnings("unused")
+            int c = a + b;
+            int d = a;
+            sum += d;
+        }
+        return sum;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(110, test(10));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(420, test(20));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(930, test(30));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1640, test(40));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_demo01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_demo01 {
+
+    public static int test(int count) {
+        int sum = 0;
+
+        for (int i = 0; i < count; i++) {
+            int[] ia = new int[count];
+            long[] la = new long[count];
+            float[] fa = new float[count];
+            double[] da = new double[count];
+            sum += ia[i] = (int) (la[i] = (long) (fa[i] = (float) (da[i] = i)));
+        }
+
+        return sum;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3160, test(80));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_field01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_field01 {
+
+    public static int a;
+    public static int b;
+    public static int c;
+
+    public static int test(int count) {
+        for (int i = 0; i <= count; i++) {
+            if (i > 5) {
+                a += i;
+            } else if (i > 7) {
+                b += i;
+            } else {
+                c += i;
+            }
+        }
+        return a + b + c;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(820, test(40));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_field02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ * Runs: 10 = 55; 20 = 210; 30 = 465; 40 = 820;
+ */
+public class HP_field02 {
+
+    public int a;
+    public int b;
+    public int c;
+
+    public static int test(int count) {
+        return new HP_field02().run(count);
+    }
+
+    public int run(int count) {
+        for (int i = 0; i <= count; i++) {
+            if (i > 5) {
+                a += i;
+            } else if (i > 7) {
+                b += i;
+            } else {
+                c += i;
+            }
+        }
+        return a + b + c;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(820, test(40));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_field03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_field03 {
+
+    public static byte b;
+    public static char c;
+    public static short s;
+    public static int i;
+    public static long l;
+    public static float f;
+    public static double d;
+
+    public static int test(int count) {
+        for (int x = 0; x <= count; x++) {
+            b += x;
+            c += x;
+            s += x;
+            i += x;
+            l += x;
+            f += x;
+            d += x;
+        }
+        return (int) (b + c + s + i + l + f + d);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(2019980, test(1000));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_field04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_field04 {
+
+    public byte b;
+    public char c;
+    public short s;
+    public int i;
+    public long l;
+    public float f;
+    public double d;
+
+    public static int test(int count) {
+        return new HP_field04().run(count);
+    }
+
+    public int run(int count) {
+        for (int x = 0; x <= count; x++) {
+            b += x;
+            c += x;
+            s += x;
+            i += x;
+            l += x;
+            f += x;
+            d += x;
+        }
+        return (int) (b + c + s + i + l + f + d);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(4972, test(40));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2019980, test(1000));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_idea.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,456 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+
+package com.oracle.max.graal.jtt.hotpath;
+
+import java.util.*;
+
+import org.junit.*;
+
+/*
+ */
+@SuppressWarnings("static-method")
+public class HP_idea {
+
+    public boolean test() {
+        buildTestData();
+        Do();
+        return verify();
+    }
+
+    // Declare class data. Byte buffer plain1 holds the original
+    // data for encryption, crypt1 holds the encrypted data, and
+    // plain2 holds the decrypted data, which should match plain1
+    // byte for byte.
+
+    int array_rows;
+
+    byte[] plain1; // Buffer for plaintext data.
+    byte[] crypt1; // Buffer for encrypted data.
+    byte[] plain2; // Buffer for decrypted data.
+
+    short[] userkey; // Key for encryption/decryption.
+    int[] Z; // Encryption subkey (userkey derived).
+    int[] DK; // Decryption subkey (userkey derived).
+
+    void Do() {
+        cipher_idea(plain1, crypt1, Z); // Encrypt plain1.
+        cipher_idea(crypt1, plain2, DK); // Decrypt.
+    }
+
+    /*
+     * buildTestData
+     * 
+     * Builds the data used for the test -- each time the test is run.
+     */
+
+    void buildTestData() {
+        // Create three byte arrays that will be used (and reused) for
+        // encryption/decryption operations.
+
+        plain1 = new byte[array_rows];
+        crypt1 = new byte[array_rows];
+        plain2 = new byte[array_rows];
+
+        Random rndnum = new Random(136506717L); // Create random number generator.
+
+        // Allocate three arrays to hold keys: userkey is the 128-bit key.
+        // Z is the set of 16-bit encryption subkeys derived from userkey,
+        // while DK is the set of 16-bit decryption subkeys also derived
+        // from userkey. NOTE: The 16-bit values are stored here in
+        // 32-bit int arrays so that the values may be used in calculations
+        // as if they are unsigned. Each 64-bit block of plaintext goes
+        // through eight processing rounds involving six of the subkeys
+        // then a final output transform with four of the keys; (8 * 6)
+        // + 4 = 52 subkeys.
+
+        userkey = new short[8]; // User key has 8 16-bit shorts.
+        Z = new int[52]; // Encryption subkey (user key derived).
+        DK = new int[52]; // Decryption subkey (user key derived).
+
+        // Generate user key randomly; eight 16-bit values in an array.
+
+        for (int i = 0; i < 8; i++) {
+            // Again, the random number function returns int. Converting
+            // to a short type preserves the bit pattern in the lower 16
+            // bits of the int and discards the rest.
+
+            userkey[i] = (short) rndnum.nextInt();
+        }
+
+        // Compute encryption and decryption subkeys.
+
+        calcEncryptKey();
+        calcDecryptKey();
+
+        // Fill plain1 with "text."
+        for (int i = 0; i < array_rows; i++) {
+            plain1[i] = (byte) i;
+
+            // Converting to a byte
+            // type preserves the bit pattern in the lower 8 bits of the
+            // int and discards the rest.
+        }
+    }
+
+    /*
+     * calcEncryptKey
+     * 
+     * Builds the 52 16-bit encryption subkeys Z[] from the user key and stores in 32-bit int array. The routing
+     * corrects an error in the source code in the Schnier book. Basically, the sense of the 7- and 9-bit shifts are
+     * reversed. It still works reversed, but would encrypted code would not decrypt with someone else's IDEA code.
+     */
+
+    private void calcEncryptKey() {
+        int j; // Utility variable.
+
+        for (int i = 0; i < 52; i++) {
+            // Zero out the 52-int Z array.
+            Z[i] = 0;
+        }
+
+        for (int i = 0; i < 8; i++) // First 8 subkeys are userkey itself.
+        {
+            Z[i] = userkey[i] & 0xffff; // Convert "unsigned"
+            // short to int.
+        }
+
+        // Each set of 8 subkeys thereafter is derived from left rotating
+        // the whole 128-bit key 25 bits to left (once between each set of
+        // eight keys and then before the last four). Instead of actually
+        // rotating the whole key, this routine just grabs the 16 bits
+        // that are 25 bits to the right of the corresponding subkey
+        // eight positions below the current subkey. That 16-bit extent
+        // straddles two array members, so bits are shifted left in one
+        // member and right (with zero fill) in the other. For the last
+        // two subkeys in any group of eight, those 16 bits start to
+        // wrap around to the first two members of the previous eight.
+
+        for (int i = 8; i < 52; i++) {
+            j = i % 8;
+            if (j < 6) {
+                Z[i] = ((Z[i - 7] >>> 9) | (Z[i - 6] << 7)) // Shift and combine.
+                & 0xFFFF; // Just 16 bits.
+                continue; // Next iteration.
+            }
+
+            if (j == 6) // Wrap to beginning for second chunk.
+            {
+                Z[i] = ((Z[i - 7] >>> 9) | (Z[i - 14] << 7)) & 0xFFFF;
+                continue;
+            }
+
+            // j == 7 so wrap to beginning for both chunks.
+
+            Z[i] = ((Z[i - 15] >>> 9) | (Z[i - 14] << 7)) & 0xFFFF;
+        }
+    }
+
+    /*
+     * calcDecryptKey
+     * 
+     * Builds the 52 16-bit encryption subkeys DK[] from the encryption- subkeys Z[]. DK[] is a 32-bit int array holding
+     * 16-bit values as unsigned.
+     */
+
+    private void calcDecryptKey() {
+        int j, k; // Index counters.
+        int t1, t2, t3; // Temps to hold decrypt subkeys.
+
+        t1 = inv(Z[0]); // Multiplicative inverse (mod x10001).
+        t2 = -Z[1] & 0xffff; // Additive inverse, 2nd encrypt subkey.
+        t3 = -Z[2] & 0xffff; // Additive inverse, 3rd encrypt subkey.
+
+        DK[51] = inv(Z[3]); // Multiplicative inverse (mod x10001).
+        DK[50] = t3;
+        DK[49] = t2;
+        DK[48] = t1;
+
+        j = 47; // Indices into temp and encrypt arrays.
+        k = 4;
+        for (int i = 0; i < 7; i++) {
+            t1 = Z[k++];
+            DK[j--] = Z[k++];
+            DK[j--] = t1;
+            t1 = inv(Z[k++]);
+            t2 = -Z[k++] & 0xffff;
+            t3 = -Z[k++] & 0xffff;
+            DK[j--] = inv(Z[k++]);
+            DK[j--] = t2;
+            DK[j--] = t3;
+            DK[j--] = t1;
+        }
+
+        t1 = Z[k++];
+        DK[j--] = Z[k++];
+        DK[j--] = t1;
+        t1 = inv(Z[k++]);
+        t2 = -Z[k++] & 0xffff;
+        t3 = -Z[k++] & 0xffff;
+        DK[j--] = inv(Z[k++]);
+        DK[j--] = t3;
+        DK[j--] = t2;
+        DK[j--] = t1;
+    }
+
+    /*
+     * cipher_idea
+     * 
+     * IDEA encryption/decryption algorithm. It processes plaintext in 64-bit blocks, one at a time, breaking the block
+     * into four 16-bit unsigned subblocks. It goes through eight rounds of processing using 6 new subkeys each time,
+     * plus four for last step. The source text is in array text1, the destination text goes into array text2 The
+     * routine represents 16-bit subblocks and subkeys as type int so that they can be treated more easily as unsigned.
+     * Multiplication modulo 0x10001 interprets a zero sub-block as 0x10000; it must to fit in 16 bits.
+     */
+
+    private void cipher_idea(byte[] text1, byte[] text2, int[] key) {
+
+        int i1 = 0; // Index into first text array.
+        int i2 = 0; // Index into second text array.
+        int ik; // Index into key array.
+        int x1, x2, x3, x4, t1, t2; // Four "16-bit" blocks, two temps.
+        int r; // Eight rounds of processing.
+
+        for (int i = 0; i < text1.length; i += 8) {
+
+            ik = 0; // Restart key index.
+            r = 8; // Eight rounds of processing.
+
+            // Load eight plain1 bytes as four 16-bit "unsigned" integers.
+            // Masking with 0xff prevents sign extension with cast to int.
+
+            x1 = text1[i1++] & 0xff; // Build 16-bit x1 from 2 bytes,
+            x1 |= (text1[i1++] & 0xff) << 8; // assuming low-order byte first.
+            x2 = text1[i1++] & 0xff;
+            x2 |= (text1[i1++] & 0xff) << 8;
+            x3 = text1[i1++] & 0xff;
+            x3 |= (text1[i1++] & 0xff) << 8;
+            x4 = text1[i1++] & 0xff;
+            x4 |= (text1[i1++] & 0xff) << 8;
+
+            do {
+                // 1) Multiply (modulo 0x10001), 1st text sub-block
+                // with 1st key sub-block.
+
+                x1 = (int) ((long) x1 * key[ik++] % 0x10001L & 0xffff);
+
+                // 2) Add (modulo 0x10000), 2nd text sub-block
+                // with 2nd key sub-block.
+
+                x2 = x2 + key[ik++] & 0xffff;
+
+                // 3) Add (modulo 0x10000), 3rd text sub-block
+                // with 3rd key sub-block.
+
+                x3 = x3 + key[ik++] & 0xffff;
+
+                // 4) Multiply (modulo 0x10001), 4th text sub-block
+                // with 4th key sub-block.
+
+                x4 = (int) ((long) x4 * key[ik++] % 0x10001L & 0xffff);
+
+                // 5) XOR results from steps 1 and 3.
+
+                t2 = x1 ^ x3;
+
+                // 6) XOR results from steps 2 and 4.
+                // Included in step 8.
+
+                // 7) Multiply (modulo 0x10001), result of step 5
+                // with 5th key sub-block.
+
+                t2 = (int) ((long) t2 * key[ik++] % 0x10001L & 0xffff);
+
+                // 8) Add (modulo 0x10000), results of steps 6 and 7.
+
+                t1 = t2 + (x2 ^ x4) & 0xffff;
+
+                // 9) Multiply (modulo 0x10001), result of step 8
+                // with 6th key sub-block.
+
+                t1 = (int) ((long) t1 * key[ik++] % 0x10001L & 0xffff);
+
+                // 10) Add (modulo 0x10000), results of steps 7 and 9.
+
+                t2 = t1 + t2 & 0xffff;
+
+                // 11) XOR results from steps 1 and 9.
+
+                x1 ^= t1;
+
+                // 14) XOR results from steps 4 and 10. (Out of order).
+
+                x4 ^= t2;
+
+                // 13) XOR results from steps 2 and 10. (Out of order).
+
+                t2 ^= x2;
+
+                // 12) XOR results from steps 3 and 9. (Out of order).
+
+                x2 = x3 ^ t1;
+
+                x3 = t2; // Results of x2 and x3 now swapped.
+
+            } while (--r != 0); // Repeats seven more rounds.
+
+            // Final output transform (4 steps).
+
+            // 1) Multiply (modulo 0x10001), 1st text-block
+            // with 1st key sub-block.
+
+            x1 = (int) ((long) x1 * key[ik++] % 0x10001L & 0xffff);
+
+            // 2) Add (modulo 0x10000), 2nd text sub-block
+            // with 2nd key sub-block. It says x3, but that is to undo swap
+            // of subblocks 2 and 3 in 8th processing round.
+
+            x3 = x3 + key[ik++] & 0xffff;
+
+            // 3) Add (modulo 0x10000), 3rd text sub-block
+            // with 3rd key sub-block. It says x2, but that is to undo swap
+            // of subblocks 2 and 3 in 8th processing round.
+
+            x2 = x2 + key[ik++] & 0xffff;
+
+            // 4) Multiply (modulo 0x10001), 4th text-block
+            // with 4th key sub-block.
+
+            x4 = (int) ((long) x4 * key[ik++] % 0x10001L & 0xffff);
+
+            // Repackage from 16-bit sub-blocks to 8-bit byte array text2.
+
+            text2[i2++] = (byte) x1;
+            text2[i2++] = (byte) (x1 >>> 8);
+            text2[i2++] = (byte) x3; // x3 and x2 are switched
+            text2[i2++] = (byte) (x3 >>> 8); // only in name.
+            text2[i2++] = (byte) x2;
+            text2[i2++] = (byte) (x2 >>> 8);
+            text2[i2++] = (byte) x4;
+            text2[i2++] = (byte) (x4 >>> 8);
+
+        } // End for loop.
+
+    } // End routine.
+
+    /*
+     * mul
+     * 
+     * Performs multiplication, modulo (2**16)+1. This code is structured on the assumption that untaken branches are
+     * cheaper than taken branches, and that the compiler doesn't schedule branches. Java: Must work with 32-bit int and
+     * one 64-bit long to keep 16-bit values and their products "unsigned." The routine assumes that both a and b could
+     * fit in 16 bits even though they come in as 32-bit ints. Lots of "& 0xFFFF" masks here to keep things 16-bit.
+     * Also, because the routine stores mod (2**16)+1 results in a 2**16 space, the result is truncated to zero whenever
+     * the result would zero, be 2**16. And if one of the multiplicands is 0, the result is not zero, but (2**16) + 1
+     * minus the other multiplicand (sort of an additive inverse mod 0x10001).
+     * 
+     * NOTE: The java conversion of this routine works correctly, but is half the speed of using Java's modulus division
+     * function (%) on the multiplication with a 16-bit masking of the result--running in the Symantec Caje IDE. So it's
+     * not called for now; the test uses Java % instead.
+     */
+
+    /*
+     * private int mul(int a, int b) throws ArithmeticException { long p; // Large enough to catch 16-bit multiply //
+     * without hitting sign bit. if (a != 0) { if(b != 0) { p = (long) a * b; b = (int) p & 0xFFFF; // Lower 16 bits. a
+     * = (int) p >>> 16; // Upper 16 bits.
+     * 
+     * return (b - a + (b < a ? 1 : 0) & 0xFFFF); } else return ((1 - a) & 0xFFFF); // If b = 0, then same as // 0x10001
+     * - a. } else // If a = 0, then return return((1 - b) & 0xFFFF); // same as 0x10001 - b. }
+     */
+
+    /*
+     * inv
+     * 
+     * Compute multiplicative inverse of x, modulo (2**16)+1 using extended Euclid's GCD (greatest common divisor)
+     * algorithm. It is unrolled twice to avoid swapping the meaning of the registers. And some subtracts are changed to
+     * adds. Java: Though it uses signed 32-bit ints, the interpretation of the bits within is strictly unsigned 16-bit.
+     */
+
+    private int inv(int x) {
+        int x2 = x;
+        int t0, t1;
+        int q, y;
+
+        if (x2 <= 1) {
+            return (x2); // 0 and 1 are self-inverse.
+        }
+
+        t1 = 0x10001 / x2; // (2**16+1)/x; x is >= 2, so fits 16 bits.
+        y = 0x10001 % x2;
+        if (y == 1) {
+            return ((1 - t1) & 0xFFFF);
+        }
+
+        t0 = 1;
+        do {
+            q = x2 / y;
+            x2 = x2 % y;
+            t0 += q * t1;
+            if (x2 == 1) {
+                return (t0);
+            }
+            q = y / x2;
+            y = y % x2;
+            t1 += q * t0;
+        } while (y != 1);
+
+        return ((1 - t1) & 0xFFFF);
+    }
+
+    boolean verify() {
+        boolean error;
+        for (int i = 0; i < array_rows; i++) {
+            error = (plain1[i] != plain2[i]);
+            if (error) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /*
+     * freeTestData
+     * 
+     * Nulls arrays and forces garbage collection to free up memory.
+     */
+
+    void freeTestData() {
+        plain1 = null;
+        crypt1 = null;
+        plain2 = null;
+        userkey = null;
+        Z = null;
+        DK = null;
+    }
+
+    public HP_idea() {
+        array_rows = 3000;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_inline01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_inline01 {
+
+    public static int test(int count) {
+        int sum = 0;
+        for (int i = 0; i < count; i++) {
+            sum += foo(i);
+        }
+        return sum;
+    }
+
+    public static int foo(int x) {
+        if (x < 15) {
+            return bar(x);
+        }
+        return bar(x + 1);
+    }
+
+    public static int bar(int x) {
+        return x + 1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(215, test(20));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_inline02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_inline02 {
+
+    public static int test(int count) {
+        int sum = 0;
+        for (int i = 0; i < count; i++) {
+            sum += foo(i, sum);
+        }
+        return sum;
+    }
+
+    public static int foo(int x, int y) {
+        if (x < 18) {
+            return bar(x, x - y);
+        }
+        return bar(x, x + y);
+    }
+
+    public static int bar(int x, int y) {
+        if (x < 15) {
+            return car(x, x + y);
+        }
+        return x - 1;
+    }
+
+    @SuppressWarnings("unused")
+    public static int car(int x, int y) {
+        if (x < 13) {
+            return x + 1;
+        }
+        return x - 1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(196, test(20));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_invoke01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_invoke01 {
+
+    private static int sum;
+
+    public static int test(int count) {
+        sum = 0;
+        final Instruction[] instructions = new Instruction[]{new Instruction.Add(), new Instruction.Sub(), new Instruction.Mul(), new Instruction.Div()};
+        final Visitor v = new Visitor();
+        for (int i = 0; i < count; i++) {
+            instructions[i % 4].accept(v);
+        }
+        return sum;
+    }
+
+    public static abstract class Instruction {
+
+        public abstract void accept(Visitor v);
+
+        public static abstract class Binary extends Instruction {
+
+        }
+
+        public static class Add extends Binary {
+
+            @Override
+            public void accept(Visitor v) {
+                v.visit(this);
+            }
+        }
+
+        public static class Sub extends Binary {
+
+            @Override
+            public void accept(Visitor v) {
+                v.visit(this);
+            }
+        }
+
+        public static class Mul extends Binary {
+
+            @Override
+            public void accept(Visitor v) {
+                v.visit(this);
+            }
+        }
+
+        public static class Div extends Binary {
+
+            @Override
+            public void accept(Visitor v) {
+                v.visit(this);
+            }
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Visitor {
+
+        public void visit(Instruction.Add i) {
+            sum += 7;
+        }
+
+        public void visit(Instruction.Sub i) {
+            sum += 194127;
+        }
+
+        public void visit(Instruction.Mul i) {
+            sum += 18991;
+        }
+
+        public void visit(Instruction.Div i) {
+            sum += 91823;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3049480, test(40));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(6098960, test(80));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_life.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+package com.oracle.max.graal.jtt.hotpath;
+
+import java.util.*;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_life {
+
+    public static int test(int generations) {
+        reset();
+        for (int i = 0; i < generations; ++i) {
+            step();
+        }
+        int sum = 0;
+        for (int row = 0; row < rows; ++row) {
+            for (int col = 0; col < cols; ++col) {
+                boolean value = cell(row, col);
+                // System.out.print(value ? "1" : "0");
+                sum += (row * 15223242 + col * 21623234) ^ ((value ? 1 : 0) * 15323142);
+            }
+        }
+        return sum;
+    }
+
+    private static final int rows = 20;
+    private static final int cols = 20;
+    private static boolean cells[] = new boolean[rows * cols];
+
+    private static boolean cell(int row, int col) {
+        return ((row >= 0) && (row < rows) && (col >= 0) && (col < cols) && cells[row * cols + col]);
+    }
+
+    private static boolean step() {
+        boolean next[] = new boolean[rows * cols];
+        boolean changed = false;
+        for (int row = rows - 1; row >= 0; --row) {
+            int row_offset = row * cols;
+            for (int col = cols - 1; col >= 0; --col) {
+                int count = 0;
+                if (cell(row - 1, col - 1)) {
+                    count++;
+                }
+                if (cell(row - 1, col)) {
+                    count++;
+                }
+                if (cell(row - 1, col + 1)) {
+                    count++;
+                }
+                if (cell(row, col - 1)) {
+                    count++;
+                }
+                if (cell(row, col + 1)) {
+                    count++;
+                }
+                if (cell(row + 1, col - 1)) {
+                    count++;
+                }
+                if (cell(row + 1, col)) {
+                    count++;
+                }
+                if (cell(row + 1, col + 1)) {
+                    count++;
+                }
+                boolean old_state = cells[row_offset + col];
+                boolean new_state = (!old_state && count == 3) || (old_state && (count == 2 || count == 3));
+                if (!changed && new_state != old_state) {
+                    changed = true;
+                }
+                next[row_offset + col] = new_state;
+            }
+        }
+        cells = next;
+        return changed;
+    }
+
+    private static void reset() {
+        Random random = new Random(0);
+        boolean cells2[] = HP_life.cells;
+        for (int offset = 0; offset < cells2.length; ++offset) {
+            cells2[offset] = random.nextDouble() > 0.5;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-1756613086, test(5));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_nest01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_nest01 {
+
+    public static int test(int count) {
+        int sum = 0;
+        for (int i = 0; i < count; i++) {
+            sum += i;
+            for (int j = 0; j < count; j++) {
+                sum += j;
+            }
+            for (int j = 0; j < count; j++) {
+                sum += j;
+            }
+        }
+        return sum;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3255, test(15));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_nest02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_nest02 {
+
+    public static int test(int count) {
+        int sum = 0;
+        for (int i = 0; i < count; i++) {
+            sum += i;
+            sum = foo(count, sum);
+            sum = foo(count, sum);
+        }
+        return sum;
+    }
+
+    private static int foo(int count, int s) {
+        int sum = s;
+        for (int j = 0; j < count; j++) {
+            sum += j;
+        }
+        return sum;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3255, test(15));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_scope01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_scope01 {
+
+    public static int test(int count) {
+        int sum = 0;
+
+        for (int k = 0; k < count; k++) {
+            {
+                int i = 1;
+                sum += i;
+            }
+            {
+                float f = 3;
+                sum += f;
+            }
+            {
+                long l = 7;
+                sum += l;
+            }
+            {
+                double d = 11;
+                sum += d;
+            }
+        }
+
+        for (int k = 0; k < count; k++) {
+            if (k < 20) {
+                int i = 1;
+                sum += i;
+            } else {
+                float f = 3;
+                sum += f;
+            }
+        }
+
+        for (int k = 0; k < count; k++) {
+            int i = 3;
+            for (int j = 0; j < count; j++) {
+                float f = 7;
+                sum += i + f;
+            }
+        }
+
+        for (int k = 0; k < count; k++) {
+            for (int j = 0; j < count; j++) {
+                float f = 7;
+                sum += j + f;
+            }
+            int i = 3;
+            sum += i;
+        }
+
+        return sum;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(59480, test(40));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_scope02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_scope02 {
+
+    public static int test(int count) {
+        int sum = 0;
+        // Although sum is not explicitly read in the tree below it is implicitly read
+        // by the guard bail-out.
+        for (int i = 0; i < count; i++) {
+            if (i > 20) {
+                break; // We need to write back either the original value of sum, or the previous iteration's value.
+            }
+            sum = i;
+        }
+        return sum;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(20, test(40));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(20, test(22));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_series.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_series {
+
+    public static double test(int count) {
+        final int arrayRows = count;
+        final double[][] testArray = new double[2][arrayRows];
+        double omega; // Fundamental frequency.
+        testArray[0][0] = TrapezoidIntegrate(0.0, // Lower bound.
+                        2.0, // Upper bound.
+                        1000, // # of steps.
+                        0.0, // No omega*n needed.
+                        0) / 2.0; // 0 = term A[0].
+        omega = 3.1415926535897932;
+        for (int i = 1; i < arrayRows; i++) {
+            testArray[0][i] = TrapezoidIntegrate(0.0, 2.0, 1000, omega * i, 1); // 1 = cosine
+            // term.
+            testArray[1][i] = TrapezoidIntegrate(0.0, 2.0, 1000, omega * i, 2); // 2 = sine
+            // term.
+        }
+        final double ref[][] = {{2.8729524964837996, 0.0}, {1.1161046676147888, -1.8819691893398025}, {0.34429060398168704, -1.1645642623320958}, {0.15238898702519288, -0.8143461113044298}};
+        double error = 0.0;
+        double sum = 0.0;
+        for (int i = 0; i < 4; i++) {
+            for (int j = 0; j < 2; j++) {
+                error += Math.abs(testArray[j][i] - ref[i][j]);
+                sum += testArray[j][i];
+            }
+        }
+        return sum + error;
+    }
+
+    private static double TrapezoidIntegrate(double x0, // Lower bound.
+                    double x1, // Upper bound.
+                    int ns, // # of steps.
+                    double omegan, // omega * n.
+                    int select) // Term type.
+    {
+        int nsteps = ns;
+        double x; // Independent variable.
+        double dx; // Step size.
+        double rvalue; // Return value.
+
+        x = x0;
+        dx = (x1 - x0) / nsteps;
+        rvalue = thefunction(x0, omegan, select) / 2.0;
+        if (nsteps != 1) {
+            --nsteps; // Already done 1 step.
+            while (--nsteps > 0) {
+                x += dx;
+                rvalue += thefunction(x, omegan, select);
+            }
+        }
+        rvalue = (rvalue + thefunction(x1, omegan, select) / 2.0) * dx;
+        return (rvalue);
+    }
+
+    private static double thefunction(double x, // Independent variable.
+                    double omegan, // Omega * term.
+                    int select) // Choose type.
+    {
+        switch (select) {
+            case 0:
+                return (Math.pow(x + 1.0, x));
+            case 1:
+                return (Math.pow(x + 1.0, x) * Math.cos(omegan * x));
+            case 2:
+                return (Math.pow(x + 1.0, x) * Math.sin(omegan * x));
+        }
+        return (0.0);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.6248571921291398d, test(100), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotpath/HP_trees01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+// Checkstyle: stop
+package com.oracle.max.graal.jtt.hotpath;
+
+import org.junit.*;
+
+/*
+ */
+public class HP_trees01 {
+
+    public static int test(int count) {
+        int sum = 0;
+        for (int i = 0; i < count; i++) {
+            if (i < 100) {
+                sum += 1;
+            } else if (i < 200) {
+                sum += 3;
+            } else if (i < 300) {
+                sum += 5;
+            } else if (i < 400) {
+                sum += 7;
+            } else if (i < 500) {
+                sum += 11;
+            }
+
+            if (i % 5 == 0) {
+                sum += 1;
+            } else if (i % 5 == 1) {
+                sum += 3;
+            } else if (i % 5 == 2) {
+                sum += 5;
+            } else if (i % 5 == 3) {
+                sum += 7;
+            } else if (i % 5 == 4) {
+                sum += 11;
+            }
+        }
+        return sum;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(8100, test(1000));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotspot/Test6186134.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.hotspot;
+
+import java.util.*;
+
+import org.junit.*;
+
+public class Test6186134 {
+
+    public static class TestClass {
+
+        int num = 0;
+
+        public TestClass(int n) {
+            num = n;
+        }
+
+        public boolean more() {
+            return num-- > 0;
+        }
+
+        public ArrayList test1() {
+            ArrayList<Object> res = new ArrayList<>();
+            int maxResults = Integer.MAX_VALUE;
+            int n = 0;
+            boolean more = more();
+            while ((n++ < maxResults) && more) {
+                res.add(new Object());
+                more = more();
+            }
+            return res;
+        }
+
+    }
+
+    public static int test(int n) {
+        for (int i = 0; i < n; i++) {
+            TestClass t = new TestClass(10);
+            int size = t.test1().size();
+            if (size != 10) {
+                return 97;
+            }
+        }
+        return 0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(100));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotspot/Test6196102.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.hotspot;
+
+import org.junit.*;
+
+/**
+ * @test
+ * @bug 6196102
+ * @summary Integer seems to be greater than Integer.MAX_VALUE
+ * 
+ * @run main Test6196102
+ */
+
+public class Test6196102 {
+
+    public static String test() {
+        int i1 = 0;
+        int i2 = Integer.MAX_VALUE;
+
+        while (i1 >= 0) {
+            i1++;
+            if (i1 > i2) {
+                return "E R R O R: " + i1;
+            }
+        }
+        return "ok";
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("ok", test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotspot/Test6753639.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.hotspot;
+
+import org.junit.*;
+
+/**
+ * @test
+ * @bug 6753639
+ * @summary Strange optimisation in for loop with cyclic integer condition
+ * 
+ * @run main/othervm -Xbatch Test6753639
+ */
+
+public class Test6753639 {
+
+    public static int test() {
+        int end = Integer.MAX_VALUE;
+        int count = 0;
+        for (int i = Integer.MAX_VALUE - 5; i <= end; i++) {
+            count++;
+            if (count > 100000) {
+                return 95;
+            }
+        }
+        return 97;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(95, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotspot/Test6850611.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.hotspot;
+
+import org.junit.*;
+
+/**
+ * @test
+ * @bug 6850611
+ * @summary int / long arithmetic seems to be broken in 1.6.0_14 HotSpot Server VM (Win XP)
+ * 
+ * @run main Test6850611
+ */
+
+public class Test6850611 {
+
+    public static int test() {
+        // for (int j = 0; j < 5; ++j) {
+        long x = 0;
+        for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; ++i) {
+            x += i;
+        }
+        if (x != -4294967295L) {
+            return 97;
+        }
+        // }
+        return 95;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(95, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotspot/Test6959129.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.hotspot;
+
+import org.junit.*;
+
+/**
+ * @test
+ * @bug 6959129
+ * @summary COMPARISON WITH INTEGER.MAX_INT DOES NOT WORK CORRECTLY IN THE CLIENT VM.
+ * 
+ *          This test will not run properly without assertions
+ * 
+ * @run main/othervm -ea Test6959129
+ */
+
+public class Test6959129 {
+
+    public static int test() {
+        int min = Integer.MAX_VALUE - 30000;
+        int max = Integer.MAX_VALUE;
+        try {
+            maxMoves(min, max);
+        } catch (AssertionError e) {
+            return 95;
+        }
+        return 97;
+    }
+
+    /**
+     * Imperative implementation that returns the length hailstone moves for a given number.
+     */
+    public static long hailstoneLengthImp(long n2) {
+        long n = n2;
+        long moves = 0;
+        while (n != 1) {
+            assert n > 1;
+            if (isEven(n)) {
+                n = n / 2;
+            } else {
+                n = 3 * n + 1;
+            }
+            ++moves;
+        }
+        return moves;
+    }
+
+    private static boolean isEven(long n) {
+        return n % 2 == 0;
+    }
+
+    /**
+     * Returns the maximum length of the hailstone sequence for numbers between min to max.
+     * 
+     * For rec1 - Assume that min is bigger than max.
+     */
+    public static long maxMoves(int min, int max) {
+        long maxmoves = 0;
+        for (int n = min; n <= max; n++) {
+            long moves = hailstoneLengthImp(n);
+            if (moves > maxmoves) {
+                maxmoves = moves;
+            }
+        }
+        return maxmoves;
+    }
+
+    // @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(95, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/hotspot/Test7005594.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.hotspot;
+
+/**
+ * @test
+ * @bug 7005594
+ * @summary Array overflow not handled correctly with loop optimzations
+ * 
+ * @run shell Test7005594.sh
+ * @##Disabled huge heap##Runs: 0 = 95
+ */
+
+public class Test7005594 {
+
+    private static int test0(byte[] a) {
+        int result = 0;
+        for (int i = 0; i < a.length; i += ((0x7fffffff >> 1) + 1)) {
+            result += a[i];
+        }
+        return result;
+    }
+
+    public static int test() {
+        byte[] a = new byte[(0x7fffffff >> 1) + 2];
+        try {
+            test0(a);
+        } catch (ArrayIndexOutOfBoundsException e) {
+            return 95;
+        }
+        return 97;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/jdk/Class_getName.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.jdk;
+
+import org.junit.*;
+
+/*
+ */
+public class Class_getName {
+
+    public static String test(int a) {
+        if (a == 0) {
+            return String.class.getName();
+        }
+        return "";
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("java.lang.String", test(0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/jdk/EnumMap01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.jdk;
+
+import java.util.*;
+
+import org.junit.*;
+
+/*
+ */
+public class EnumMap01 {
+
+    private static final EnumMap<Enum, String> map = new EnumMap<>(Enum.class);
+
+    static {
+        map.put(Enum.A, "A");
+        map.put(Enum.B, "B");
+        map.put(Enum.C, "C");
+    }
+
+    public static String test(int i) {
+        return map.get(Enum.values()[i]);
+    }
+
+    private enum Enum {
+        A, B, C
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("A", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("B", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("C", test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/jdk/EnumMap02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.jdk;
+
+import java.util.*;
+
+import org.junit.*;
+
+/*
+ */
+public class EnumMap02 {
+
+    public static String test(int i) {
+        EnumMap<Enum, String> map = new EnumMap<>(Enum.class);
+        map.put(Enum.A, "A");
+        map.put(Enum.B, "B");
+        map.put(Enum.C, "C");
+        return map.get(Enum.values()[i]);
+    }
+
+    private enum Enum {
+        A, B, C
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("A", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("B", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("C", test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/jdk/System_currentTimeMillis01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.jdk;
+
+import org.junit.*;
+
+/*
+ */
+public class System_currentTimeMillis01 {
+
+    public static int test() {
+        long start = System.currentTimeMillis();
+        for (int i = 0; i < 10000000; i++) {
+            if (System.currentTimeMillis() - start > 0) {
+                return 1;
+            }
+        }
+        return 0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/jdk/System_currentTimeMillis02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.jdk;
+
+import org.junit.*;
+
+/*
+ */
+public class System_currentTimeMillis02 {
+
+    public static boolean test() {
+        long start = System.currentTimeMillis();
+        long delta = 0;
+        for (int i = 0; delta == 0 && i < 5000000; i++) {
+            delta = System.currentTimeMillis() - start;
+            // do nothing.
+        }
+        // better get at least 40 millisecond resolution.
+        return delta >= 1 && delta < 40;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/jdk/System_nanoTime01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.jdk;
+
+import org.junit.*;
+
+/*
+ */
+public class System_nanoTime01 {
+
+    public static int test() {
+        long start = System.nanoTime();
+        for (int i = 0; i < 10000000; i++) {
+            if (System.nanoTime() - start > 0) {
+                return 1;
+            }
+        }
+        return 0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/jdk/System_nanoTime02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.jdk;
+
+import org.junit.*;
+
+/*
+ */
+public class System_nanoTime02 {
+
+    public static boolean test() {
+        long minDelta = Long.MAX_VALUE;
+
+        // the first call to System.nanoTime might take a long time due to call resolution
+        for (int c = 0; c < 10; c++) {
+            long start = System.nanoTime();
+            long delta = 0;
+            int i;
+            for (i = 0; delta == 0 && i < 50000; i++) {
+                delta = System.nanoTime() - start;
+                // do nothing.
+            }
+            if (delta < minDelta) {
+                minDelta = delta;
+            }
+        }
+
+        // better get at least 30 microsecond resolution.
+        return minDelta > 1 && minDelta < 30000;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/jdk/System_setOut.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.jdk;
+
+import java.io.*;
+
+import org.junit.*;
+
+/*
+ */
+public class System_setOut {
+
+    public static int test(int n) throws Exception {
+        PrintStream oldOut = System.out;
+        int sum = 0;
+        for (int i = 0; i < 10; i++) {
+            ByteArrayOutputStream ba = new ByteArrayOutputStream(n * 10);
+            PrintStream newOut = new PrintStream(ba);
+            System.setOut(newOut);
+            doPrint(n);
+            sum += ba.size();
+        }
+
+        System.setOut(oldOut);
+        return sum;
+    }
+
+// @NEVER_INLINE
+    private static void doPrint(int n) {
+        for (int i = 0; i < n; i++) {
+            System.out.print('x');
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        System.out.println(test(10000));
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(100000, test(10000));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/jdk/Thread_setName.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.jdk;
+
+import org.junit.*;
+
+/*
+ */
+public class Thread_setName {
+
+    public static String test(String name) {
+        String oldName = Thread.currentThread().getName();
+        Thread.currentThread().setName(name);
+        String name2 = Thread.currentThread().getName();
+        Thread.currentThread().setName(oldName);
+        return name2;
+    }
+
+    public static void main(String[] args) throws Exception {
+        System.out.println(test("abc"));
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("abc", test("abc"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/jdk/UnsafeAccess01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.jdk;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+import sun.misc.*;
+
+/*
+ */
+public class UnsafeAccess01 {
+
+    @SuppressWarnings("unused")
+    private int field = 42;
+
+    public static int test() throws SecurityException, NoSuchFieldException, IllegalAccessException {
+        final Unsafe unsafe = getUnsafe();
+
+        final UnsafeAccess01 object = new UnsafeAccess01();
+        final Field field = UnsafeAccess01.class.getDeclaredField("field");
+        final long offset = unsafe.objectFieldOffset(field);
+        final int value = unsafe.getInt(object, offset);
+        return value;
+    }
+
+    private static Unsafe getUnsafe() throws NoSuchFieldException, IllegalAccessException {
+        final Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
+        unsafeField.setAccessible(true);
+        return (Unsafe) unsafeField.get(null);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(42, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Boxed_TYPE_01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class Boxed_TYPE_01 {
+
+    public static String test(int i) {
+        if (i == 0) {
+            return Boolean.TYPE.getName();
+        }
+        if (i == 1) {
+            return Byte.TYPE.getName();
+        }
+        if (i == 2) {
+            return Character.TYPE.getName();
+        }
+        if (i == 3) {
+            return Double.TYPE.getName();
+        }
+        if (i == 4) {
+            return Float.TYPE.getName();
+        }
+        if (i == 5) {
+            return Integer.TYPE.getName();
+        }
+        if (i == 6) {
+            return Long.TYPE.getName();
+        }
+        if (i == 7) {
+            return Short.TYPE.getName();
+        }
+        if (i == 8) {
+            return Void.TYPE.getName();
+        }
+        return null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("boolean", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("byte", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("char", test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals("double", test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals("float", test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals("int", test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals("long", test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals("short", test(7));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals("void", test(8));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Bridge_method01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class Bridge_method01 {
+
+    private abstract static class Wrap<T> {
+
+        abstract T get();
+    }
+
+    private static class IWrap extends Wrap<Integer> {
+
+        @Override
+        Integer get() {
+            return 1;
+        }
+    }
+
+    private static Wrap<Integer> wrapped = new IWrap();
+
+    public static int test() {
+        return wrapped.get();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/ClassLoader_loadClass01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.lang;
+
+import java.net.*;
+
+import org.junit.*;
+
+/*
+ */
+@SuppressWarnings("static-method")
+public final class ClassLoader_loadClass01 {
+
+    public static String test(int i) throws ClassNotFoundException {
+        final URLClassLoader classLoader = new URLClassLoader(new URL[0], String.class.getClassLoader());
+        if (i == 0) {
+            return classLoader.loadClass("java.lang.String").toString();
+        } else if (i == 1) {
+            return classLoader.loadClass("[Ljava.lang.String;").toString();
+        } else if (i == 2) {
+            return classLoader.loadClass("java.lang.String[]").toString();
+        }
+        return null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("class java.lang.String", test(0));
+    }
+
+    @Test(expected = java.lang.ClassNotFoundException.class)
+    public void run1() throws Throwable {
+        test(1);
+    }
+
+    @Test(expected = java.lang.ClassNotFoundException.class)
+    public void run2() throws Throwable {
+        test(2);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(null, test(5));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_Literal01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_Literal01 {
+
+    public static String test(int i) {
+        if (i == 0) {
+            return Object.class.toString();
+        }
+        if (i == 1) {
+            return String.class.toString();
+        }
+        if (i == 2) {
+            return Class.class.toString();
+        }
+        if (i == 3) {
+            return Class_Literal01.class.toString();
+        }
+        return null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("class java.lang.Object", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("class java.lang.String", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("class java.lang.Class", test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals("class com.oracle.max.graal.jtt.lang.Class_Literal01", test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(null, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_asSubclass01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_asSubclass01 {
+
+    public static int test(int i) {
+        if (i == 0) {
+            if (Object.class.asSubclass(String.class) == null) {
+                return -1;
+            }
+        }
+        if (i == 1) {
+            if (String.class.asSubclass(Object.class) == null) {
+                return -1;
+            }
+        }
+        if (i == 2) {
+            if (Object.class.asSubclass(Class_asSubclass01.class) == null) {
+                return -1;
+            }
+        }
+        if (i == 3) {
+            if (Class_asSubclass01.class.asSubclass(Object.class) == null) {
+                return -1;
+            }
+        }
+        return i;
+    }
+
+    @Test(expected = java.lang.ClassCastException.class)
+    public void run0() throws Throwable {
+        test(0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test(expected = java.lang.ClassCastException.class)
+    public void run2() throws Throwable {
+        test(2);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(3, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(4, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_cast01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_cast01 {
+
+    static final String string = "";
+    static final Object object = new Object();
+    static final Class_cast01 thisObject = new Class_cast01();
+
+    public static int test(int i) {
+        if (i == 0) {
+            if (Object.class.cast(string) == null) {
+                return -1;
+            }
+        }
+        if (i == 1) {
+            if (String.class.cast(object) == null) {
+                return -1;
+            }
+        }
+        if (i == 2) {
+            if (Object.class.cast(thisObject) == null) {
+                return -1;
+            }
+        }
+        if (i == 3) {
+            if (Class_cast01.class.cast(object) == null) {
+                return -1;
+            }
+        }
+        return i;
+    }
+
+    @Test(expected = java.lang.ClassCastException.class)
+    public void run0() throws Throwable {
+        test(1);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test(expected = java.lang.ClassCastException.class)
+    public void run2() throws Throwable {
+        test(3);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(4, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_cast02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_cast02 {
+
+    static final String string = "";
+    static final Object object = new Object();
+    static final Class_cast02 thisObject = new Class_cast02();
+
+    public static int test(int i) {
+        if (i == 0) {
+            if (Object.class.cast(null) == null) {
+                return -1;
+            }
+        }
+        if (i == 1) {
+            if (String.class.cast(null) == null) {
+                return -1;
+            }
+        }
+        if (i == 2) {
+            if (Object.class.cast(null) == null) {
+                return -1;
+            }
+        }
+        if (i == 3) {
+            if (Class_cast02.class.cast(null) == null) {
+                return -1;
+            }
+        }
+        return i;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-1, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-1, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(4, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_forName01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_forName01 {
+
+    public static String test(int i) throws ClassNotFoundException {
+        if (i == 0) {
+            return Class.forName("java.lang.Object").toString();
+        }
+        if (i == 1) {
+            return Class.forName("java.lang.String").toString();
+        }
+        if (i == 2) {
+            return Class.forName("com.oracle.max.graal.jtt.lang.Class_forName01").toString();
+        }
+        if (i == 3) {
+            return Class.forName("xyxzz.xyzyzyz.XXYYY").toString();
+        }
+        return null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("class java.lang.Object", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("class java.lang.String", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("class com.oracle.max.graal.jtt.lang.Class_forName01", test(2));
+    }
+
+    @Test(expected = java.lang.ClassNotFoundException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(null, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_forName02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_forName02 {
+
+    public static String test(int i) throws ClassNotFoundException {
+        String clname = null;
+        Class cl = null;
+        if (i == 0) {
+            clname = "java.lang.Object";
+            cl = Object.class;
+        } else if (i == 1) {
+            clname = "java.lang.String";
+            cl = String.class;
+        } else if (i == 2) {
+            clname = "com.oracle.max.graal.jtt.lang.Class_forName02";
+            cl = Class_forName02.class;
+        } else if (i == 3) {
+            clname = "xyzz.zyxy.XYXY";
+            cl = Class_forName02.class;
+        }
+        if (clname != null) {
+            return Class.forName(clname, false, cl.getClassLoader()).toString();
+        }
+        return null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("class java.lang.Object", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("class java.lang.String", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("class com.oracle.max.graal.jtt.lang.Class_forName02", test(2));
+    }
+
+    @Test(expected = java.lang.ClassNotFoundException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(null, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_forName03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import java.net.*;
+
+import org.junit.*;
+
+/*
+ */
+@SuppressWarnings("static-method")
+public final class Class_forName03 {
+
+    public static String test(int i) throws ClassNotFoundException {
+        String clname = null;
+        Class cl = null;
+        if (i == 0) {
+            clname = "java.lang.Object[]";
+            cl = Object.class;
+        } else if (i == 1) {
+            clname = "[Ljava.lang.String;";
+            cl = String.class;
+        } else if (i == 2) {
+            clname = "[Ljava/lang/String;";
+            cl = String.class;
+        } else if (i == 3) {
+            clname = "[I";
+            cl = Class_forName03.class;
+        } else if (i == 4) {
+            clname = "[java.lang.Object;";
+            cl = Class_forName03.class;
+        }
+        if (clname != null) {
+            return Class.forName(clname, false, new URLClassLoader(new URL[0], cl.getClassLoader())).toString();
+        }
+        return null;
+    }
+
+    @Test(expected = java.lang.ClassNotFoundException.class)
+    public void run0() throws Throwable {
+        test(0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("class [Ljava.lang.String;", test(1));
+    }
+
+    @Test(expected = java.lang.ClassNotFoundException.class)
+    public void run2() throws Throwable {
+        test(2);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals("class [I", test(3));
+    }
+
+    @Test(expected = java.lang.ClassNotFoundException.class)
+    public void run4() throws Throwable {
+        test(4);
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(null, test(5));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_forName04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+@SuppressWarnings("static-method")
+public final class Class_forName04 {
+
+    public static String test(int i) throws ClassNotFoundException {
+        String clname = null;
+        if (i == 0) {
+            clname = "java.lang.Object[]";
+        } else if (i == 1) {
+            clname = "[Ljava.lang.String;";
+        } else if (i == 2) {
+            clname = "[Ljava/lang/String;";
+        } else if (i == 3) {
+            clname = "[I";
+        } else if (i == 4) {
+            clname = "[java.lang.Object;";
+        }
+        if (clname != null) {
+            return Class.forName(clname).toString();
+        }
+        return null;
+    }
+
+    @Test(expected = java.lang.ClassNotFoundException.class)
+    public void run0() throws Throwable {
+        test(0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("class [Ljava.lang.String;", test(1));
+    }
+
+    @Test(expected = java.lang.ClassNotFoundException.class)
+    public void run2() throws Throwable {
+        test(2);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals("class [I", test(3));
+    }
+
+    @Test(expected = java.lang.ClassNotFoundException.class)
+    public void run4() throws Throwable {
+        test(4);
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(null, test(5));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_forName05.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.lang;
+
+import java.net.*;
+
+import org.junit.*;
+
+/*
+ */
+@SuppressWarnings("static-method")
+public final class Class_forName05 {
+
+    public static String test(int i) throws ClassNotFoundException {
+        final URLClassLoader classLoader = new URLClassLoader(new URL[0], String.class.getClassLoader());
+        if (i == 0) {
+            return Class.forName("java.lang.String", false, classLoader).toString();
+        } else if (i == 1) {
+            return Class.forName("[Ljava.lang.String;", false, classLoader).toString();
+        }
+        return null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("class java.lang.String", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("class [Ljava.lang.String;", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(null, test(5));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_getComponentType01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_getComponentType01 {
+
+    public static String test(int i) {
+        Class cl = Object.class;
+        if (i == 0) {
+            cl = int.class;
+        } else if (i == 1) {
+            cl = int[].class;
+        } else if (i == 2) {
+            cl = Object.class;
+        } else if (i == 3) {
+            cl = Object[].class;
+        } else if (i == 4) {
+            cl = Class_getComponentType01.class;
+        } else if (i == 5) {
+            cl = Cloneable.class;
+        } else if (i == 6) {
+            cl = Object[][].class;
+        } else if (i == 7) {
+            cl = void.class;
+        }
+        cl = cl.getComponentType();
+        if (cl == null) {
+            return null;
+        }
+        return cl.getName();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(null, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("int", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(null, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals("java.lang.Object", test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(null, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(null, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals("[Ljava.lang.Object;", test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(null, test(7));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(null, test(8));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_getInterfaces01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2010, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+
+@SuppressWarnings("static-method")
+public final class Class_getInterfaces01 {
+
+    public static String test(int i) {
+        switch (i) {
+            case 0:
+                return toString(I1.class);
+            case 1:
+                return toString(I2.class);
+            case 2:
+                return toString(C1.class);
+            case 3:
+                return toString(C2.class);
+            case 4:
+                return toString(C12.class);
+            default:
+                return null;
+        }
+    }
+
+    private static String toString(Class< ? > klass) {
+        final Class< ? >[] classes = klass.getInterfaces();
+        final StringBuilder sb = new StringBuilder();
+        boolean first = true;
+        for (Class< ? > c : classes) {
+            if (!first) {
+                sb.append(' ');
+            } else {
+                first = false;
+            }
+            sb.append(c.getName());
+        }
+        return sb.toString();
+    }
+
+    interface I1 {
+
+    }
+
+    interface I2 extends I1 {
+
+    }
+
+    static class C1 implements I1 {
+
+    }
+
+    static class C2 implements I2 {
+
+    }
+
+    static class C12 implements I1, I2 {
+
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("com.oracle.max.graal.jtt.lang.Class_getInterfaces01$I1", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("com.oracle.max.graal.jtt.lang.Class_getInterfaces01$I1", test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals("com.oracle.max.graal.jtt.lang.Class_getInterfaces01$I2", test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals("com.oracle.max.graal.jtt.lang.Class_getInterfaces01$I1 com.oracle.max.graal.jtt.lang.Class_getInterfaces01$I2", test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_getName01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_getName01 {
+
+    public static String test(int i) {
+        if (i == 0) {
+            return Object.class.getName();
+        } else if (i == 1) {
+            return Class.class.getName();
+        } else if (i == 2) {
+            return Class_getName01.class.getName();
+        } else if (i == 3) {
+            return "a string".getClass() == String.class ? "true" : "false";
+        }
+        return null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("java.lang.Object", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("java.lang.Class", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("com.oracle.max.graal.jtt.lang.Class_getName01", test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals("true", test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(null, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_getName02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_getName02 {
+
+    public static String test(int i) {
+        if (i == 0) {
+            return int.class.getName();
+        }
+        if (i == 1) {
+            return int[].class.getName();
+        }
+        if (i == 2) {
+            return Object[][].class.getName();
+        }
+        return null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("int", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("[I", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("[[Ljava.lang.Object;", test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(null, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_getSimpleName01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+/*
+ */
+package com.oracle.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_getSimpleName01 {
+
+    public static String test(int i) {
+        if (i == 0) {
+            return Object.class.getSimpleName();
+        }
+        if (i == 1) {
+            return Class.class.getSimpleName();
+        }
+        if (i == 2) {
+            return Class_getSimpleName01.class.getSimpleName();
+        }
+        return null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("Object", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("Class", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("Class_getSimpleName01", test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(null, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_getSimpleName02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+/*
+ */
+package com.oracle.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_getSimpleName02 {
+
+    public static String test(int i) {
+        if (i == 0) {
+            return int.class.getSimpleName();
+        }
+        if (i == 1) {
+            return int[].class.getSimpleName();
+        }
+        if (i == 2) {
+            return Object[][].class.getSimpleName();
+        }
+        return null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("int", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("int[]", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("Object[][]", test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(null, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_getSuperClass01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_getSuperClass01 {
+
+    public static String test(int i) {
+        Class cl = Object.class;
+        if (i == 0) {
+            cl = int.class;
+        } else if (i == 1) {
+            cl = Object.class;
+        } else if (i == 2) {
+            cl = int[].class;
+        } else if (i == 3) {
+            cl = Cloneable.class;
+        } else if (i == 4) {
+            cl = Integer.class;
+        } else if (i == 5) {
+            cl = Class.class;
+        } else if (i == 6) {
+            cl = Class_getSuperClass01.class;
+        }
+        cl = cl.getSuperclass();
+        if (cl == null) {
+            return null;
+        }
+        return cl.getName();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(null, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(null, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("java.lang.Object", test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(null, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals("java.lang.Number", test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals("java.lang.Object", test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals("java.lang.Object", test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(null, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_isArray01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_isArray01 {
+
+    public static boolean test(int i) {
+        if (i == 0) {
+            return int.class.isArray();
+        }
+        if (i == 1) {
+            return int[].class.isArray();
+        }
+        if (i == 2) {
+            return Object.class.isArray();
+        }
+        if (i == 3) {
+            return Object[].class.isArray();
+        }
+        if (i == 4) {
+            return Class_isArray01.class.isArray();
+        }
+        if (i == 5) {
+            return Cloneable.class.isArray();
+        }
+        if (i == 6) {
+            return Runnable.class.isArray();
+        }
+        if (i == 7) {
+            return void.class.isArray();
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(false, test(7));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(false, test(8));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_isAssignableFrom01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_isAssignableFrom01 {
+
+    public static boolean test(int i) {
+        Class source = Object.class;
+        if (i == 0) {
+            source = int.class;
+        }
+        if (i == 1) {
+            source = int[].class;
+        }
+        if (i == 2) {
+            source = float.class;
+        }
+        if (i == 3) {
+            source = byte.class;
+        }
+        if (i == 4) {
+            source = Runnable.class;
+        }
+        if (i == 5) {
+            source = Class_isAssignableFrom01.class;
+        }
+        if (i == 6) {
+            source = Object[].class;
+        }
+        return int.class.isAssignableFrom(source);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(false, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_isAssignableFrom02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_isAssignableFrom02 {
+
+    public static boolean test(int i) {
+        Class source = Object.class;
+        if (i == 0) {
+            source = int.class;
+        }
+        if (i == 1) {
+            source = int[].class;
+        }
+        if (i == 2) {
+            source = float.class;
+        }
+        if (i == 3) {
+            source = byte.class;
+        }
+        if (i == 4) {
+            source = Runnable.class;
+        }
+        if (i == 5) {
+            source = Class_isAssignableFrom02.class;
+        }
+        if (i == 6) {
+            source = Object[].class;
+        }
+        return Object.class.isAssignableFrom(source);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(true, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_isAssignableFrom03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_isAssignableFrom03 implements Cloneable {
+
+    public static boolean test(int i) {
+        Class source = Object.class;
+        if (i == 0) {
+            source = int.class;
+        }
+        if (i == 1) {
+            source = int[].class;
+        }
+        if (i == 2) {
+            source = float.class;
+        }
+        if (i == 3) {
+            source = Cloneable.class;
+        }
+        if (i == 4) {
+            source = Runnable.class;
+        }
+        if (i == 5) {
+            source = Class_isAssignableFrom03.class;
+        }
+        if (i == 6) {
+            source = Object[].class;
+        }
+        return Cloneable.class.isAssignableFrom(source);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(false, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_isInstance01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_isInstance01 {
+
+    static final String string = "";
+    static final Object obj = new Object();
+    static final Class_isInstance01 thisObject = new Class_isInstance01();
+
+    public static boolean test(int i) {
+        Object object = null;
+        if (i == 0) {
+            object = obj;
+        }
+        if (i == 1) {
+            object = string;
+        }
+        if (i == 2) {
+            object = thisObject;
+        }
+        return Object.class.isInstance(object);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_isInstance02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_isInstance02 {
+
+    static final String string = "";
+    static final Object obj = new Object();
+    static final Class_isInstance02 thisObject = new Class_isInstance02();
+
+    public static boolean test(int i) {
+        Object object = null;
+        if (i == 0) {
+            object = obj;
+        }
+        if (i == 1) {
+            object = string;
+        }
+        if (i == 2) {
+            object = thisObject;
+        }
+        return String.class.isInstance(object);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_isInstance03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_isInstance03 {
+
+    static final String string = "";
+    static final Object obj = new Object();
+    static final Class_isInstance03 thisObject = new Class_isInstance03();
+
+    public static boolean test(int i) {
+        Object object = null;
+        if (i == 0) {
+            object = obj;
+        }
+        if (i == 1) {
+            object = string;
+        }
+        if (i == 2) {
+            object = thisObject;
+        }
+        return Class_isInstance03.class.isInstance(object);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_isInstance04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_isInstance04 {
+
+    static final String string = "";
+    static final Object[] oarray = {};
+    static final String[] sarray = {};
+
+    public static boolean test(int i) {
+        Object object = null;
+        if (i == 0) {
+            object = oarray;
+        }
+        if (i == 1) {
+            object = string;
+        }
+        if (i == 2) {
+            object = sarray;
+        }
+        return String[].class.isInstance(object);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_isInstance05.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_isInstance05 {
+
+    static final String string = "";
+    static final Object obj = new Object();
+    static final int[] array = {};
+
+    public static boolean test(int i) {
+        Object object = null;
+        if (i == 0) {
+            object = obj;
+        }
+        if (i == 1) {
+            object = string;
+        }
+        if (i == 2) {
+            object = array;
+        }
+        return int[].class.isInstance(object);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_isInstance06.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_isInstance06 implements Cloneable {
+
+    static final String string = "";
+    static final Object obj = new Object();
+    static final String[] sarray = {};
+    static final Object thisObject = new Class_isInstance06();
+
+    public static boolean test(int i) {
+        Object object = null;
+        if (i == 0) {
+            object = obj;
+        }
+        if (i == 1) {
+            object = string;
+        }
+        if (i == 2) {
+            object = sarray;
+        }
+        if (i == 3) {
+            object = thisObject;
+        }
+        return Cloneable.class.isInstance(object);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_isInterface01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_isInterface01 {
+
+    public static boolean test(int i) {
+        if (i == 0) {
+            return int.class.isInterface();
+        }
+        if (i == 1) {
+            return int[].class.isInterface();
+        }
+        if (i == 2) {
+            return Object.class.isInterface();
+        }
+        if (i == 3) {
+            return Object[].class.isInterface();
+        }
+        if (i == 4) {
+            return Class_isInterface01.class.isInterface();
+        }
+        if (i == 5) {
+            return Cloneable.class.isInterface();
+        }
+        if (i == 6) {
+            return Runnable.class.isInterface();
+        }
+        if (i == 7) {
+            return void.class.isInterface();
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(false, test(7));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(false, test(8));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Class_isPrimitive01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_isPrimitive01 {
+
+    public static boolean test(int i) {
+        if (i == 0) {
+            return int.class.isPrimitive();
+        }
+        if (i == 1) {
+            return int[].class.isPrimitive();
+        }
+        if (i == 2) {
+            return Object.class.isPrimitive();
+        }
+        if (i == 3) {
+            return Object[].class.isPrimitive();
+        }
+        if (i == 4) {
+            return Class_isPrimitive01.class.isPrimitive();
+        }
+        if (i == 5) {
+            return Cloneable.class.isPrimitive();
+        }
+        if (i == 6) {
+            return Runnable.class.isPrimitive();
+        }
+        if (i == 7) {
+            return void.class.isPrimitive();
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(true, test(7));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(false, test(8));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Double_01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class Double_01 {
+
+    public static boolean test() {
+        return Double.doubleToLongBits(Double.longBitsToDouble(0x7ff8000000000088L)) == 0x7ff8000000000000L;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Double_toString.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+@SuppressWarnings("static-method")
+public final class Double_toString {
+
+    public static String test() {
+        double z1 = 0.4363485526704198;
+        double z2 = -0.43536514763046896;
+        double z3 = z1 + z2;
+        return Double.toString(z3);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("9.834050399508132E-4", test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Float_01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+public class Float_01 {
+
+    public static boolean test(float f) {
+        return /* Float.isNaN(f); */f != f;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(1.0f));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(2.0f));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(0.5f));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(java.lang.Float.NaN));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Float_02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class Float_02 {
+
+    public static boolean test(float f) {
+        return f != 1.0f;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(1.0f));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(2.0f));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(0.5f));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(java.lang.Float.NaN));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Float_03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class Float_03 {
+
+    public static boolean test() {
+        return Float.floatToIntBits(Float.intBitsToFloat(0x7fc00088)) == 0x7fc00000;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Int_greater01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Int_greater01 {
+
+    public static boolean test(int i) {
+        if (i > 0) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-2147483648));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(-2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(-1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(2147483647));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Int_greater02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Int_greater02 {
+
+    public static boolean test(int i) {
+        if (i > 5) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-2147483648));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(-2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(-1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(4));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(5));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(true, test(6));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(true, test(2147483647));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Int_greater03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Int_greater03 {
+
+    public static boolean test(int i) {
+        if (i > -5) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-2147483648));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(-6));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(-5));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(-4));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(-1));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(true, test(2147483647));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Int_greaterEqual01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Int_greaterEqual01 {
+
+    public static boolean test(int i) {
+        if (i >= 0) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-2147483648));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(-2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(-1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(2147483647));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Int_greaterEqual02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Int_greaterEqual02 {
+
+    public static boolean test(int i) {
+        if (i >= 5) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-2147483648));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(-2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(-1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(4));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(5));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(true, test(6));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(true, test(2147483647));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Int_greaterEqual03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Int_greaterEqual03 {
+
+    public static boolean test(int i) {
+        if (i >= -5) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-2147483648));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(-6));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(-5));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(-4));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(-1));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(true, test(2147483647));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Int_less01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Int_less01 {
+
+    public static boolean test(int i) {
+        if (i < 0) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-2147483648));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(-2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(-1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(2));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(2147483647));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Int_less02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Int_less02 {
+
+    public static boolean test(int i) {
+        if (i < 5) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-2147483648));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(-2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(-1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(false, test(2147483647));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Int_less03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Int_less03 {
+
+    public static boolean test(int i) {
+        if (i < -5) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-2147483648));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(-6));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(-5));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(-4));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(-1));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(false, test(2));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(false, test(2147483647));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Int_lessEqual01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Int_lessEqual01 {
+
+    public static boolean test(int i) {
+        if (i <= 0) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-2147483648));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(-2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(-1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(2));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(2147483647));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Int_lessEqual02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Int_lessEqual02 {
+
+    public static boolean test(int i) {
+        if (i <= 5) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-2147483648));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(-2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(-1));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(false, test(2147483647));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Int_lessEqual03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Int_lessEqual03 {
+
+    public static boolean test(int i) {
+        if (i <= -5) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-2147483648));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(-6));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(-5));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(-4));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(-1));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(false, test(2));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(false, test(2147483647));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/JDK_ClassLoaders01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class JDK_ClassLoaders01 {
+
+    public static boolean test(int i) {
+        if (i == 0) {
+            return Object.class.getClassLoader() == null;
+        }
+        if (i == 1) {
+            return Class.class.getClassLoader() == null;
+        }
+        if (i == 2) {
+            return String.class.getClassLoader() == null;
+        }
+        if (i == 3) {
+            return Thread.class.getClassLoader() == null;
+        }
+        if (i == 4) {
+            return System.class.getClassLoader() == null;
+        }
+        if (i == 5) {
+            return ClassLoader.class.getClassLoader() == null;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(6));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/JDK_ClassLoaders02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
+ * that is described in this document. In particular, and without limitation, these intellectual property
+ * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
+ * more additional patents or pending patent applications in the U.S. and in other countries.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject to the Sun
+ * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
+ * supplements.
+ *
+ * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
+ * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
+ * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
+ * U.S. and other countries.
+ *
+ * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
+ * Company, Ltd.
+ */
+package com.oracle.max.graal.jtt.lang;
+
+import java.net.*;
+
+import org.junit.*;
+
+/*
+ */
+public class JDK_ClassLoaders02 {
+
+    public static boolean test() {
+        ClassLoader classLoader = JDK_ClassLoaders02.class.getClassLoader();
+        return classLoader == null || classLoader instanceof URLClassLoader;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Long_greater01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+@SuppressWarnings("static-method")
+public final class Long_greater01 {
+
+    public static boolean test(long i) {
+        if (i > 0L) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-9223372036854775808L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(-2L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(-1L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(0L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(1L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(2L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(9223372036854775807L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Long_greater02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Long_greater02 {
+
+    public static boolean test(long i) {
+        if (i > 5L) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-9223372036854775808L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(-2L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(-1L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(0L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(1L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(4L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(5L));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(true, test(6L));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(true, test(9223372036854775807L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Long_greater03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Long_greater03 {
+
+    public static boolean test(long i) {
+        if (i > -5L) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-9223372036854775808L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(-6L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(-5L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(-4L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(-1L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(0L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(1L));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(true, test(2L));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(true, test(9223372036854775807L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Long_greaterEqual01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Long_greaterEqual01 {
+
+    public static boolean test(long i) {
+        if (i >= 0L) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-9223372036854775808L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(-2L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(-1L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(0L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(1L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(2L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(9223372036854775807L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Long_greaterEqual02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Long_greaterEqual02 {
+
+    public static boolean test(long i) {
+        if (i >= 5L) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-9223372036854775808L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(-2L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(-1L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(0L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(1L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(4L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(5L));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(true, test(6L));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(true, test(9223372036854775807L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Long_greaterEqual03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Long_greaterEqual03 {
+
+    public static boolean test(long i) {
+        if (i >= -5L) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(-9223372036854775808L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(-6L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(-5L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(-4L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(-1L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(0L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(1L));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(true, test(2L));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(true, test(9223372036854775807L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Long_less01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Long_less01 {
+
+    public static boolean test(long i) {
+        if (i < 0L) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-9223372036854775808L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(-2L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(-1L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(0L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(1L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(2L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(9223372036854775807L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Long_less02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Long_less02 {
+
+    public static boolean test(long i) {
+        if (i < 5L) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-9223372036854775808L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(-2L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(-1L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(0L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(5L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(6L));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(false, test(9223372036854775807L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Long_less03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Long_less03 {
+
+    public static boolean test(long i) {
+        if (i < -5L) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-9223372036854775808L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(-6L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(-5L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(-4L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(-1L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(0L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(1L));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(false, test(2L));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(false, test(9223372036854775807L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Long_lessEqual01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Long_lessEqual01 {
+
+    public static boolean test(long i) {
+        if (i <= 0L) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-2L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(-9223372036854775808L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(-2L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(-1L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(0L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(1L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(2L));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(false, test(9223372036854775807L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Long_lessEqual02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Long_lessEqual02 {
+
+    public static boolean test(long i) {
+        if (i <= 5L) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-9223372036854775808L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(-2L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(-1L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(0L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(5L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(6L));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(false, test(9223372036854775807L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Long_lessEqual03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Long_lessEqual03 {
+
+    public static boolean test(long i) {
+        if (i <= -5L) {
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-9223372036854775808L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(-6L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(-5L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(-4L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(-1L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(0L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(false, test(1L));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(false, test(2L));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(false, test(9223372036854775807L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Long_reverseBytes01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class Long_reverseBytes01 {
+
+    public static long test(long val) {
+        return Long.reverseBytes(val);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0x877665544332211L, test(0x1122334455667708L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Long_reverseBytes02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class Long_reverseBytes02 {
+
+    public static long test(long val) {
+        return (((val >> 56) & 0xff) << 0) | (((val >> 48) & 0xff) << 8) | (((val >> 40) & 0xff) << 16) | (((val >> 32) & 0xff) << 24) | (((val >> 24) & 0xff) << 32) | (((val >> 16) & 0xff) << 40) |
+                        (((val >> 8) & 0xff) << 48) | (((val >> 0) & 0xff) << 56);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0x877665544332211L, test(0x1122334455667708L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Math_abs.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class Math_abs {
+
+    @SuppressWarnings("serial")
+    public static class NaN extends Throwable {
+    }
+
+    public static double test(double arg) throws NaN {
+        double v = Math.abs(arg);
+        if (Double.isNaN(v)) {
+            // NaN can't be tested against itself
+            throw new NaN();
+        }
+        return v;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(5.0d, test(5.0d), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(5.0d, test(-5.0d), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0.0d, test(0.0d), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0.0d, test(-0.0d), 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(java.lang.Double.POSITIVE_INFINITY, test(java.lang.Double.NEGATIVE_INFINITY), 0);
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(java.lang.Double.POSITIVE_INFINITY, test(java.lang.Double.POSITIVE_INFINITY), 0);
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_abs.NaN.class)
+    public void run6() throws Throwable {
+        test(java.lang.Double.NaN);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Math_cos.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class Math_cos {
+
+    @SuppressWarnings("serial")
+    public static class NaN extends Throwable {
+    }
+
+    public static double test(double arg) throws NaN {
+        double v = Math.cos(arg);
+        if (Double.isNaN(v)) {
+            // NaN can't be tested against itself
+            throw new NaN();
+        }
+        return v;
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_cos.NaN.class)
+    public void run0() throws Throwable {
+        test(java.lang.Double.NaN);
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_cos.NaN.class)
+    public void run1() throws Throwable {
+        test(java.lang.Double.NEGATIVE_INFINITY);
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_cos.NaN.class)
+    public void run2() throws Throwable {
+        test(java.lang.Double.POSITIVE_INFINITY);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Math_log.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class Math_log {
+
+    @SuppressWarnings("serial")
+    public static class NaN extends Throwable {
+    }
+
+    public static double test(double arg) throws NaN {
+        double v = Math.log(arg);
+        if (Double.isNaN(v)) {
+            // NaN can't be tested against itself
+            throw new NaN();
+        }
+        return v;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1.0d, test(java.lang.Math.E), 0);
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_log.NaN.class)
+    public void run1() throws Throwable {
+        test(java.lang.Double.NaN);
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_log.NaN.class)
+    public void run2() throws Throwable {
+        test(-1.0d);
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_log.NaN.class)
+    public void run3() throws Throwable {
+        test(java.lang.Double.NEGATIVE_INFINITY);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(java.lang.Double.POSITIVE_INFINITY, test(java.lang.Double.POSITIVE_INFINITY), 0);
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(java.lang.Double.NEGATIVE_INFINITY, test(0.0d), 0);
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(java.lang.Double.NEGATIVE_INFINITY, test(-0.0d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Math_log10.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class Math_log10 {
+
+    @SuppressWarnings("serial")
+    public static class NaN extends Throwable {
+    }
+
+    public static double test(double arg) throws NaN {
+        double v = Math.log10(arg);
+        if (Double.isNaN(v)) {
+            // NaN can't be tested against itself
+            throw new NaN();
+        }
+        return v;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.0d, test(1.0d), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1.0d, test(10.0d), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2.0d, test(100.0d), 0);
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_log10.NaN.class)
+    public void run3() throws Throwable {
+        test(java.lang.Double.NaN);
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_log10.NaN.class)
+    public void run4() throws Throwable {
+        test(-1.0d);
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_log10.NaN.class)
+    public void run5() throws Throwable {
+        test(java.lang.Double.NEGATIVE_INFINITY);
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(java.lang.Double.POSITIVE_INFINITY, test(java.lang.Double.POSITIVE_INFINITY), 0);
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(java.lang.Double.NEGATIVE_INFINITY, test(0.0d), 0);
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(java.lang.Double.NEGATIVE_INFINITY, test(-0.0d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Math_pow.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class Math_pow {
+
+    public static double test(double pow) {
+        return Math.pow(2.0d, pow);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(4.0d, test(2d), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(8.574187700290345d, test(3.1d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Math_sin.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class Math_sin {
+
+    @SuppressWarnings("serial")
+    public static class NaN extends Throwable {
+    }
+
+    public static double test(double arg) throws NaN {
+        double v = Math.sin(arg);
+        if (Double.isNaN(v)) {
+            // NaN can't be tested against itself
+            throw new NaN();
+        }
+        return v;
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_sin.NaN.class)
+    public void run0() throws Throwable {
+        test(java.lang.Double.NaN);
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_sin.NaN.class)
+    public void run1() throws Throwable {
+        test(java.lang.Double.NEGATIVE_INFINITY);
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_sin.NaN.class)
+    public void run2() throws Throwable {
+        test(java.lang.Double.POSITIVE_INFINITY);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-0.0d, test(-0.0d), 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0.0d, test(0.0d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Math_sqrt.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class Math_sqrt {
+
+    @SuppressWarnings("serial")
+    public static class NaN extends Throwable {
+    }
+
+    public static double test(double arg) throws NaN {
+        double v = Math.sqrt(arg);
+        if (Double.isNaN(v)) {
+            // NaN can't be tested against itself
+            throw new NaN();
+        }
+        return v;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(2.0d, test(4.0d), 0);
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_sqrt.NaN.class)
+    public void run1() throws Throwable {
+        test(java.lang.Double.NaN);
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_sqrt.NaN.class)
+    public void run2() throws Throwable {
+        test(-1.0d);
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_sqrt.NaN.class)
+    public void run3() throws Throwable {
+        test(java.lang.Double.NEGATIVE_INFINITY);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(java.lang.Double.POSITIVE_INFINITY, test(java.lang.Double.POSITIVE_INFINITY), 0);
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(0.0d, test(0.0d), 0);
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(-0.0d, test(-0.0d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Math_tan.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class Math_tan {
+
+    @SuppressWarnings("serial")
+    public static class NaN extends Throwable {
+    }
+
+    public static double test(double arg) throws NaN {
+        double v = Math.tan(arg);
+        if (Double.isNaN(v)) {
+            // NaN can't be tested against itself
+            throw new NaN();
+        }
+        return v;
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_tan.NaN.class)
+    public void run0() throws Throwable {
+        test(java.lang.Double.NaN);
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_tan.NaN.class)
+    public void run1() throws Throwable {
+        test(java.lang.Double.NEGATIVE_INFINITY);
+    }
+
+    @Test(expected = com.oracle.max.graal.jtt.lang.Math_tan.NaN.class)
+    public void run2() throws Throwable {
+        test(java.lang.Double.POSITIVE_INFINITY);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-0.0d, test(-0.0d), 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0.0d, test(0.0d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Object_clone01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+public class Object_clone01 {
+
+    static final Object_clone01 field = new Object_clone01();
+
+    public static boolean test(int i) throws CloneNotSupportedException {
+        return field.tryClone(i);
+    }
+
+    @SuppressWarnings("unused")
+    private boolean tryClone(int i) throws CloneNotSupportedException {
+        return this == this.clone();
+    }
+
+    @Test(expected = java.lang.CloneNotSupportedException.class)
+    public void run0() throws Throwable {
+        test(0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Object_clone02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+public class Object_clone02 implements Cloneable {
+
+    static final Object_clone02 field = new Object_clone02();
+
+    public static boolean test(int i) throws CloneNotSupportedException {
+        return field.tryClone(i);
+    }
+
+    @SuppressWarnings("unused")
+    private boolean tryClone(int i) throws CloneNotSupportedException {
+        return this == this.clone();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Object_equals01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Object_equals01 {
+
+    public static Object_equals01 field = new Object_equals01();
+
+    public static boolean test(int i) {
+        final Object obj1 = new Object();
+        final Object obj2 = new Object();
+        switch (i) {
+            case 0:
+                return obj1.equals(field);
+            case 1:
+                return obj1.equals(obj2);
+            case 2:
+                return obj1.equals(null);
+            case 3:
+                return obj1.equals(obj1);
+            case 4:
+                return field.equals(field);
+            case 5:
+                return obj2.equals(field);
+            case 6:
+                return obj2.equals(obj2);
+            case 7:
+                return obj2.equals(null);
+            case 8:
+                return obj2.equals(obj1);
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(false, test(7));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(false, test(8));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Object_getClass01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Object_getClass01 {
+
+    static final Object object = new Object();
+    static final Object string = new String();
+    static final Object_getClass01 thisObject = new Object_getClass01();
+
+    public static String test(int i) {
+        if (i == 0) {
+            return object.getClass().toString();
+        }
+        if (i == 1) {
+            return string.getClass().toString();
+        }
+        if (i == 2) {
+            return thisObject.getClass().toString();
+        }
+        if (i == 3) {
+            return thisObject.getClass().getClass().toString();
+        }
+        return null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("class java.lang.Object", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("class java.lang.String", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("class com.oracle.max.graal.jtt.lang.Object_getClass01", test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals("class java.lang.Class", test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(null, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Object_hashCode01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Object_hashCode01 {
+
+    public static boolean test() {
+        final Object o1 = new Object();
+        final Object o2 = new Object();
+        return o1.hashCode() != 0 || o2.hashCode() != 0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Object_notify01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Object_notify01 {
+
+    static final Object object = new Object();
+
+    public static boolean test() {
+        object.notify();
+        return true;
+    }
+
+    @Test(expected = java.lang.IllegalMonitorStateException.class)
+    public void run0() throws Throwable {
+        test();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Object_notify02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Object_notify02 {
+
+    static final Object object = new Object();
+
+    public static boolean test() {
+        synchronized (object) {
+            object.notify();
+        }
+        return true;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Object_notifyAll01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Object_notifyAll01 {
+
+    static final Object obj = new Object();
+
+    public static boolean test() {
+        obj.notifyAll();
+        return true;
+    }
+
+    @Test(expected = java.lang.IllegalMonitorStateException.class)
+    public void run0() throws Throwable {
+        test();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Object_notifyAll02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Object_notifyAll02 {
+
+    static final Object object = new Object();
+
+    public static boolean test() {
+        synchronized (object) {
+            object.notifyAll();
+        }
+        return true;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Object_toString01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+public class Object_toString01 {
+
+    static final String string = "Object_toString01";
+    static final Object object = new Object();
+
+    public static boolean test(int i) {
+        if (i == 0) {
+            return object.toString() != null;
+        }
+        if (i == 1) {
+            return new Object_toString01().toString() == string;
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return string;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Object_toString02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+/*
+ */
+package com.oracle.max.graal.jtt.lang;
+
+import org.junit.*;
+
+public class Object_toString02 {
+
+    static final Object obj = new Object_toString02();
+
+    public static String test(int i) {
+        Object object = null;
+        if (i == 0) {
+            object = obj;
+        } else if (i == 1) {
+            object = "string";
+        } else if (i == 2) {
+            object = "string".getClass();
+        }
+        return object.toString();
+    }
+
+    @Override
+    public String toString() {
+        return "XYZ";
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("XYZ", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("string", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("class java.lang.String", test(2));
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Object_wait01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Object_wait01 {
+
+    static final Object object = new Object();
+
+    public static boolean test() throws InterruptedException {
+        object.wait();
+        return true;
+    }
+
+    @Test(expected = java.lang.IllegalMonitorStateException.class)
+    public void run0() throws Throwable {
+        test();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Object_wait02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Object_wait02 {
+
+    static final Object object = new Object();
+
+    public static boolean test() throws InterruptedException {
+        synchronized (object) {
+            object.wait(1);
+        }
+        return true;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/Object_wait03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Object_wait03 {
+
+    static final Object object = new Object();
+
+    public static boolean test() throws InterruptedException {
+        synchronized (object) {
+            object.wait(1, 1);
+        }
+        return true;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/ProcessEnvironment_init.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ */
+package com.oracle.max.graal.jtt.lang;
+
+import java.util.*;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class ProcessEnvironment_init {
+
+    private static HashMap<Object, Object> theEnvironment;
+    public static Map<Object, Object> theUnmodifiableEnvironment;
+
+    public static int test(int v) {
+
+        byte[][] environ = environ();
+        theEnvironment = new HashMap<>(environ.length / 2 + 3);
+
+        for (int i = environ.length - 1; i > 0; i -= 2) {
+            theEnvironment.put(Variable.valueOf(environ[i - 1]), Value.valueOf(environ[i]));
+        }
+
+        theUnmodifiableEnvironment = Collections.unmodifiableMap(new StringEnvironment(theEnvironment));
+
+        return v;
+    }
+
+    @SuppressWarnings("serial")
+    private static final class StringEnvironment extends HashMap<Object, Object> {
+
+        @SuppressWarnings("unused")
+        public StringEnvironment(HashMap<Object, Object> theenvironment) {
+        }
+    }
+
+    private static final class Variable {
+
+        @SuppressWarnings("unused")
+        public static Object valueOf(byte[] bs) {
+            return new Object();
+        }
+    }
+
+    private static final class Value {
+
+        @SuppressWarnings("unused")
+        public static Object valueOf(byte[] bs) {
+            return new Object();
+        }
+    }
+
+    private static byte[][] environ() {
+        return new byte[3][3];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(7, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/StringCoding_Scale.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+public class StringCoding_Scale {
+
+    public static float maxCharPerByte = 1.0f;
+
+    public static int test(int i) {
+        return scale(i, maxCharPerByte);
+    }
+
+    // Copy of java.lang.StringCode.scale
+    private static int scale(int len, float expansionFactor) {
+        // We need to perform double, not float, arithmetic; otherwise
+        // we lose low order bits when len is larger than 2**24.
+        return (int) (len * (double) expansionFactor);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/String_intern01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class String_intern01 {
+
+    public static boolean test() {
+        // Checkstyle: stop
+        return "id".intern() == "id";
+        // Checkstyle: resume
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/String_intern02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class String_intern02 {
+
+    public static boolean test(int i) {
+        return ("id" + i).intern() == ("id" + i).intern();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/String_intern03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class String_intern03 {
+
+    public static boolean test(int i) {
+        return ("id" + i).intern().equals("id" + i);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/String_valueOf01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class String_valueOf01 {
+
+    public static String test(int i) {
+        Object result = null;
+        if (i == 1) {
+            result = "string";
+        }
+        return String.valueOf(result);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("null", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("string", test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/lang/System_identityHashCode01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.lang;
+
+import org.junit.*;
+
+/*
+ */
+public class System_identityHashCode01 {
+
+    private static final Object object0 = new Object();
+    private static final Object object1 = new Object();
+    private static final Object object2 = new Object();
+
+    private static final int hash0 = System.identityHashCode(object0);
+    private static final int hash1 = System.identityHashCode(object1);
+    private static final int hash2 = System.identityHashCode(object2);
+
+    public static boolean test(int i) {
+        if (i == 0) {
+            return hash0 == System.identityHashCode(object0);
+        }
+        if (i == 1) {
+            return hash1 == System.identityHashCode(object1);
+        }
+        if (i == 2) {
+            return hash2 == System.identityHashCode(object2);
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/loop/DegeneratedLoop.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ */
+public class DegeneratedLoop {
+
+    public static String test(int a) {
+        int arg = a;
+        for (;;) {
+            try {
+                arg++;
+                break;
+            } catch (Unresolved iioe) {
+            }
+        }
+        return "ok-" + arg;
+    }
+
+    @SuppressWarnings("serial")
+    public static class Unresolved extends RuntimeException {
+
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("ok-1", test(0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/loop/Loop01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ */
+public class Loop01 {
+
+    public static boolean test() {
+        int x = 1;
+
+        for (int i = 0; i < 10; i++) {
+            int y = m();
+            if (x == 1) {
+                return true;
+            }
+            x = y;
+        }
+        return false;
+    }
+
+    private static int m() {
+        return 2;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/loop/Loop02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ */
+public class Loop02 {
+
+    public static boolean test(int arg) {
+        int x = arg;
+
+        for (int i = 0; i < 10; i++) {
+            int y = m();
+            if (x == 1) {
+                return true;
+            }
+            x = y;
+        }
+        return false;
+    }
+
+    private static int m() {
+        return 2;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/loop/Loop03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ */
+public class Loop03 {
+
+    public static int test(int count) {
+        int i1 = 1;
+        int i2 = 2;
+        int i4 = 4;
+
+        for (int i = 0; i < count; i++) {
+            i1 = i2;
+            i2 = 7;
+            i4 = i1;
+        }
+        return i1 + i2 * 10 + i4 * 1000;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(7077, test(10));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/loop/Loop04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ */
+public class Loop04 {
+
+    public static int test(int count) {
+        int i1 = 1;
+        int i2 = 2;
+        int i3 = 3;
+        int i4 = 4;
+
+        for (int i = 0; i < count; i++) {
+            i1 = i2;
+            i2 = i3;
+            i3 = i4;
+            i4 = i1;
+        }
+        return i1 + i2 * 10 + i3 * 100 + i4 * 1000;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(4321, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2432, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2432, test(10));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/loop/Loop05.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ */
+public class Loop05 {
+
+    @SuppressWarnings("unused")
+    public static String test(int a) {
+        int arg = a;
+        int count = 0;
+        while (--arg > 0) {
+            count++;
+            new Object();
+        }
+        return "ok" + count;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("ok0", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("ok9", test(10));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("ok24", test(25));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/loop/Loop06.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ */
+public class Loop06 {
+
+    public static String test(int a) {
+        int arg = a;
+        int count = 0;
+        while (--arg > 0) {
+            count++;
+            foo();
+        }
+        return "ok" + count;
+    }
+
+    static void foo() {
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("ok0", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("ok9", test(10));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("ok24", test(25));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/loop/Loop07.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ */
+public class Loop07 {
+
+    public static String test(int arg) {
+        int count = arg;
+        for (int i = 0; i < arg; i++) {
+            count++;
+        }
+        return "ok" + count;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("ok0", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("ok20", test(10));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("ok50", test(25));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/loop/Loop08.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ */
+public class Loop08 {
+
+    public static int test(int arg) {
+        int a = 0;
+        for (int i = 0; i < arg; i++) {
+            a += i;
+        }
+        return a;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(45, test(10));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(300, test(25));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/loop/Loop09.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ */
+public class Loop09 {
+
+    private static int cnt;
+
+    public static String test(int arg) {
+        cnt = 0;
+        int count = arg;
+        for (int i = 0; i < arg; i++) {
+            count++;
+            foo();
+        }
+        return "ok" + count + "-" + cnt;
+    }
+
+    static void foo() {
+        cnt++;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("ok0-0", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("ok20-10", test(10));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("ok50-25", test(25));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/loop/Loop11.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ */
+public class Loop11 {
+
+    public static int test(int a) {
+        int arg = a;
+        int v = 0;
+        while (arg-- > 0) {
+            v = 1;
+        }
+        return v;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(1, test(5));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/loop/Loop12.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ */
+public class Loop12 {
+
+    private static int[] source = new int[]{10, 15, 20, 25, 30};
+
+    public static int test(int arg) {
+        int i = 0;
+        if (source[i] != arg) {
+            while (++i <= 5 && source[i] != arg) {
+                // nothing
+            }
+        }
+        return i;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(10));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(15));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(4, test(30));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/loop/Loop13.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ */
+public class Loop13 {
+
+    public static class Loop {
+
+        private int index;
+        private Object[] nodes = new Object[]{null, null, new Object(), null, null, new Object(), null};
+        private int size = nodes.length;
+
+        public Loop(int start) {
+            index = start;
+        }
+
+        public void test0() {
+            if (index < size) {
+                do {
+                    index++;
+                } while (index < size && nodes[index] == null);
+            }
+        }
+
+        public int getIndex() {
+            return index;
+        }
+
+    }
+
+    public static int test(int arg) {
+        Loop loop = new Loop(arg);
+        loop.test0();
+        return loop.getIndex();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(2, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(5, test(3));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(7, test(6));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(7, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/loop/Loop14.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ */
+public class Loop14 {
+
+    private static int value;
+
+    public static int test(int arg) {
+        return calc(arg);
+    }
+
+    public static int calc(int arg) {
+        int result = 0;
+        for (int k = 0; k < arg; ++k) {
+            value = 5;
+            for (int i = 0; i < arg; ++i) {
+                for (int j = 0; j < arg; ++j) {
+                }
+                result += value;
+            }
+        }
+        return result;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(5, test(1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(5, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/loop/LoopInline.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ * This test is meaningful only if you run it with 'forced' inlinning because running it in the harness with -Xcomp will not trigger any normal inlining
+ */
+public class LoopInline {
+
+    public static int test(int arg) {
+        int count = 0;
+        for (int i = 0; i < arg; i++) {
+            count += foo(i);
+            if (count > 15) {
+                count -= foo(3);
+                break;
+            }
+        }
+        return count;
+    }
+
+    public static int foo(int t) {
+        int sum = 0;
+        for (int i = 0; i < t; i++) {
+            sum += i;
+            if (i == 4) {
+                sum += foo2(sum);
+                break;
+            }
+        }
+        return sum;
+    }
+
+    public static int foo2(int i) {
+        int j = i;
+        int sum = 0;
+        while (j > 0) {
+            sum += j * j;
+            j--;
+        }
+        return sum;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(402, test(10));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/loop/LoopNewInstance.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ */
+public class LoopNewInstance {
+
+    public static Blop initBlop = new Blop();
+
+    @SuppressWarnings("unused")
+    public static int test(int arg) {
+        for (int i = 0; i < arg; i++) {
+            new Blop();
+        }
+        return count;
+    }
+
+    private static int count = 0;
+
+    private static class Blop {
+
+        private boolean exists;
+
+        public Blop() {
+            if (!exists) {
+                count++;
+            }
+            exists = true;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        count = 0;
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        count = 0;
+        Assert.assertEquals(5, test(5));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/loop/LoopPhi.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ */
+
+public class LoopPhi {
+
+    public static int test(int arg) {
+        for (int i = 0; i < arg; i++) {
+            test(1, 1, 1, 1, 1, 1);
+        }
+        return test(1, 1, 1, 1, 1, 1);
+    }
+
+    public static int test(int j1, int j2, int j3, int j4, int j5, int j6) {
+        int i1 = j1;
+        int i2 = j2;
+        int i3 = j3;
+        int i4 = j4;
+        int i5 = j5;
+        int i6 = j6;
+
+        if (i1 == 0) {
+            i1 = 2;
+        } else {
+            i2 = 2;
+        }
+        for (int i = 0; i < 10; i++) {
+            if (i == 0) {
+                i3 = 2;
+            } else {
+                i4 = 2;
+            }
+
+            for (int j = 0; j < 10; j++) {
+                if (j == 0) {
+                    i5 = 2;
+                } else {
+                    i6 = 2;
+                }
+            }
+        }
+
+        return i1 + i2 + i3 + i4 + i5 + i6;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11, test(50000));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/loop/LoopSwitch01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ */
+public class LoopSwitch01 {
+
+    static int count = 0;
+
+    @SuppressWarnings("unused")
+    public static String test() {
+        String line;
+        while ((line = string()) != null) {
+            switch (line.charAt(0)) {
+                case 'a':
+                    new Object();
+                    break;
+                case 'b':
+                    new Object();
+                    break;
+                default:
+                    new Object();
+                    break;
+            }
+        }
+        return "ok" + count;
+    }
+
+    private static String string() {
+        if (count == 0) {
+            return null;
+        }
+        count--;
+        return "" + ('a' + count);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("ok0", test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/ArrayCompare01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class ArrayCompare01 {
+
+    static final long[] a1 = {1, 2, 3, -5};
+    static final long[] a2 = {1, 2, 3, -5};
+    static final long[] a3 = {1, 2, 4, -5};
+
+    public static boolean test(int arg) {
+        if (arg == 0) {
+            return compare(a1, a2);
+        }
+        if (arg == 1) {
+            return compare(a1, a3);
+        }
+        return false;
+    }
+
+    static boolean compare(long[] a, long[] b) {
+        if (a.length == b.length) {
+            for (int i = 0; i < a.length; i++) {
+                if (a[i] != b[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/ArrayCompare02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class ArrayCompare02 {
+
+    static final long[] a1 = {1, 1, 1, 1, 1, 1};
+    static final long[] a2 = {1, 1, 1, 2, 1, 1};
+    static final long[] a3 = {1, 1, 2, 2, 3, 3};
+
+    public static boolean test(int arg) {
+        if (arg == 0) {
+            return compare(a1);
+        }
+        if (arg == 1) {
+            return compare(a2);
+        }
+        if (arg == 2) {
+            return compare(a3);
+        }
+        return false;
+    }
+
+    static boolean compare(long[] a) {
+        return a[0] == a[1] & a[2] == a[3] & a[4] == a[5];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/BC_invokevirtual2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_invokevirtual2 {
+
+    static Unresolved object;
+
+    public static class Unresolved {
+
+        public int id(int i) {
+            return i;
+        }
+    }
+
+    private static Unresolved object() {
+        if (object == null) {
+            object = new Unresolved();
+        }
+        return object;
+    }
+
+    public static int test(int a) {
+        return object().id(a);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(3, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-4, test(-4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/BigByteParams01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class BigByteParams01 {
+
+    public static int test(int num) {
+        int sum = 0;
+        if (num == 0) {
+            sum += testA((byte) 0, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+            sum += testA((byte) 1, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+            sum += testA((byte) 2, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+            sum += testA((byte) 3, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+            sum += testA((byte) 4, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+            sum += testA((byte) 5, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+            sum += testA((byte) 6, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+            sum += testA((byte) 7, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+            sum += testA((byte) 8, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+        } else if (num == 1) {
+            sum += testB(0, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+            sum += testB(1, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+            sum += testB(2, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+            sum += testB(3, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+            sum += testB(4, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+            sum += testB(5, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+            sum += testB(6, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+            sum += testB(7, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+            sum += testB(8, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+        } else if (num == 2) {
+            for (int i = 0; i < 9; i++) {
+                sum += testA(i, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+            }
+        } else if (num == 3) {
+            for (int i = 0; i < 9; i++) {
+                sum += testB(i, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9);
+            }
+        }
+        return sum;
+    }
+
+    private static int testA(int choice, byte p0, byte p1, byte p2, byte p3, byte p4, byte p5, byte p6, byte p7, byte p8) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+        }
+        return 42;
+    }
+
+    private static long testB(int choice, long p0, long p1, long p2, long p3, long p4, long p5, long p6, long p7, long p8) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(45, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(45, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(45, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(45, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/BigDoubleParams02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class BigDoubleParams02 {
+
+    public static double test(int choice, double p0, double p1, double p2, double p3, double p4, double p5, double p6, double p7, double p8) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1d, test(0, 1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2d, test(1, 1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(3d, test(2, 1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(4d, test(3, 1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d), 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(5d, test(4, 1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d), 0);
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(6d, test(5, 1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d), 0);
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(7d, test(6, 1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d), 0);
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(8d, test(7, 1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d), 0);
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(9d, test(8, 1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/BigFloatParams01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class BigFloatParams01 {
+
+    public static double test(int num) {
+        double sum = 0;
+        if (num == 0) {
+            sum += testA(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(1, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(2, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(3, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(4, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(5, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(6, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(7, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(8, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+        } else if (num == 1) {
+            sum += testB(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testB(1, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testB(2, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testB(3, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testB(4, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testB(5, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testB(6, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testB(7, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testB(8, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+        } else if (num == 2) {
+            for (int i = 0; i < 9; i++) {
+                sum += testA(i, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            }
+        } else if (num == 3) {
+            for (int i = 0; i < 9; i++) {
+                sum += testB(i, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            }
+        }
+        return sum;
+    }
+
+    private static float testA(int choice, float p0, float p1, float p2, float p3, float p4, float p5, float p6, float p7, float p8) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+        }
+        return 42;
+    }
+
+    private static double testB(int choice, double p0, double p1, double p2, double p3, double p4, double p5, double p6, double p7, double p8) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(45D, test(0), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(45D, test(1), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(45D, test(2), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(45D, test(3), 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0D, test(4), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/BigFloatParams02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class BigFloatParams02 {
+
+    public static float test(int choice, float p0, float p1, float p2, float p3, float p4, float p5, float p6, float p7, float p8) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1f, test(0, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f, 9f), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2f, test(1, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f, 9f), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(3f, test(2, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f, 9f), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(4f, test(3, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f, 9f), 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(5f, test(4, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f, 9f), 0);
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(6f, test(5, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f, 9f), 0);
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(7f, test(6, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f, 9f), 0);
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(8f, test(7, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f, 9f), 0);
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(9f, test(8, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f, 9f), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/BigIntParams01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class BigIntParams01 {
+
+    public static int test(int num) {
+        int sum = 0;
+        if (num == 0) {
+            sum += testA(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(1, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(2, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(3, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(4, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(5, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(6, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(7, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(8, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+        } else if (num == 1) {
+            sum += testB(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testB(1, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testB(2, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testB(3, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testB(4, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testB(5, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testB(6, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testB(7, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testB(8, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+        } else if (num == 2) {
+            for (int i = 0; i < 9; i++) {
+                sum += testA(i, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            }
+        } else if (num == 3) {
+            for (int i = 0; i < 9; i++) {
+                sum += testB(i, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            }
+        }
+        return sum;
+    }
+
+    private static int testA(int choice, int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+        }
+        return 42;
+    }
+
+    private static long testB(int choice, long p0, long p1, long p2, long p3, long p4, long p5, long p6, long p7, long p8) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(45, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(45, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(45, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(45, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/BigIntParams02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class BigIntParams02 {
+
+    public static int test(int choice, int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1, test(0, 1, 2, 3, 4, 5, 6, 7, -8, -9));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2, test(1, 1, 2, 3, 4, 5, 6, 7, -8, -9));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(3, test(2, 1, 2, 3, 4, 5, 6, 7, -8, -9));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(4, test(3, 1, 2, 3, 4, 5, 6, 7, -8, -9));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(5, test(4, 1, 2, 3, 4, 5, 6, 7, -8, -9));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(6, test(5, 1, 2, 3, 4, 5, 6, 7, -8, -9));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(7, test(6, 1, 2, 3, 4, 5, 6, 7, -8, -9));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(-8, test(7, 1, 2, 3, 4, 5, 6, 7, -8, -9));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(-9, test(8, 1, 2, 3, 4, 5, 6, 7, -8, -9));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/BigInterfaceParams01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class BigInterfaceParams01 {
+
+    public static String test(boolean b, String p0, String p1, String p2, String p3, String p4, String p5, String p6, String p7, String p8, String p9) {
+        I i = b ? new A() : new B();
+        return i.test(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
+    }
+
+    interface I {
+
+        String test(String p0, String p1, String p2, String p3, String p4, String p5, String p6, String p7, String p8, String p9);
+    }
+
+    static class A implements I {
+
+        public String test(String p0, String p1, String p2, String p3, String p4, String p5, String p6, String p7, String p8, String p9) {
+            return "A" + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9;
+        }
+    }
+
+    static class B implements I {
+
+        public String test(String p0, String p1, String p2, String p3, String p4, String p5, String p6, String p7, String p8, String p9) {
+            return "B" + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("A0123456789", test(true, "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("B0123456789", test(false, "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/BigLongParams02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class BigLongParams02 {
+
+    public static long test(int choice, long p0, long p1, long p2, long p3, long p4, long p5, long p6, long p7, long p8) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1L, test(0, 1L, 2L, 3L, 4L, 5L, 6L, 7L, -8L, -9L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2L, test(1, 1L, 2L, 3L, 4L, 5L, 6L, 7L, -8L, -9L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(3L, test(2, 1L, 2L, 3L, 4L, 5L, 6L, 7L, -8L, -9L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(4L, test(3, 1L, 2L, 3L, 4L, 5L, 6L, 7L, -8L, -9L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(5L, test(4, 1L, 2L, 3L, 4L, 5L, 6L, 7L, -8L, -9L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(6L, test(5, 1L, 2L, 3L, 4L, 5L, 6L, 7L, -8L, -9L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(7L, test(6, 1L, 2L, 3L, 4L, 5L, 6L, 7L, -8L, -9L));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(-8L, test(7, 1L, 2L, 3L, 4L, 5L, 6L, 7L, -8L, -9L));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(-9L, test(8, 1L, 2L, 3L, 4L, 5L, 6L, 7L, -8L, -9L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/BigMixedParams01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class BigMixedParams01 {
+
+    public static double test(int num) {
+        double sum = 0;
+        if (num == 0) {
+            sum += testA(0, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f);
+            sum += testA(1, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f);
+            sum += testA(2, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f);
+            sum += testA(3, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f);
+            sum += testA(4, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f);
+            sum += testA(5, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f);
+            sum += testA(6, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f);
+            sum += testA(7, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f);
+            sum += testA(8, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f);
+        } else if (num == 1) {
+            sum += testB(0, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d);
+            sum += testB(1, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d);
+            sum += testB(2, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d);
+            sum += testB(3, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d);
+            sum += testB(4, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d);
+            sum += testB(5, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d);
+            sum += testB(6, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d);
+            sum += testB(7, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d);
+            sum += testB(8, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d);
+        } else if (num == 2) {
+            for (int i = 0; i < 9; i++) {
+                sum += testA(i, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f);
+            }
+        } else if (num == 3) {
+            for (int i = 0; i < 9; i++) {
+                sum += testB(i, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d);
+            }
+        }
+        return sum;
+    }
+
+    @SuppressWarnings("unused")
+    private static float testA(int choice, int i0, int i1, int i2, int i3, float p0, float p1, float p2, float p3, int i4, int i5, float p4, float p5, float p6, float p7, float p8) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+        }
+        return 42;
+    }
+
+    @SuppressWarnings("unused")
+    private static double testB(int choice, int i0, int i1, int i2, double p0, double p1, double p2, double p3, int i3, int i4, double p4, double p5, double p6, double p7, double p8) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(45D, test(0), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(45D, test(1), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(45D, test(2), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(45D, test(3), 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0D, test(4), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/BigMixedParams02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class BigMixedParams02 {
+
+    @SuppressWarnings("unused")
+    public static float test(int choice, int i0, int i1, int i2, int i3, float p0, float p1, float p2, float p3, int i4, int i5, float p4, float p5, float p6, float p7, float p8) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1f, test(0, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2f, test(1, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(3f, test(2, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(4f, test(3, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f), 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(5f, test(4, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f), 0);
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(6f, test(5, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f), 0);
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(7f, test(6, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f), 0);
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(8f, test(7, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f), 0);
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(9f, test(8, -1, -1, -1, -1, 1f, 2f, 3f, 4f, -1, -1, 5f, 6f, 7f, 8f, 9f), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/BigMixedParams03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class BigMixedParams03 {
+
+    @SuppressWarnings("unused")
+    public static double test(int choice, int i0, int i1, int i2, int i3, double p0, double p1, double p2, double p3, int i4, int i5, double p4, double p5, double p6, double p7, double p8) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1d, test(0, -1, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2d, test(1, -1, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(3d, test(2, -1, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(4d, test(3, -1, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d), 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(5d, test(4, -1, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d), 0);
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(6d, test(5, -1, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d), 0);
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(7d, test(6, -1, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d), 0);
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(8d, test(7, -1, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d), 0);
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(9d, test(8, -1, -1, -1, -1, 1d, 2d, 3d, 4d, -1, -1, 5d, 6d, 7d, 8d, 9d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/BigObjectParams01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class BigObjectParams01 {
+
+    @SuppressWarnings("unused")
+    public static String test(String p0, String p1, String p2, String p3, String p4, String p5, String p6, String p7, String p8, String p9) {
+        return p0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("0", test("0", "1", "2", "3", "4", "5", "6", "7", "8", "9"));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("a", test("a", null, null, null, null, null, null, null, null, null));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/BigObjectParams02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class BigObjectParams02 {
+
+    public static String test(String p0, String p1, String p2, String p3, String p4, String p5, String p6, String p7, String p8, String p9) {
+        return p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("0123456789", test("0", "1", "2", "3", "4", "5", "6", "7", "8", "9"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/BigParamsAlignment.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+/*
+ */
+package com.oracle.max.graal.jtt.micro;
+
+import org.junit.*;
+
+public class BigParamsAlignment {
+
+    public static int test(int num) {
+        int sum = 0;
+        if (num == 0) {
+            sum += testA(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(1, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(2, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(3, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(4, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(5, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(6, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(7, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            sum += testA(8, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+        } else if (num == 1) {
+            sum += testB(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+            sum += testB(1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+            sum += testB(2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+            sum += testB(3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+            sum += testB(4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+            sum += testB(5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+            sum += testB(6, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+            sum += testB(7, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+            sum += testB(8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+            sum += testB(9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+        } else if (num == 2) {
+            for (int i = 0; i < 9; i++) {
+                sum += testA(i, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+            }
+        } else if (num == 3) {
+            for (int i = 0; i < 10; i++) {
+                sum += testB(i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+            }
+        } else if (num == 4) {
+            for (int i = 0; i < 11; i++) {
+                sum += testC(i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
+            }
+        } else if (num == 5) {
+            for (int i = 0; i < 12; i++) {
+                sum += testD(i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
+            }
+        }
+        return sum;
+    }
+
+    private static int testA(int choice, int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+        }
+        return 42;
+    }
+
+    private static int testB(int choice, int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+            case 9:
+                return p9;
+        }
+        return 42;
+    }
+
+    private static int testC(int choice, int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9, int p10) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+            case 9:
+                return p9;
+            case 10:
+                return p10;
+        }
+        return 42;
+    }
+
+    private static int testD(int choice, int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9, int p10, int p11) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+            case 9:
+                return p9;
+            case 10:
+                return p10;
+            case 11:
+                return p11;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(45, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(55, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(45, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(55, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(66, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(78, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(0, test(6));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/BigShortParams01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class BigShortParams01 {
+
+    public static int test(int num) {
+        int sum = 0;
+        if (num == 0) {
+            sum += testA((short) 0, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+            sum += testA((short) 1, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+            sum += testA((short) 2, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+            sum += testA((short) 3, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+            sum += testA((short) 4, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+            sum += testA((short) 5, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+            sum += testA((short) 6, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+            sum += testA((short) 7, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+            sum += testA((short) 8, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+        } else if (num == 1) {
+            sum += testB(0, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+            sum += testB(1, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+            sum += testB(2, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+            sum += testB(3, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+            sum += testB(4, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+            sum += testB(5, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+            sum += testB(6, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+            sum += testB(7, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+            sum += testB(8, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+        } else if (num == 2) {
+            for (int i = 0; i < 9; i++) {
+                sum += testA(i, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+            }
+        } else if (num == 3) {
+            for (int i = 0; i < 9; i++) {
+                sum += testB(i, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6, (short) 7, (short) 8, (short) 9);
+            }
+        }
+        return sum;
+    }
+
+    private static int testA(int choice, short p0, short p1, short p2, short p3, short p4, short p5, short p6, short p7, short p8) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+        }
+        return 42;
+    }
+
+    private static long testB(int choice, long p0, long p1, long p2, long p3, long p4, long p5, long p6, long p7, long p8) {
+        switch (choice) {
+            case 0:
+                return p0;
+            case 1:
+                return p1;
+            case 2:
+                return p2;
+            case 3:
+                return p3;
+            case 4:
+                return p4;
+            case 5:
+                return p5;
+            case 6:
+                return p6;
+            case 7:
+                return p7;
+            case 8:
+                return p8;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(45, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(45, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(45, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(45, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/BigVirtualParams01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class BigVirtualParams01 {
+
+    public static String test(boolean b, String p0, String p1, String p2, String p3, String p4, String p5, String p6, String p7, String p8, String p9) {
+        I i = b ? new A() : new B();
+        return i.test(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
+    }
+
+    abstract static class I {
+
+        abstract String test(String p0, String p1, String p2, String p3, String p4, String p5, String p6, String p7, String p8, String p9);
+    }
+
+    static class A extends I {
+
+        @Override
+        public String test(String p0, String p1, String p2, String p3, String p4, String p5, String p6, String p7, String p8, String p9) {
+            return "A" + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9;
+        }
+    }
+
+    static class B extends I {
+
+        @Override
+        public String test(String p0, String p1, String p2, String p3, String p4, String p5, String p6, String p7, String p8, String p9) {
+            return "B" + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("A0123456789", test(true, "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("B0123456789", test(false, "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/Bubblesort.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+public class Bubblesort {
+
+    public static int test(int num) {
+        final int[] array = {23, 8, -9, 5, 882, 0, 0, 1};
+
+        for (int i = 0; i < array.length; i++) {
+            for (int j = i + 1; j < array.length; j++) {
+                if (array[j] < array[i]) {
+                    final int tmp = array[i];
+                    array[i] = array[j];
+                    array[j] = tmp;
+                }
+            }
+        }
+        return array[num];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-9, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(5, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(8, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(23, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(882, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/Fibonacci.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class Fibonacci {
+
+    public static int test(int num) {
+        if (num <= 0) {
+            return 0;
+        }
+        int n1 = 0;
+        int n2 = 1;
+        for (int i = 1; i < num; i++) {
+            final int next = n2 + n1;
+            n1 = n2;
+            n2 = next;
+        }
+        return n2;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(1, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(2, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(3, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(5, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(8, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(13, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/InvokeVirtual_01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+public class InvokeVirtual_01 {
+
+    static class A {
+
+        int plus(int a) {
+            return a;
+        }
+    }
+
+    static class B extends A {
+
+        @Override
+        int plus(int a) {
+            return a + 10;
+        }
+    }
+
+    static class C extends A {
+
+        @Override
+        int plus(int a) {
+            return a + 20;
+        }
+    }
+
+    static A aObject = new A();
+    static A bObject = new B();
+    static A cObject = new C();
+
+    public static int test(int a) {
+        if (a == 0) {
+            return aObject.plus(a);
+        }
+        if (a == 1) {
+            return bObject.plus(a);
+        }
+        if (a == 2) {
+            return cObject.plus(a);
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(22, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(42, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/InvokeVirtual_02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+public class InvokeVirtual_02 {
+
+    static class A {
+
+        long plus(long a) {
+            return a;
+        }
+    }
+
+    static class B extends A {
+
+        @Override
+        long plus(long a) {
+            return a + 10;
+        }
+    }
+
+    static class C extends A {
+
+        @Override
+        long plus(long a) {
+            return a + 20;
+        }
+    }
+
+    static A objectA = new A();
+    static A objectB = new B();
+    static A objectC = new C();
+
+    public static long test(long a) {
+        if (a == 0) {
+            return objectA.plus(a);
+        }
+        if (a == 1) {
+            return objectB.plus(a);
+        }
+        if (a == 2) {
+            return objectC.plus(a);
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(0L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11L, test(1L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(22L, test(2L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(42L, test(3L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/Matrix01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class Matrix01 {
+
+    public static class Matrix {
+
+        final int id;
+
+        Matrix(int id) {
+            this.id = id;
+        }
+    }
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return matrix1(3) + matrix1(5);
+        }
+        if (arg == 1) {
+            return matrix2(3) + matrix2(5);
+        }
+        if (arg == 2) {
+            return matrix3(3) + matrix3(5);
+        }
+        if (arg == 3) {
+            return matrix4(3) + matrix4(5);
+        }
+        if (arg == 4) {
+            return matrix5(3) + matrix5(5);
+        }
+        return 42;
+    }
+
+    static int matrix1(int size) {
+        Matrix[] matrix = new Matrix[size];
+        fillMatrix(matrix, size);
+        int count = 0;
+        for (Matrix m : matrix) {
+            if (m != null) {
+                count++;
+            }
+        }
+        return count;
+    }
+
+    static int matrix2(int size) {
+        Matrix[][] matrix = new Matrix[size][size];
+        fillMatrix(matrix, size * size);
+        int count = 0;
+        for (Matrix[] n : matrix) {
+            for (Matrix m : n) {
+                if (m != null) {
+                    count++;
+                }
+            }
+        }
+        return count;
+    }
+
+    static int matrix3(int size) {
+        Matrix[][][] matrix = new Matrix[size][5][size];
+        fillMatrix(matrix, size * size * size);
+        int count = 0;
+        for (Matrix[][] o : matrix) {
+            for (Matrix[] n : o) {
+                for (Matrix m : n) {
+                    if (m != null) {
+                        count++;
+                    }
+                }
+            }
+        }
+        return count;
+    }
+
+    static int matrix4(int size) {
+        Matrix[][][][] matrix = new Matrix[size][2][size][3];
+        fillMatrix(matrix, size * size * size * size);
+        int count = 0;
+        for (Matrix[][][] p : matrix) {
+            for (Matrix[][] o : p) {
+                for (Matrix[] n : o) {
+                    for (Matrix m : n) {
+                        if (m != null) {
+                            count++;
+                        }
+                    }
+                }
+            }
+        }
+        return count;
+    }
+
+    static int matrix5(int size) {
+        Matrix[][][][][] matrix = new Matrix[size][size][3][4][size];
+        fillMatrix(matrix, size * size * size * size * size);
+        int count = 0;
+        for (Matrix[][][][] q : matrix) {
+            for (Matrix[][][] p : q) {
+                for (Matrix[][] o : p) {
+                    for (Matrix[] n : o) {
+                        for (Matrix m : n) {
+                            if (m != null) {
+                                count++;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return count;
+    }
+
+    static void fillMatrix(Object[] matrix, int total) {
+        for (int i = 0; i < 10000; i += 7) {
+            int number = i % total;
+            set(matrix, number);
+        }
+    }
+
+    static void set(Object[] matrix, int number) {
+        int val = number;
+        Object[] array = matrix;
+        while (!(array instanceof Matrix[])) {
+            int index = val % array.length;
+            val = val / array.length;
+            array = (Object[]) array[index];
+        }
+        ((Matrix[]) array)[val % array.length] = new Matrix(number);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(8, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(34, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(152, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(204, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(1547, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(42, test(5));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/ReferenceMap01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2010, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class ReferenceMap01 {
+
+    public static Integer val1 = new Integer(3);
+    public static Integer val2 = new Integer(4);
+
+    @SuppressWarnings("unused")
+    private static String foo(String[] a) {
+        String[] args = new String[]{"78"};
+        Integer i1 = new Integer(1);
+        Integer i2 = new Integer(2);
+        Integer i3 = val1;
+        Integer i4 = val2;
+        Integer i5 = new Integer(5);
+        Integer i6 = new Integer(6);
+        Integer i7 = new Integer(7);
+        Integer i8 = new Integer(8);
+        Integer i9 = new Integer(9);
+        Integer i10 = new Integer(10);
+        Integer i11 = new Integer(11);
+        Integer i12 = new Integer(12);
+
+        System.gc();
+        int sum = i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + i10 + i11 + i12;
+        return args[0] + sum;
+    }
+
+    public static int test() {
+        return Integer.valueOf(foo(new String[]{"asdf"}));
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(7878, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/StrangeFrames.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+@SuppressWarnings("unused")
+public class StrangeFrames {
+
+    public static boolean test(int arg) {
+        empty();
+        oneOperandStackSlot();
+        twoOperandStackSlots();
+        oneLocalSlot();
+        return true;
+    }
+
+    static void empty() {
+        // do nothing.
+    }
+
+    static void oneOperandStackSlot() {
+        new StrangeFrames();
+    }
+
+    static void twoOperandStackSlots() {
+        two(new StrangeFrames(), new StrangeFrames());
+    }
+
+    static void oneLocalSlot() {
+        int a;
+    }
+
+    static void two(Object a, Object b) {
+        Object c = b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/String_format01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class String_format01 {
+
+    public static String test(String s) {
+        return String.format("Hello %s", s);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("Hello World", test("World"));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("Hello New World Order", test("New World Order"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/String_format02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2008, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class String_format02 {
+
+    public static String test(int val) {
+        return String.format("Hello %d", val);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("Hello 0", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("Hello -11", test(-11));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("Hello -2147483648", test(-2147483648));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals("Hello 2147483647", test(2147483647));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/VarArgs_String01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class VarArgs_String01 {
+
+    public static String test(int arg) {
+        if (arg == 4) {
+            return get(0);
+        }
+        return get(arg, "a", null, "test");
+    }
+
+    private static String get(int index, String... args) {
+        return args[index];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("a", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(null, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("test", test(2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run4() throws Throwable {
+        test(4);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/VarArgs_boolean01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class VarArgs_boolean01 {
+
+    public static boolean test(int arg) {
+        if (arg == 4) {
+            return get(0);
+        }
+        return get(arg, true, false, true);
+    }
+
+    private static boolean get(int index, boolean... args) {
+        return args[index];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run4() throws Throwable {
+        test(4);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/VarArgs_byte01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class VarArgs_byte01 {
+
+    public static byte test(int arg) {
+        if (arg == 4) {
+            return get(0);
+        }
+        return get(arg, (byte) 1, (byte) 2, (byte) 3);
+    }
+
+    private static byte get(int index, byte... args) {
+        return args[index];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((byte) 1), test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((byte) 2), test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((byte) 3), test(2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run4() throws Throwable {
+        test(4);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/VarArgs_char01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class VarArgs_char01 {
+
+    public static char test(int arg) {
+        if (arg == 4) {
+            return get(0);
+        }
+        return get(arg, 'a', 'b', 'c');
+    }
+
+    private static char get(int index, char... args) {
+        return args[index];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((char) 97), test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((char) 98), test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((char) 99), test(2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run4() throws Throwable {
+        test(4);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/VarArgs_double01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class VarArgs_double01 {
+
+    public static double test(int arg) {
+        if (arg == 4) {
+            return get(0);
+        }
+        return get(arg, 0.0d, 1.0d, 2.0d);
+    }
+
+    private static double get(int index, double... args) {
+        return args[index];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.0d, test(0), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1.0d, test(1), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2.0d, test(2), 0);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run4() throws Throwable {
+        test(4);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/VarArgs_float01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class VarArgs_float01 {
+
+    public static float test(int arg) {
+        if (arg == 4) {
+            return get(0);
+        }
+        return get(arg, 0.0f, 1.0f, 2.0f);
+    }
+
+    private static float get(int index, float... args) {
+        return args[index];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0.0f, test(0), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1.0f, test(1), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2.0f, test(2), 0);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run4() throws Throwable {
+        test(4);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/VarArgs_int01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class VarArgs_int01 {
+
+    public static int test(int arg) {
+        if (arg == 4) {
+            return get(0);
+        }
+        return get(arg, 0, 1, 2);
+    }
+
+    private static int get(int index, int... args) {
+        return args[index];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run4() throws Throwable {
+        test(4);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/VarArgs_long01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class VarArgs_long01 {
+
+    public static long test(int arg) {
+        if (arg == 4) {
+            return get(0);
+        }
+        return get(arg, 0L, 1L, 2L);
+    }
+
+    private static long get(int index, long... args) {
+        return args[index];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1L, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2L, test(2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run4() throws Throwable {
+        test(4);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/micro/VarArgs_short01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.micro;
+
+import org.junit.*;
+
+/*
+ */
+public class VarArgs_short01 {
+
+    public static short test(int arg) {
+        if (arg == 4) {
+            return get(0);
+        }
+        return get(arg, (short) 0, (short) 1, (short) 2);
+    }
+
+    private static short get(int index, short... args) {
+        return args[index];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((short) 0), test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((short) 1), test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((short) 2), test(2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run4() throws Throwable {
+        test(4);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/ABCE_01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class ABCE_01 {
+
+    public static int[] array = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+
+    public static int test(int a) {
+        int arg = a;
+        for (int i = 0; i < array.length; i++) {
+            arg += array[i];
+        }
+        return arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(55, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(65, test(10));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/ABCE_02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class ABCE_02 {
+
+    public static int[] array = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+
+    public static int test(int arg) {
+        int r = 0;
+        for (int i = 0; i < arg; i++) {
+            r += array[i];
+        }
+        return r;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(55, test(10));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run2() throws Throwable {
+        test(20);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/ABCE_03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class ABCE_03 {
+
+    private static final int[] ARRAY1 = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+    private static final int[] ARRAY2 = new int[]{1};
+
+    public static int test(int arg) {
+        int[] array = arg == 0 ? ARRAY2 : ARRAY1;
+        int r = 0;
+        for (int i = 0; i < arg; i++) {
+            r += array[i];
+        }
+        return r;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(55, test(10));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run2() throws Throwable {
+        test(20);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/ArrayCopy01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests calls to the array copy method.
+ */
+public class ArrayCopy01 {
+
+    public static Object[] src = new Object[]{null, null};
+    public static Object[] dest = new Object[]{null, null};
+
+    public static int test(int srcPos, int destPos, int length) {
+        System.arraycopy(src, srcPos, dest, destPos, length);
+        return 0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0, 0, 0));
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(0, 0, -1);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run2() throws Throwable {
+        test(-1, 0, 0);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(0, -1, 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0, test(0, 0, 2));
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run5() throws Throwable {
+        test(0, 1, 2);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run6() throws Throwable {
+        test(1, 0, 2);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run7() throws Throwable {
+        test(1, 1, -1);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/ArrayLength01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of array length operations.
+ */
+public class ArrayLength01 {
+
+    public static final int SIZE = 8;
+    public static final byte[] arr = new byte[5];
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return arr.length;
+        }
+        if (arg == 1) {
+            return new byte[6].length;
+        }
+        if (arg == 2) {
+            return new Object[7].length;
+        }
+        if (arg == 3) {
+            return new Class[SIZE][].length;
+        }
+        if (arg == 4) {
+            return new int[arg].length;
+        }
+        return 0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(5, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(6, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(7, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(8, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(4, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/BC_idiv_16.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_idiv_16 {
+
+    public static int test(int i, int arg) {
+        if (i == 0) {
+            final int constant = 16;
+            return arg / constant;
+        }
+        return arg / 16;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0, 0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(0, 16));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(1, test(0, 17));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0, test(0, -1));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-1, test(0, -16));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(-1, test(0, -17));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(-64, test(0, -1024));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(0, test(1, 0));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(1, test(1, 16));
+    }
+
+    @Test
+    public void run9() throws Throwable {
+        Assert.assertEquals(1, test(1, 17));
+    }
+
+    @Test
+    public void run10() throws Throwable {
+        Assert.assertEquals(0, test(1, -1));
+    }
+
+    @Test
+    public void run11() throws Throwable {
+        Assert.assertEquals(-1, test(1, -16));
+    }
+
+    @Test
+    public void run12() throws Throwable {
+        Assert.assertEquals(-1, test(1, -17));
+    }
+
+    @Test
+    public void run13() throws Throwable {
+        Assert.assertEquals(-64, test(1, -1024));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/BC_idiv_4.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_idiv_4 {
+
+    public static int test(int arg) {
+        return arg / 4;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(4));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(1, test(5));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0, test(-1));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-1, test(-4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(-1, test(-5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(-64, test(-256));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/BC_imul_16.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_imul_16 {
+
+    public static int test(int i, int arg) {
+        if (i == 0) {
+            final int mult = 16;
+            return arg * mult;
+        }
+        return arg * 16;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0, 0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(256, test(0, 16));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(272, test(0, 17));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-16, test(0, -1));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-256, test(0, -16));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(-272, test(0, -17));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(-16, test(0, 2147483647));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(0, test(0, -2147483648));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(0, test(1, 0));
+    }
+
+    @Test
+    public void run9() throws Throwable {
+        Assert.assertEquals(256, test(1, 16));
+    }
+
+    @Test
+    public void run10() throws Throwable {
+        Assert.assertEquals(272, test(1, 17));
+    }
+
+    @Test
+    public void run11() throws Throwable {
+        Assert.assertEquals(-16, test(1, -1));
+    }
+
+    @Test
+    public void run12() throws Throwable {
+        Assert.assertEquals(-256, test(1, -16));
+    }
+
+    @Test
+    public void run13() throws Throwable {
+        Assert.assertEquals(-272, test(1, -17));
+    }
+
+    @Test
+    public void run14() throws Throwable {
+        Assert.assertEquals(-16, test(1, 2147483647));
+    }
+
+    @Test
+    public void run15() throws Throwable {
+        Assert.assertEquals(0, test(1, -2147483648));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/BC_imul_4.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_imul_4 {
+
+    public static int test(int arg) {
+        return arg * 4;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(16, test(4));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(20, test(5));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-4, test(-1));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-16, test(-4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(-20, test(-5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(-1024, test(-256));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/BC_ldiv_16.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ldiv_16 {
+
+    public static long test(long arg) {
+        return arg / 16;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(0L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1L, test(16L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(1L, test(17L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0L, test(-1L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-1L, test(-16L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(-1L, test(-17L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(-64L, test(-1024L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/BC_ldiv_4.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ldiv_4 {
+
+    public static long test(long arg) {
+        return arg / 4;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(0L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1L, test(4L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(1L, test(5L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0L, test(-1L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-1L, test(-4L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(-1L, test(-5L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(-64L, test(-256L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/BC_lmul_16.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lmul_16 {
+
+    public static long test(long arg) {
+        return arg * 16;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(0L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(256L, test(16L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(272L, test(17L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-16L, test(-1L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-256L, test(-16L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(-272L, test(-17L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(-16384L, test(-1024L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/BC_lmul_4.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lmul_4 {
+
+    public static long test(long arg) {
+        return arg * 4;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0L, test(0L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(16L, test(4L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(20L, test(5L));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-4L, test(-1L));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(-16L, test(-4L));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(-20L, test(-5L));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(-1024L, test(-256L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/BC_lshr_C16.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lshr_C16 {
+
+    public static long test(long a) {
+        return a >> 16;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1330945L, test(87224824140L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/BC_lshr_C24.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lshr_C24 {
+
+    public static long test(long a) {
+        return a >> 24;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(5199L, test(87224824140L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/BC_lshr_C32.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_lshr_C32 {
+
+    public static long test(long a) {
+        return a >> 32;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(20L, test(87224824140L));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/BlockSkip01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class BlockSkip01 {
+
+    public static boolean test(int arg) {
+        int x = 1;
+
+        if (arg > 2) {
+            x = 2;
+        } else {
+            x = 1;
+        }
+        return m(x) == 2;
+    }
+
+    private static int m(int x) {
+        return x + 1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Cmov01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class Cmov01 {
+
+    public static boolean test(int a, int b) {
+        boolean result = a < b || a == b;
+        return result;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(-1, -1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1, 10));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(1, 0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Cmov02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class Cmov02 {
+
+    public static int test(double a, double b, int v1, int v2) {
+        return a < b ? v1 : v2;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1, test(1.0, 1.1, 1, 2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2, test(1.0, -1.1, 1, 2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(1.0, java.lang.Double.NaN, 1, 2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Conditional01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.jtt.optimize;
+
+import java.util.*;
+
+import org.junit.*;
+
+/*
+ */
+@SuppressWarnings("unused")
+public class Conditional01 {
+
+    private static final int RAM_SIZE = 0x100;
+
+    public static int test(int arg) {
+        Conditional01 c = new Conditional01();
+        Random rnd = new Random();
+        for (int i = 0; i < arg; i++) {
+            CPC i2 = new CPC();
+            i2.r1 = new Register();
+            i2.r1.val = i;
+            i2.r1.num = i + RAM_SIZE - 20;
+            i2.r2 = new Register();
+            i2.r2.val = rnd.nextInt();
+            i2.r2.num = rnd.nextInt(RAM_SIZE);
+            try {
+                c.visit(i2);
+            } catch (RuntimeException re) {
+
+            }
+        }
+        return c.cyclesConsumed;
+    }
+
+    private static class Register {
+
+        int val;
+        int num;
+    }
+
+    private static class CPC {
+
+        public Register r1;
+        public Register r2;
+
+    }
+
+    private int nextPC;
+    private int pc;
+    private boolean aC;
+    private boolean aH;
+    private boolean aN;
+    private boolean aZ;
+    private boolean aV;
+    private boolean aS;
+    private int cyclesConsumed;
+    private int[] sram = new int[RAM_SIZE];
+
+    public void visit(CPC i) {
+        nextPC = pc + 2;
+        int tmp0 = getRegisterByte(i.r1);
+        int tmp1 = getRegisterByte(i.r2);
+        int tmp2 = bit(aC);
+        int tmp3 = tmp0 - tmp1 - tmp2;
+        boolean tmp4 = ((tmp0 & 128) != 0);
+        boolean tmp5 = ((tmp1 & 128) != 0);
+        boolean tmp6 = ((tmp3 & 128) != 0);
+        boolean tmp7 = ((tmp0 & 8) != 0);
+        boolean tmp8 = ((tmp1 & 8) != 0);
+        boolean tmp9 = ((tmp3 & 8) != 0);
+        aH = !tmp7 && tmp8 || tmp8 && tmp9 || tmp9 && !tmp7;
+        aC = !tmp4 && tmp5 || tmp5 && tmp6 || tmp6 && !tmp4;
+        aN = tmp6;
+        aZ = low(tmp3) == 0 && aZ;
+        aV = tmp4 && !tmp5 && !tmp6 || !tmp4 && tmp5 && tmp6;
+        aS = (aN != aV);
+        cyclesConsumed++;
+    }
+
+    public int getRegisterByte(Register r1) {
+        if ((r1.val % 10) == 0) {
+            return sram[r1.num];
+        }
+        return r1.val;
+    }
+
+    public int low(int tmp3) {
+        return tmp3 & 0x01;
+    }
+
+    public int bit(boolean c2) {
+        return c2 ? 1 : 0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(10, test(10));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(20, test(20));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(38, test(40));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/DeadCode01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class DeadCode01 {
+
+    public static int test(int a) {
+        int arg = a;
+        int p = arg;
+        if (p > 2) {
+            p += 1;
+            arg += 10;
+        } else {
+            p += 2;
+            arg += 20;
+            if (p > 3) {
+                p += 1;
+                arg += 10;
+                if (p > 4) {
+                    p += 1;
+                    arg += 10;
+                } else {
+                    p += 2;
+                    arg += 20;
+                }
+            } else {
+                p += 2;
+                arg += 20;
+            }
+        }
+        return p;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(4, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(5, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(6, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(4, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(5, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(7, test(6));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/DeadCode02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class DeadCode02 {
+
+    public static int test() {
+        int i = 0;
+        while (true) {
+            i++;
+            if (test2()) {
+                break;
+            }
+        }
+        return i;
+    }
+
+    public static boolean test2() {
+        return true;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Fold_Cast01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer operations.
+ */
+public class Fold_Cast01 {
+
+    static final Object object = new Fold_Cast01();
+
+    int field = 9;
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return ((Fold_Cast01) object).field;
+        }
+        if (arg == 1) {
+            Object obj = new Fold_Cast01();
+            return ((Fold_Cast01) obj).field;
+        }
+        if (arg == 2) {
+            return ((Fold_Cast01) null).field;
+        }
+        return 0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(9, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(9, test(1));
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run2() throws Throwable {
+        test(2);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Fold_Convert01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer operations.
+ */
+public class Fold_Convert01 {
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return i2b();
+        }
+        if (arg == 1) {
+            return i2s();
+        }
+        if (arg == 2) {
+            return i2c();
+        }
+        return 0;
+    }
+
+    public static int i2b() {
+        int x = 0x00000080;
+        return (byte) x;
+    }
+
+    public static int i2s() {
+        int x = 0x00008000;
+        return (short) x;
+    }
+
+    public static int i2c() {
+        int x = 0xffffffff;
+        return (char) x;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-128, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-32768, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(65535, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Fold_Convert02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer operations.
+ */
+public class Fold_Convert02 {
+    public static long test(long arg) {
+        if (arg == 0) {
+            return i2l();
+        }
+        if (arg == 1) {
+            return f2l();
+        }
+        if (arg == 2) {
+            return d2l();
+        }
+        return  0;
+    }
+    public static long i2l() {
+        int x = 0x80000000;
+        return x;
+    }
+    public static long f2l() {
+        float x = -33.1f;
+        return (long) x;
+    }
+    public static long d2l() {
+        double x = -78.1d;
+        return (long) x;
+    }
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(-2147483648L, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-33L, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-78L, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Fold_Convert03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of float conversions
+ */
+public class Fold_Convert03 {
+
+    public static float test(float arg) {
+        if (arg == 0) {
+            return i2f();
+        }
+        if (arg == 1) {
+            return l2f();
+        }
+        if (arg == 2) {
+            return d2f();
+        }
+        return 0;
+    }
+
+    public static float i2f() {
+        int x = 1024;
+        return x;
+    }
+
+    public static float l2f() {
+        long x = -33;
+        return x;
+    }
+
+    public static float d2f() {
+        double x = -78.1d;
+        return (float) x;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1024f, test(0), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-33f, test(1), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-78.1f, test(2), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Fold_Convert04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of float conversions
+ */
+public class Fold_Convert04 {
+
+    public static double test(double arg) {
+        if (arg == 0) {
+            return l2d();
+        }
+        if (arg == 1) {
+            return f2d();
+        }
+        return 0;
+    }
+
+    public static double l2d() {
+        long x = 1024;
+        return x;
+    }
+
+    public static double f2d() {
+        float x = -1.25f;
+        return x;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1024d, test(0), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1.25d, test(1), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Fold_Double01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of float operations.
+ */
+public class Fold_Double01 {
+
+    public static double test(double arg) {
+        if (arg == 0) {
+            return add();
+        }
+        if (arg == 1) {
+            return sub();
+        }
+        if (arg == 2) {
+            return mul();
+        }
+        if (arg == 3) {
+            return div();
+        }
+        if (arg == 4) {
+            return mod();
+        }
+        return 0;
+    }
+
+    public static double add() {
+        double x = 3;
+        return x + 7;
+    }
+
+    public static double sub() {
+        double x = 15;
+        return x - 4;
+    }
+
+    public static double mul() {
+        double x = 6;
+        return x * 2;
+    }
+
+    public static double div() {
+        double x = 26;
+        return x / 2;
+    }
+
+    public static double mod() {
+        double x = 29;
+        return x % 15;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10d, test(0d), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11d, test(1d), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(12d, test(2d), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(13d, test(3d), 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(14d, test(4d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Fold_Double02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer comparisons.
+ */
+public class Fold_Double02 {
+
+    public static boolean test(int arg) {
+        if (arg == 0) {
+            return equ();
+        }
+        if (arg == 1) {
+            return neq();
+        }
+        if (arg == 2) {
+            return geq();
+        }
+        if (arg == 3) {
+            return ge();
+        }
+        if (arg == 4) {
+            return ltq();
+        }
+        if (arg == 5) {
+            return lt();
+        }
+        return false;
+    }
+
+    static boolean equ() {
+        double x = 34;
+        return x == 34;
+    }
+
+    static boolean neq() {
+        double x = 34;
+        return x != 33;
+    }
+
+    static boolean geq() {
+        double x = 34;
+        return x >= 33;
+    }
+
+    static boolean ge() {
+        double x = 34;
+        return x > 35;
+    }
+
+    static boolean ltq() {
+        double x = 34;
+        return x <= 32;
+    }
+
+    static boolean lt() {
+        double x = 34;
+        return x < 31;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(5));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Fold_Double03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class Fold_Double03 {
+
+    private static final double MINUS_ZERO = 1 / Double.NEGATIVE_INFINITY;
+
+    public static double test(int t, double a) {
+        double v;
+        if (t == 0) {
+            v = a * 0.0;
+        } else {
+            v = a * MINUS_ZERO;
+        }
+        return 1 / v;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(java.lang.Double.POSITIVE_INFINITY, test(0, 5.0), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(java.lang.Double.NEGATIVE_INFINITY, test(1, 5.0), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(java.lang.Double.NEGATIVE_INFINITY, test(0, -5.0), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(java.lang.Double.POSITIVE_INFINITY, test(1, -5.0), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Fold_Float01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of float operations.
+ */
+public class Fold_Float01 {
+
+    public static float test(float arg) {
+        if (arg == 0) {
+            return add();
+        }
+        if (arg == 1) {
+            return sub();
+        }
+        if (arg == 2) {
+            return mul();
+        }
+        if (arg == 3) {
+            return div();
+        }
+        if (arg == 4) {
+            return mod();
+        }
+        return 0;
+    }
+
+    public static float add() {
+        float x = 3;
+        return x + 7;
+    }
+
+    public static float sub() {
+        float x = 15;
+        return x - 4;
+    }
+
+    public static float mul() {
+        float x = 6;
+        return x * 2;
+    }
+
+    public static float div() {
+        float x = 26;
+        return x / 2;
+    }
+
+    public static float mod() {
+        float x = 29;
+        return x % 15;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10f, test(0f), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11f, test(1f), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(12f, test(2f), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(13f, test(3f), 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(14f, test(4f), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Fold_Float02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer comparisons.
+ */
+public class Fold_Float02 {
+
+    public static boolean test(int arg) {
+        if (arg == 0) {
+            return equ();
+        }
+        if (arg == 1) {
+            return neq();
+        }
+        if (arg == 2) {
+            return geq();
+        }
+        if (arg == 3) {
+            return ge();
+        }
+        if (arg == 4) {
+            return ltq();
+        }
+        if (arg == 5) {
+            return lt();
+        }
+        return false;
+    }
+
+    static boolean equ() {
+        float x = 34;
+        return x == 34;
+    }
+
+    static boolean neq() {
+        float x = 34;
+        return x != 33;
+    }
+
+    static boolean geq() {
+        float x = 34;
+        return x >= 33;
+    }
+
+    static boolean ge() {
+        float x = 34;
+        return x > 35;
+    }
+
+    static boolean ltq() {
+        float x = 34;
+        return x <= 32;
+    }
+
+    static boolean lt() {
+        float x = 34;
+        return x < 31;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(5));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Fold_InstanceOf01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer operations.
+ */
+public class Fold_InstanceOf01 {
+
+    static final Object object = new Fold_InstanceOf01();
+
+    public static boolean test(int arg) {
+        if (arg == 0) {
+            return object instanceof Fold_InstanceOf01;
+        }
+        if (arg == 1) {
+            Object obj = new Fold_InstanceOf01();
+            return obj instanceof Fold_InstanceOf01;
+        }
+        if (arg == 2) {
+            return null instanceof Fold_InstanceOf01;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Fold_Int01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer operations.
+ */
+public class Fold_Int01 {
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return add();
+        }
+        if (arg == 1) {
+            return sub();
+        }
+        if (arg == 2) {
+            return mul();
+        }
+        if (arg == 3) {
+            return div();
+        }
+        if (arg == 4) {
+            return mod();
+        }
+        if (arg == 5) {
+            return and();
+        }
+        if (arg == 6) {
+            return or();
+        }
+        if (arg == 7) {
+            return xor();
+        }
+        return 0;
+    }
+
+    public static int add() {
+        int x = 3;
+        return x + 7;
+    }
+
+    public static int sub() {
+        int x = 15;
+        return x - 4;
+    }
+
+    public static int mul() {
+        int x = 6;
+        return x * 2;
+    }
+
+    public static int div() {
+        int x = 26;
+        return x / 2;
+    }
+
+    public static int mod() {
+        int x = 29;
+        return x % 15;
+    }
+
+    public static int and() {
+        int x = 31;
+        return x & 15;
+    }
+
+    public static int or() {
+        int x = 16;
+        return x | 16;
+    }
+
+    public static int xor() {
+        int x = 0;
+        return x ^ 17;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(12, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(13, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(14, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(15, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(16, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(17, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Fold_Int02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer comparisons.
+ */
+public class Fold_Int02 {
+
+    public static boolean test(int arg) {
+        if (arg == 0) {
+            return equ();
+        }
+        if (arg == 1) {
+            return neq();
+        }
+        if (arg == 2) {
+            return geq();
+        }
+        if (arg == 3) {
+            return ge();
+        }
+        if (arg == 4) {
+            return ltq();
+        }
+        if (arg == 5) {
+            return lt();
+        }
+        return false;
+    }
+
+    static boolean equ() {
+        int x = 34;
+        return x == 34;
+    }
+
+    static boolean neq() {
+        int x = 34;
+        return x != 33;
+    }
+
+    static boolean geq() {
+        int x = 34;
+        return x >= 33;
+    }
+
+    static boolean ge() {
+        int x = 34;
+        return x > 35;
+    }
+
+    static boolean ltq() {
+        int x = 34;
+        return x <= 32;
+    }
+
+    static boolean lt() {
+        int x = 34;
+        return x < 31;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(5));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Fold_Long01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer operations.
+ */
+public class Fold_Long01 {
+
+    public static long test(long arg) {
+        if (arg == 0) {
+            return add();
+        }
+        if (arg == 1) {
+            return sub();
+        }
+        if (arg == 2) {
+            return mul();
+        }
+        if (arg == 3) {
+            return div();
+        }
+        if (arg == 4) {
+            return mod();
+        }
+        if (arg == 5) {
+            return and();
+        }
+        if (arg == 6) {
+            return or();
+        }
+        if (arg == 7) {
+            return xor();
+        }
+        return 0;
+    }
+
+    public static long add() {
+        long x = 3;
+        return x + 7;
+    }
+
+    public static long sub() {
+        long x = 15;
+        return x - 4;
+    }
+
+    public static long mul() {
+        long x = 6;
+        return x * 2;
+    }
+
+    public static long div() {
+        long x = 26;
+        return x / 2;
+    }
+
+    public static long mod() {
+        long x = 29;
+        return x % 15;
+    }
+
+    public static long and() {
+        long x = 31;
+        return x & 15;
+    }
+
+    public static long or() {
+        long x = 16;
+        return x | 16;
+    }
+
+    public static long xor() {
+        long x = 0;
+        return x ^ 17;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10L, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11L, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(12L, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(13L, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(14L, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(15L, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(16L, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(17L, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Fold_Long02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer comparisons.
+ */
+public class Fold_Long02 {
+
+    public static boolean test(int arg) {
+        if (arg == 0) {
+            return equ();
+        }
+        if (arg == 1) {
+            return neq();
+        }
+        if (arg == 2) {
+            return geq();
+        }
+        if (arg == 3) {
+            return ge();
+        }
+        if (arg == 4) {
+            return ltq();
+        }
+        if (arg == 5) {
+            return lt();
+        }
+        return false;
+    }
+
+    static boolean equ() {
+        long x = 34;
+        return x == 34;
+    }
+
+    static boolean neq() {
+        long x = 34;
+        return x != 33;
+    }
+
+    static boolean geq() {
+        long x = 34;
+        return x >= 33;
+    }
+
+    static boolean ge() {
+        long x = 34;
+        return x > 35;
+    }
+
+    static boolean ltq() {
+        long x = 34;
+        return x <= 32;
+    }
+
+    static boolean lt() {
+        long x = 34;
+        return x < 31;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(false, test(5));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Fold_Math01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class Fold_Math01 {
+
+    public static double test(int arg) {
+        switch (arg) {
+            case 0:
+                return abs();
+            case 1:
+                return sin();
+            case 2:
+                return cos();
+            case 3:
+                return tan();
+            case 4:
+                return atan2();
+            case 5:
+                return sqrt();
+            case 6:
+                return log();
+            case 7:
+                return log10();
+            case 8:
+                return pow();
+            case 9:
+                return exp();
+            case 10:
+                return min();
+            case 11:
+                return max();
+        }
+        return 42;
+    }
+
+    private static double abs() {
+        return Math.abs(-10.0d);
+    }
+
+    private static double sin() {
+        return Math.sin(0.15d);
+    }
+
+    private static double cos() {
+        return Math.cos(0.15d);
+    }
+
+    private static double tan() {
+        return Math.tan(0.15d);
+    }
+
+    private static double atan2() {
+        return Math.atan2(0.15d, 3.1d);
+    }
+
+    private static double sqrt() {
+        return Math.sqrt(144d);
+    }
+
+    private static double log() {
+        return Math.log(3.15d);
+    }
+
+    private static double log10() {
+        return Math.log10(0.15d);
+    }
+
+    private static double pow() {
+        return Math.pow(2.15d, 6.1d);
+    }
+
+    private static double exp() {
+        return Math.log(3.15d);
+    }
+
+    private static int min() {
+        return Math.min(2, -1);
+    }
+
+    private static int max() {
+        return Math.max(2, -1);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10d, test(0), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0.14943813247359922d, test(1), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(0.9887710779360422d, test(2), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(0.15113521805829508d, test(3), 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0.04834938665190287d, test(4), 0);
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(12.0d, test(5), 0);
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(1.1474024528375417d, test(6), 0);
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(-0.8239087409443188d, test(7), 0);
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(106.62882057436371d, test(8), 0);
+    }
+
+    @Test
+    public void run9() throws Throwable {
+        Assert.assertEquals(1.1474024528375417d, test(9), 0);
+    }
+
+    @Test
+    public void run10() throws Throwable {
+        Assert.assertEquals(-1.0d, test(10), 0);
+    }
+
+    @Test
+    public void run11() throws Throwable {
+        Assert.assertEquals(2.0d, test(11), 0);
+    }
+
+    @Test
+    public void run12() throws Throwable {
+        Assert.assertEquals(42d, test(12), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Inline01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class Inline01 {
+
+    public static int test(int arg) {
+        return arg + nobranch(true) + nobranch(false) + nobranch(true) + nobranch(false);
+    }
+
+    static int nobranch(boolean f) {
+        if (f) {
+            return 0;
+        }
+        return 1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(2, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(3, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Inline02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class Inline02 {
+
+    public static int test(int arg) {
+        return arg + nobranch(true, arg) + nobranch(false, arg) + nobranch(true, arg) + nobranch(false, arg);
+    }
+
+    static int nobranch(boolean f, int v) {
+        if (f) {
+            return v;
+        }
+        return 1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(2, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(5, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(8, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/LLE_01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Test case for local load elimination. It makes sure that the second field store is not eliminated, because
+ * it is recognized that the first store changes the field "field1", so it is no longer guaranteed that it
+ * has its default value 0.
+ */
+public class LLE_01 {
+
+    int field1;
+
+    public static int test() {
+        LLE_01 o = new LLE_01();
+        o.field1 = 1;
+        o.field1 = 0;
+        return o.field1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/List_reorder_bug.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+@SuppressWarnings("unused")
+public class List_reorder_bug {
+
+    static class List {
+
+        List(int id) {
+            this.id = id;
+        }
+
+        List next;
+        int id;
+        boolean bool = true;
+    }
+
+    private static List list;
+
+    public static boolean test(int i) {
+        list = new List(5);
+        list.next = new List(6);
+        new List_reorder_bug().match(new Object(), 27, 6, 0);
+        return list.next == null;
+    }
+
+    private void match(Object a, int src, int id, int seq) {
+        print("match: " + src + ", " + id);
+        List item = list;
+        List itemPrev = null;
+        while (item != null) {
+            if (item.id == id) {
+                if (item.bool) {
+                    outcall(item.id);
+                }
+                if (itemPrev != null) {
+                    itemPrev.next = item.next;
+                } else {
+                    list = item.next;
+                }
+
+                item.next = null;
+                return;
+            }
+
+            itemPrev = item;
+            item = item.next;
+        }
+    }
+
+    static int globalId;
+
+    private static void outcall(int id) {
+        globalId = id;
+    }
+
+    String s;
+
+    private void print(String s2) {
+        this.s = s2;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/NCE_01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Test case for null check elimination.
+ */
+public class NCE_01 {
+
+    public static NCE_01 object = new NCE_01();
+
+    int field1 = 22;
+    int field2 = 23;
+
+    public static int test() {
+        NCE_01 o = object;
+        int i = o.field1;
+        // expected null check elimination here
+        return o.field2 + i;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(45, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/NCE_02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Test case for null check elimination.
+ */
+public class NCE_02 {
+
+    public static NCE_02 object = new NCE_02();
+
+    int field1;
+    int field2 = 23;
+
+    public static int test() {
+        NCE_02 o = object;
+        o.field1 = 11;
+        // expect non-null
+        o.field1 = 22;
+        // expect non-null
+        return o.field2;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(23, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/NCE_03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Test case for null check elimination.
+ */
+public class NCE_03 {
+
+    private static boolean cond = true;
+    public static NCE_03 object = new NCE_03();
+
+    int field1;
+    int field2 = 23;
+
+    public static int test() {
+        NCE_03 o = object;
+        o.field1 = 11;
+        if (cond) {
+            // expect non-null
+            o.field1 = 22;
+        }
+        // expect non-null
+        return o.field2;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(23, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/NCE_04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Test case for null check elimination.
+ */
+public class NCE_04 {
+
+    private static boolean cond = true;
+    public static NCE_04 object = new NCE_04();
+
+    int field1;
+    int field2 = 23;
+
+    public static int test() {
+        NCE_04 o = object;
+        if (cond) {
+            o.field1 = 22;
+        } else {
+            o.field1 = 11;
+        }
+        // expect non-null
+        return o.field2;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(23, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/NCE_FlowSensitive01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class NCE_FlowSensitive01 {
+
+    public static String test(String arg) {
+        if (arg != null) {
+            return arg.toString();
+        }
+        return null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(null, test(null));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("x", test("x"));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("yay", test("yay"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/NCE_FlowSensitive02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class NCE_FlowSensitive02 {
+
+    @SuppressWarnings("all")
+    public static String test(String arg) {
+        if (arg != null) {
+            return arg.toString();
+        }
+        return arg.toString();
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run0() throws Throwable {
+        test(null);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("x", test("x"));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("yay", test("yay"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/NCE_FlowSensitive03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class NCE_FlowSensitive03 {
+
+    public static String test(String arg) {
+        if ("x".equals(arg)) {
+            if (arg == null) {
+                return "null";
+            }
+        } else {
+            if (arg == null) {
+                return "null";
+            }
+        }
+        // arg cannot be null here
+        return arg.toString();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("null", test(null));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("x", test("x"));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("yay", test("yay"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/NCE_FlowSensitive04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class NCE_FlowSensitive04 {
+
+    public static String test(String arg2) {
+        String arg = arg2;
+        if (arg == null) {
+            arg = "null";
+        }
+        // arg cannot be null here
+        return arg.toString();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("null", test(null));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("x", test("x"));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("yay", test("yay"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/NCE_FlowSensitive05.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class NCE_FlowSensitive05 {
+
+    public static String test(Object arg) {
+
+        // An artificial loop to trigger iterative NCE.
+        while (arg != null) {
+            System.out.println(arg);
+        }
+
+        // The upcast must still include the null check.
+        return (String) arg;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(null, test(null));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Narrow_byte01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class Narrow_byte01 {
+
+    public static byte val;
+
+    public static byte test(byte b) {
+        val = b;
+        return val;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((byte) 0), test(((byte) 0)));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((byte) 1), test(((byte) 1)));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((byte) -1), test(((byte) -1)));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(((byte) 110), test(((byte) 110)));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Narrow_byte02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class Narrow_byte02 {
+
+    static class Byte {
+
+        byte foo;
+    }
+
+    static Byte val = new Byte();
+
+    public static byte test(byte b) {
+        val.foo = b;
+        return val.foo;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((byte) 0), test(((byte) 0)));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((byte) 1), test(((byte) 1)));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((byte) -1), test(((byte) -1)));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(((byte) 110), test(((byte) 110)));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Narrow_byte03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class Narrow_byte03 {
+
+    static byte[] val = new byte[4];
+
+    public static byte test(byte b) {
+        val[0] = b;
+        return val[0];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((byte) 0), test(((byte) 0)));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((byte) 1), test(((byte) 1)));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((byte) -1), test(((byte) -1)));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(((byte) 110), test(((byte) 110)));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Narrow_char01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class Narrow_char01 {
+
+    public static char val;
+
+    public static char test(char b) {
+        val = b;
+        return val;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((char) 0), test(((char) 0)));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((char) 1), test(((char) 1)));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((char) 255), test(((char) 255)));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(((char) 65000), test(((char) 65000)));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Narrow_char02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class Narrow_char02 {
+
+    static class Char {
+
+        char foo;
+    }
+
+    static Char val = new Char();
+
+    public static char test(char b) {
+        val.foo = b;
+        return val.foo;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((char) 0), test(((char) 0)));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((char) 1), test(((char) 1)));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((char) 255), test(((char) 255)));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(((char) 65000), test(((char) 65000)));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Narrow_char03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class Narrow_char03 {
+
+    static char[] val = new char[4];
+
+    public static char test(char b) {
+        val[0] = b;
+        return val[0];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((char) 0), test(((char) 0)));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((char) 1), test(((char) 1)));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((char) 255), test(((char) 255)));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(((char) 65000), test(((char) 65000)));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Narrow_short01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class Narrow_short01 {
+
+    public static short val;
+
+    public static short test(short b) {
+        val = b;
+        return val;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((short) 0), test(((short) 0)));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((short) 1), test(((short) 1)));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((short) -1), test(((short) -1)));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(((short) 23110), test(((short) 23110)));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Narrow_short02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class Narrow_short02 {
+
+    static class Short {
+
+        short foo;
+    }
+
+    static Short val = new Short();
+
+    public static short test(short b) {
+        val.foo = b;
+        return val.foo;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((short) 0), test(((short) 0)));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((short) 1), test(((short) 1)));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((short) -1), test(((short) -1)));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(((short) 23110), test(((short) 23110)));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Narrow_short03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class Narrow_short03 {
+
+    static short[] val = new short[4];
+
+    public static short test(short b) {
+        val[0] = b;
+        return val[0];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((short) 0), test(((short) 0)));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((short) 1), test(((short) 1)));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((short) -1), test(((short) -1)));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(((short) 23110), test(((short) 23110)));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Phi01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class Phi01 {
+
+    public static class Phi {
+
+        int f;
+
+        Phi(int f) {
+            this.f = f;
+        }
+    }
+
+    public static int test(int arg) {
+        return test2(new Phi(arg), arg);
+    }
+
+// @NEVER_INLINE
+    private static int test2(Phi p, int a) {
+        int arg = a;
+        if (arg > 2) {
+            p.f += 1;
+            arg += 1;
+        } else {
+            p.f += 2;
+            arg += 2;
+            if (arg > 3) {
+                p.f += 1;
+                arg += 1;
+                if (arg > 4) {
+                    p.f += 1;
+                    arg += 1;
+                } else {
+                    p.f += 2;
+                    arg += 2;
+                }
+            } else {
+                p.f += 2;
+                arg += 2;
+            }
+        }
+        return arg + p.f;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(8, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(10, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(12, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(8, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(10, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(14, test(6));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Phi02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class Phi02 {
+
+    public static class Phi {
+
+        int f;
+
+        Phi(int f) {
+            this.f = f;
+        }
+    }
+
+    public static int test(int arg) {
+        return test2(new Phi(arg), arg);
+    }
+
+// @NEVER_INLINE
+    private static int test2(Phi p, int a) {
+        int arg = a;
+        if (arg > 2) {
+            inc(p, 1);
+            arg += 1;
+        } else {
+            inc(p, 2);
+            arg += 2;
+            if (arg > 3) {
+                inc(p, 1);
+                arg += 1;
+                if (arg > 4) {
+                    inc(p, 1);
+                    arg += 1;
+                } else {
+                    inc(p, 2);
+                    arg += 2;
+                }
+            } else {
+                inc(p, 2);
+                arg += 2;
+            }
+        }
+        return arg + p.f;
+    }
+
+// @NEVER_INLINE
+    private static void inc(Phi p, int inc) {
+        p.f += inc;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(8, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(10, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(12, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(8, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(10, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(14, test(6));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Phi03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class Phi03 {
+
+    public static class Phi {
+
+        int f;
+
+        Phi(int f) {
+            this.f = f;
+        }
+    }
+
+    public static int test(int arg) {
+        return test2(new Phi(arg), arg);
+    }
+
+// @NEVER_INLINE
+    private static int test2(Phi p, int a) {
+        int arg = a;
+        if (arg > 2) {
+            inc(p, 1);
+            arg += 1;
+        } else {
+            inc(p, 2);
+            arg += 2;
+            if (arg > 3) {
+                inc(p, 1);
+                arg += 1;
+                if (arg > 4) {
+                    inc(p, 1);
+                    arg += 1;
+                } else {
+                    inc(p, 2);
+                    arg += 2;
+                }
+            } else {
+                inc(p, 2);
+                arg += 2;
+            }
+        }
+        return p.f;
+    }
+
+// @NEVER_INLINE
+    private static void inc(Phi p, int inc) {
+        p.f += inc;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(4, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(5, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(6, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(4, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(5, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(7, test(6));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Reduce_Convert01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests optimization integer conversions.
+ */
+public class Reduce_Convert01 {
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return i2b(arg + 10);
+        }
+        if (arg == 1) {
+            return i2s(arg + 10);
+        }
+        if (arg == 2) {
+            return i2c(arg + 10);
+        }
+        return 0;
+    }
+
+    public static int i2b(int arg) {
+        int x = (byte) arg;
+        return (byte) x;
+    }
+
+    public static int i2s(int arg) {
+        int x = (short) arg;
+        return (short) x;
+    }
+
+    public static int i2c(int arg) {
+        int x = (char) arg;
+        return (char) x;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(12, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Reduce_Double01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests optimization of double operations.
+ */
+public class Reduce_Double01 {
+
+    public static double test(double arg) {
+        if (arg == 0) {
+            return add(10);
+        }
+        if (arg == 1) {
+            return sub(11);
+        }
+        if (arg == 2) {
+            return mul(12);
+        }
+        if (arg == 3) {
+            return div(13);
+        }
+        return 0;
+    }
+
+    public static double add(double x) {
+        return x + 0;
+    }
+
+    public static double sub(double x) {
+        return x - 0;
+    }
+
+    public static double mul(double x) {
+        return x * 1;
+    }
+
+    public static double div(double x) {
+        return x / 1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10d, test(0d), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11d, test(1d), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(12d, test(2d), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(13d, test(3d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Reduce_Float01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests optimization of float operations.
+ */
+public class Reduce_Float01 {
+
+    public static float test(float arg) {
+        if (arg == 0) {
+            return add(10);
+        }
+        if (arg == 1) {
+            return sub(11);
+        }
+        if (arg == 2) {
+            return mul(12);
+        }
+        if (arg == 3) {
+            return div(13);
+        }
+        return 0;
+    }
+
+    public static float add(float x) {
+        return x + 0;
+    }
+
+    public static float sub(float x) {
+        return x - 0;
+    }
+
+    public static float mul(float x) {
+        return x * 1;
+    }
+
+    public static float div(float x) {
+        return x / 1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10f, test(0f), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11f, test(1f), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(12f, test(2f), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(13f, test(3f), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Reduce_Int01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer operations.
+ */
+public class Reduce_Int01 {
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return add(10);
+        }
+        if (arg == 1) {
+            return sub(11);
+        }
+        if (arg == 2) {
+            return mul(12);
+        }
+        if (arg == 3) {
+            return div(13);
+        }
+        if (arg == 4) {
+            return mod();
+        }
+        if (arg == 5) {
+            return and(15);
+        }
+        if (arg == 6) {
+            return or(16);
+        }
+        if (arg == 7) {
+            return xor(17);
+        }
+        return 0;
+    }
+
+    public static int add(int x) {
+        return x + 0;
+    }
+
+    public static int sub(int x) {
+        return x - 0;
+    }
+
+    public static int mul(int x) {
+        return x * 1;
+    }
+
+    public static int div(int x) {
+        return x / 1;
+    }
+
+    public static int mod() {
+        return 14;
+    }
+
+    public static int and(int x) {
+        return x & -1;
+    }
+
+    public static int or(int x) {
+        return x | 0;
+    }
+
+    public static int xor(int x) {
+        return x ^ 0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(12, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(13, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(14, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(15, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(16, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(17, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Reduce_Int02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer operations.
+ */
+public class Reduce_Int02 {
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return add(10);
+        }
+        if (arg == 1) {
+            return sub();
+        }
+        if (arg == 2) {
+            return mul(12);
+        }
+        if (arg == 3) {
+            return div();
+        }
+        if (arg == 4) {
+            return mod();
+        }
+        if (arg == 5) {
+            return and(15);
+        }
+        if (arg == 6) {
+            return or(16);
+        }
+        if (arg == 7) {
+            return xor(17);
+        }
+        return 0;
+    }
+
+    public static int add(int x) {
+        return 0 + x;
+    }
+
+    public static int sub() {
+        return 11;
+    }
+
+    public static int mul(int x) {
+        return 1 * x;
+    }
+
+    public static int div() {
+        return 13;
+    }
+
+    public static int mod() {
+        return 14;
+    }
+
+    public static int and(int x) {
+        return -1 & x;
+    }
+
+    public static int or(int x) {
+        return 0 | x;
+    }
+
+    public static int xor(int x) {
+        return 0 ^ x;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(12, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(13, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(14, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(15, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(16, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(17, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Reduce_Int03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer operations.
+ */
+public class Reduce_Int03 {
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return add(5);
+        }
+        if (arg == 1) {
+            return sub(10);
+        }
+        if (arg == 2) {
+            return mul(5);
+        }
+        if (arg == 3) {
+            return div(5);
+        }
+        if (arg == 4) {
+            return mod(5);
+        }
+        if (arg == 5) {
+            return and(15);
+        }
+        if (arg == 6) {
+            return or(16);
+        }
+        if (arg == 7) {
+            return xor(17);
+        }
+        return 0;
+    }
+
+    public static int add(int x) {
+        return x + x;
+    }
+
+    public static int sub(int x) {
+        return x - x;
+    }
+
+    public static int mul(int x) {
+        return x * x;
+    }
+
+    public static int div(int x) {
+        return x / x;
+    }
+
+    public static int mod(int x) {
+        return x % x;
+    }
+
+    public static int and(int x) {
+        return x & x;
+    }
+
+    public static int or(int x) {
+        return x | x;
+    }
+
+    public static int xor(int x) {
+        return x ^ x;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(25, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(15, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(16, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(0, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Reduce_Int04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer operations.
+ */
+public class Reduce_Int04 {
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return mul0(arg + 10);
+        }
+        if (arg == 1) {
+            return mul1(arg + 9);
+        }
+        return 0;
+    }
+
+    public static int mul0(int x) {
+        return x * 4;
+    }
+
+    public static int mul1(int x) {
+        return x * 65536;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(40, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(655360, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Reduce_IntShift01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests optimization of integer operations.
+ */
+public class Reduce_IntShift01 {
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return shift0(arg + 10);
+        }
+        if (arg == 1) {
+            return shift1(arg + 10);
+        }
+        if (arg == 2) {
+            return shift2(arg + 10);
+        }
+        if (arg == 3) {
+            return shift3(arg + 10);
+        }
+        if (arg == 4) {
+            return shift4(arg + 10);
+        }
+        if (arg == 5) {
+            return shift5(arg + 10);
+        }
+        return 0;
+    }
+
+    public static int shift0(int x) {
+        return x >> 0;
+    }
+
+    public static int shift1(int x) {
+        return x >>> 0;
+    }
+
+    public static int shift2(int x) {
+        return x << 0;
+    }
+
+    public static int shift3(int x) {
+        return x >> 64;
+    }
+
+    public static int shift4(int x) {
+        return x >>> 64;
+    }
+
+    public static int shift5(int x) {
+        return x << 64;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(12, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(13, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(14, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(15, test(5));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Reduce_IntShift02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests optimization of integer operations.
+ */
+public class Reduce_IntShift02 {
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return shift0(arg + 80);
+        }
+        if (arg == 1) {
+            return shift1(arg + 0x8000000a);
+        }
+        if (arg == 2) {
+            return shift2(arg + 192);
+        }
+        if (arg == 3) {
+            return shift3(arg + 208);
+        }
+        if (arg == 4) {
+            return shift4(arg);
+        }
+        if (arg == 5) {
+            return shift5(arg);
+        }
+        return 0;
+    }
+
+    public static int shift0(int x) {
+        return x >>> 3 << 3;
+    }
+
+    public static int shift1(int x) {
+        return x << 3 >>> 3;
+    }
+
+    public static int shift2(int x) {
+        return x >> 3 >> 1;
+    }
+
+    public static int shift3(int x) {
+        return x >>> 3 >>> 1;
+    }
+
+    public static int shift4(int x) {
+        return x << 3 << 1;
+    }
+
+    public static int shift5(int x) {
+        return x << 16 << 17;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(80, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(12, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(13, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(64, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(0, test(5));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Reduce_Long01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer operations.
+ */
+public class Reduce_Long01 {
+
+    public static long test(long arg) {
+        if (arg == 0) {
+            return add(10);
+        }
+        if (arg == 1) {
+            return sub(11);
+        }
+        if (arg == 2) {
+            return mul(12);
+        }
+        if (arg == 3) {
+            return div(13);
+        }
+        if (arg == 4) {
+            return mod();
+        }
+        if (arg == 5) {
+            return and(15);
+        }
+        if (arg == 6) {
+            return or(16);
+        }
+        if (arg == 7) {
+            return xor(17);
+        }
+        return 0;
+    }
+
+    public static long add(long x) {
+        return x + 0;
+    }
+
+    public static long sub(long x) {
+        return x - 0;
+    }
+
+    public static long mul(long x) {
+        return x * 1;
+    }
+
+    public static long div(long x) {
+        return x / 1;
+    }
+
+    public static long mod() {
+        return 14;
+    }
+
+    public static long and(long x) {
+        return x & -1;
+    }
+
+    public static long or(long x) {
+        return x | 0;
+    }
+
+    public static long xor(long x) {
+        return x ^ 0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10L, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11L, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(12L, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(13L, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(14L, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(15L, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(16L, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(17L, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Reduce_Long02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer operations.
+ */
+public class Reduce_Long02 {
+
+    public static long test(long arg) {
+        if (arg == 0) {
+            return add(10);
+        }
+        if (arg == 1) {
+            return sub();
+        }
+        if (arg == 2) {
+            return mul(12);
+        }
+        if (arg == 3) {
+            return div();
+        }
+        if (arg == 4) {
+            return mod();
+        }
+        if (arg == 5) {
+            return and(15);
+        }
+        if (arg == 6) {
+            return or(16);
+        }
+        if (arg == 7) {
+            return xor(17);
+        }
+        return 0;
+    }
+
+    public static long add(long x) {
+        return 0 + x;
+    }
+
+    public static long sub() {
+        return 11;
+    }
+
+    public static long mul(long x) {
+        return 1 * x;
+    }
+
+    public static long div() {
+        return 13;
+    }
+
+    public static long mod() {
+        return 14;
+    }
+
+    public static long and(long x) {
+        return -1 & x;
+    }
+
+    public static long or(long x) {
+        return 0 | x;
+    }
+
+    public static long xor(long x) {
+        return 0 ^ x;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10L, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11L, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(12L, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(13L, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(14L, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(15L, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(16L, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(17L, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Reduce_Long03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer operations.
+ */
+public class Reduce_Long03 {
+
+    public static long test(long arg) {
+        if (arg == 0) {
+            return add(5);
+        }
+        if (arg == 1) {
+            return sub(10);
+        }
+        if (arg == 2) {
+            return mul(5);
+        }
+        if (arg == 3) {
+            return div(5);
+        }
+        if (arg == 4) {
+            return mod(5);
+        }
+        if (arg == 5) {
+            return and(15);
+        }
+        if (arg == 6) {
+            return or(16);
+        }
+        if (arg == 7) {
+            return xor(17);
+        }
+        return 0;
+    }
+
+    public static long add(long x) {
+        return x + x;
+    }
+
+    public static long sub(long x) {
+        return x - x;
+    }
+
+    public static long mul(long x) {
+        return x * x;
+    }
+
+    public static long div(long x) {
+        return x / x;
+    }
+
+    public static long mod(long x) {
+        return x % x;
+    }
+
+    public static long and(long x) {
+        return x & x;
+    }
+
+    public static long or(long x) {
+        return x | x;
+    }
+
+    public static long xor(long x) {
+        return x ^ x;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10L, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0L, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(25L, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1L, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0L, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(15L, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(16L, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(0L, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Reduce_Long04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer operations.
+ */
+public class Reduce_Long04 {
+
+    public static long test(long arg) {
+        if (arg == 0) {
+            return mul0(arg + 10);
+        }
+        if (arg == 1) {
+            return mul1(arg + 9);
+        }
+        return 0;
+    }
+
+    public static long mul0(long x) {
+        return x * 4;
+    }
+
+    public static long mul1(long x) {
+        return x * 8589934592L;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(40L, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(85899345920L, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Reduce_LongShift01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests optimization of integer operations.
+ */
+public class Reduce_LongShift01 {
+
+    public static long test(long arg) {
+        if (arg == 0) {
+            return shift0(arg + 10);
+        }
+        if (arg == 1) {
+            return shift1(arg + 10);
+        }
+        if (arg == 2) {
+            return shift2(arg + 10);
+        }
+        if (arg == 3) {
+            return shift3(arg + 10);
+        }
+        if (arg == 4) {
+            return shift4(arg + 10);
+        }
+        if (arg == 5) {
+            return shift5(arg + 10);
+        }
+        return 0;
+    }
+
+    public static long shift0(long x) {
+        return x >> 0;
+    }
+
+    public static long shift1(long x) {
+        return x >>> 0;
+    }
+
+    public static long shift2(long x) {
+        return x << 0;
+    }
+
+    public static long shift3(long x) {
+        return x >> 64;
+    }
+
+    public static long shift4(long x) {
+        return x >>> 64;
+    }
+
+    public static long shift5(long x) {
+        return x << 64;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10L, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11L, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(12L, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(13L, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(14L, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(15L, test(5));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Reduce_LongShift02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests optimization of integer operations.
+ */
+public class Reduce_LongShift02 {
+
+    public static long test(long arg) {
+        if (arg == 0) {
+            return shift0(arg + 80);
+        }
+        if (arg == 1) {
+            return shift1(arg + 0x800000000000000aL);
+        }
+        if (arg == 2) {
+            return shift2(arg + 192);
+        }
+        if (arg == 3) {
+            return shift3(arg + 208);
+        }
+        if (arg == 4) {
+            return shift4(arg);
+        }
+        return 0;
+    }
+
+    public static long shift0(long x) {
+        return x >>> 3 << 3;
+    }
+
+    public static long shift1(long x) {
+        return x << 3 >>> 3;
+    }
+
+    public static long shift2(long x) {
+        return x >> 3 >> 1;
+    }
+
+    public static long shift3(long x) {
+        return x >>> 3 >>> 1;
+    }
+
+    public static long shift4(long x) {
+        return x << 3 << 1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(80L, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(11L, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(12L, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(13L, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(64L, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Switch01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests optimization of switches.
+ */
+public class Switch01 {
+
+    public static int test(int arg) {
+        switch (arg) {
+            default:
+                return 1;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1, test(0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/Switch02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests optimization of switches.
+ */
+public class Switch02 {
+
+    public static int test(int arg) {
+        switch (arg) {
+            case 1:
+                return 2;
+            default:
+                return 1;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(1, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(2, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/TypeCastElem.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ */
+public class TypeCastElem {
+
+    interface Int1 {
+
+        int do1();
+    }
+
+    interface Int2 {
+
+        int do2();
+    }
+
+    interface Int3 extends Int1 {
+
+        int do3();
+    }
+
+    public static class ClassA implements Int1 {
+
+        private int a;
+
+        public ClassA(int a) {
+            this.a = a;
+        }
+
+        public int do1() {
+            return a;
+        }
+    }
+
+    public static class ClassB extends ClassA implements Int2 {
+
+        int b;
+
+        public ClassB(int a, int b) {
+            super(a);
+            this.b = b;
+        }
+
+        public int do2() {
+            return b;
+        }
+    }
+
+    public static class ClassC implements Int3 {
+
+        private int a;
+        private int b;
+
+        public ClassC(int a, int b) {
+            this.a = a;
+            this.b = b;
+        }
+
+        public int do3() {
+            return b;
+        }
+
+        public int do1() {
+            return a;
+        }
+
+    }
+
+    public static int test1(Object o) {
+        if (o instanceof ClassB) {
+            ClassB b = (ClassB) o;
+            if (o instanceof Int1) {
+                return b.b - b.b + 1;
+            }
+            return 7;
+        }
+        return 3;
+    }
+
+    public static int test2(Object o) {
+        Object b = o;
+        if (o instanceof ClassB) {
+            ClassA a = (ClassA) o;
+            if (b instanceof Int1) {
+                return ((Int1) a).do1();
+            }
+            return 7;
+        }
+        return 3;
+    }
+
+    public static int test3(Object o) {
+        Object b = o;
+        boolean t = o instanceof Int3;
+        if (t) {
+            Int1 a = (Int1) b;
+            return a.do1();
+        }
+        return 3;
+    }
+
+    public static int test(int a, int b, int c) {
+        ClassA ca = new ClassA(a);
+        ClassB cb = new ClassB(a, b);
+        ClassC cc = new ClassC(c, c);
+        int sum1 = test1(ca) + test1(cb) * 10 + test1(cc) * 100;
+        int sum2 = test2(ca) + test2(cb) * 10 + test2(cc) * 100;
+        int sum3 = test3(ca) + test3(cb) * 10 + test3(cc) * 100;
+        int result = sum1 * 5 + sum2 * 7 + sum3 * 9;
+        return result;
+    }
+
+    public static void main(String[] args) {
+        System.out.println(test(10, 13, 25));
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(27183, test(10, 13, 25));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_Cast01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer operations.
+ */
+public class VN_Cast01 {
+
+    static final Object object = new VN_Cast01();
+
+    int field = 9;
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return test1();
+        }
+        if (arg == 1) {
+            return test2();
+        }
+        if (arg == 2) {
+            return test3();
+        }
+        return 0;
+    }
+
+    private static int test1() {
+        Object o = object;
+        VN_Cast01 a = (VN_Cast01) o;
+        VN_Cast01 b = (VN_Cast01) o;
+        return a.field + b.field;
+    }
+
+    private static int test2() {
+        Object obj = new VN_Cast01();
+        VN_Cast01 a = (VN_Cast01) obj;
+        VN_Cast01 b = (VN_Cast01) obj;
+        return a.field + b.field;
+    }
+
+    @SuppressWarnings("all")
+    private static int test3() {
+        Object o = null;
+        VN_Cast01 a = (VN_Cast01) o;
+        VN_Cast01 b = (VN_Cast01) o;
+        return a.field + b.field;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(18, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(18, test(1));
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run2() throws Throwable {
+        test(2);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_Cast02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer operations.
+ */
+public class VN_Cast02 {
+
+    private static boolean cond = true;
+    static final Object object = new VN_Cast02();
+
+    int field = 9;
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return test1();
+        }
+        if (arg == 1) {
+            return test2();
+        }
+        if (arg == 2) {
+            return test3();
+        }
+        return 0;
+    }
+
+    private static int test1() {
+        Object o = object;
+        VN_Cast02 a = (VN_Cast02) o;
+        if (cond) {
+            VN_Cast02 b = (VN_Cast02) o;
+            return a.field + b.field;
+        }
+        return 0;
+    }
+
+    private static int test2() {
+        Object obj = new VN_Cast02();
+        VN_Cast02 a = (VN_Cast02) obj;
+        if (cond) {
+            VN_Cast02 b = (VN_Cast02) obj;
+            return a.field + b.field;
+        }
+        return 0;
+    }
+
+    @SuppressWarnings("all")
+    private static int test3() {
+        Object o = null;
+        VN_Cast02 a = (VN_Cast02) o;
+        if (cond) {
+            VN_Cast02 b = (VN_Cast02) o;
+            return a.field + b.field;
+        }
+        return 0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(18, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(18, test(1));
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run2() throws Throwable {
+        test(2);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_Convert01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests optimization integer conversions.
+ */
+public class VN_Convert01 {
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return i2b(arg + 10);
+        }
+        if (arg == 1) {
+            return i2s(arg + 10);
+        }
+        if (arg == 2) {
+            return i2c(arg + 10);
+        }
+        return 0;
+    }
+
+    public static int i2b(int arg) {
+        int x = (byte) arg;
+        int y = (byte) arg;
+        return x + y;
+    }
+
+    public static int i2s(int arg) {
+        int x = (short) arg;
+        int y = (short) arg;
+        return x + y;
+    }
+
+    public static int i2c(int arg) {
+        int x = (char) arg;
+        int y = (char) arg;
+        return x + y;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(20, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(22, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(24, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_Convert02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests optimization integer conversions.
+ */
+public class VN_Convert02 {
+
+    private static boolean cond = true;
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return i2b(arg + 10);
+        }
+        if (arg == 1) {
+            return i2s(arg + 10);
+        }
+        if (arg == 2) {
+            return i2c(arg + 10);
+        }
+        return 0;
+    }
+
+    public static int i2b(int arg) {
+        int x = (byte) arg;
+        if (cond) {
+            int y = (byte) arg;
+            return x + y;
+        }
+        return 0;
+    }
+
+    public static int i2s(int arg) {
+        int x = (short) arg;
+        if (cond) {
+            int y = (short) arg;
+            return x + y;
+        }
+        return 0;
+    }
+
+    public static int i2c(int arg) {
+        int x = (char) arg;
+        if (cond) {
+            int y = (char) arg;
+            return x + y;
+        }
+        return 0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(20, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(22, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(24, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_Double01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests optimization of float operations.
+ */
+public class VN_Double01 {
+
+    public static double test(double arg) {
+        if (arg == 0) {
+            return add(arg + 10);
+        }
+        if (arg == 1) {
+            return sub(arg + 10);
+        }
+        if (arg == 2) {
+            return mul(arg + 10);
+        }
+        if (arg == 3) {
+            return div(arg + 10);
+        }
+        return 0;
+    }
+
+    public static double add(double x) {
+        double c = 1;
+        double t = x + c;
+        double u = x + c;
+        return t + u;
+    }
+
+    public static double sub(double x) {
+        double c = 1;
+        double t = x - c;
+        double u = x - c;
+        return t - u;
+    }
+
+    public static double mul(double x) {
+        double c = 1;
+        double t = x * c;
+        double u = x * c;
+        return t * u;
+    }
+
+    public static double div(double x) {
+        double c = 1;
+        double t = x / c;
+        double u = x / c;
+        return t / u;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(22d, test(0d), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0d, test(1d), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(144d, test(2d), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1d, test(3d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_Double02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests optimization of float operations.
+ */
+public class VN_Double02 {
+
+    private static boolean cond = true;
+
+    public static double test(double arg) {
+        if (arg == 0) {
+            return add(arg + 10);
+        }
+        if (arg == 1) {
+            return sub(arg + 10);
+        }
+        if (arg == 2) {
+            return mul(arg + 10);
+        }
+        if (arg == 3) {
+            return div(arg + 10);
+        }
+        return 0;
+    }
+
+    public static double add(double x) {
+        double c = 1.0d;
+        double t = x + c;
+        if (cond) {
+            double u = x + c;
+            return t + u;
+        }
+        return 1;
+    }
+
+    public static double sub(double x) {
+        double c = 1.0d;
+        double t = x - c;
+        if (cond) {
+            double u = x - c;
+            return t - u;
+        }
+        return 1;
+    }
+
+    public static double mul(double x) {
+        double c = 1.0d;
+        double t = x * c;
+        if (cond) {
+            double u = x * c;
+            return t * u;
+        }
+        return 1.0d;
+    }
+
+    public static double div(double x) {
+        double c = 1.0d;
+        double t = x / c;
+        if (cond) {
+            double u = x / c;
+            return t / u;
+        }
+        return 1.0d;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(22d, test(0d), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0d, test(1d), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(144d, test(2d), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1d, test(3d), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_Field01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer operations.
+ */
+public class VN_Field01 {
+
+    static final VN_Field01 object = new VN_Field01();
+
+    int field = 9;
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return test1();
+        }
+        if (arg == 1) {
+            return test2();
+        }
+        if (arg == 2) {
+            return test3();
+        }
+        return 0;
+    }
+
+    private static int test1() {
+        VN_Field01 a = object;
+        return a.field + a.field;
+    }
+
+    private static int test2() {
+        VN_Field01 a = object;
+        VN_Field01 b = object;
+        return a.field + b.field;
+    }
+
+    @SuppressWarnings("all")
+    private static int test3() {
+        VN_Field01 a = null;
+        VN_Field01 b = null;
+        return a.field + b.field;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(18, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(18, test(1));
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run2() throws Throwable {
+        test(2);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_Field02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests constant folding of integer operations.
+ */
+public class VN_Field02 {
+
+    private static boolean cond = true;
+    static final VN_Field02 object = new VN_Field02();
+
+    int field = 9;
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return test1();
+        }
+        if (arg == 1) {
+            return test2();
+        }
+        if (arg == 2) {
+            return test3();
+        }
+        return 0;
+    }
+
+    private static int test1() {
+        VN_Field02 a = object;
+        int c = a.field;
+        if (cond) {
+            return c + a.field;
+        }
+        return 0;
+    }
+
+    private static int test2() {
+        VN_Field02 a = object;
+        if (cond) {
+            VN_Field02 b = object;
+            return a.field + b.field;
+        }
+        return 0;
+    }
+
+    @SuppressWarnings("all")
+    private static int test3() {
+        VN_Field02 a = null;
+        if (cond) {
+            VN_Field02 b = null;
+            return a.field + b.field;
+        }
+        return 0;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(18, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(18, test(1));
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run2() throws Throwable {
+        test(2);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_Float01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests optimization of float operations.
+ */
+public class VN_Float01 {
+
+    public static float test(float arg) {
+        if (arg == 0) {
+            return add(arg + 10);
+        }
+        if (arg == 1) {
+            return sub(arg + 10);
+        }
+        if (arg == 2) {
+            return mul(arg + 10);
+        }
+        if (arg == 3) {
+            return div(arg + 10);
+        }
+        return 0;
+    }
+
+    public static float add(float x) {
+        float c = 1;
+        float t = x + c;
+        float u = x + c;
+        return t + u;
+    }
+
+    public static float sub(float x) {
+        float c = 1;
+        float t = x - c;
+        float u = x - c;
+        return t - u;
+    }
+
+    public static float mul(float x) {
+        float c = 1;
+        float t = x * c;
+        float u = x * c;
+        return t * u;
+    }
+
+    public static float div(float x) {
+        float c = 1;
+        float t = x / c;
+        float u = x / c;
+        return t / u;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(22f, test(0f), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0f, test(1f), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(144f, test(2f), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1f, test(3f), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_Float02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests optimization of float operations.
+ */
+public class VN_Float02 {
+
+    private static boolean cond = true;
+
+    public static float test(float arg) {
+        if (arg == 0) {
+            return add(arg + 10);
+        }
+        if (arg == 1) {
+            return sub(arg + 10);
+        }
+        if (arg == 2) {
+            return mul(arg + 10);
+        }
+        if (arg == 3) {
+            return div(arg + 10);
+        }
+        return 0;
+    }
+
+    public static float add(float x) {
+        float c = 1.0f;
+        float t = x + c;
+        if (cond) {
+            float u = x + c;
+            return t + u;
+        }
+        return 1.0f;
+    }
+
+    public static float sub(float x) {
+        float c = 1.0f;
+        float t = x - c;
+        if (cond) {
+            float u = x - c;
+            return t - u;
+        }
+        return 1.0f;
+    }
+
+    public static float mul(float x) {
+        float c = 1.0f;
+        float t = x * c;
+        if (cond) {
+            float u = x * c;
+            return t * u;
+        }
+        return 1.0f;
+    }
+
+    public static float div(float x) {
+        float c = 1.0f;
+        float t = x / c;
+        if (cond) {
+            float u = x / c;
+            return t / u;
+        }
+        return 1.0f;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(22f, test(0f), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0f, test(1f), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(144f, test(2f), 0);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1f, test(3f), 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_InstanceOf01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests value numbering of instanceof operations.
+ */
+public class VN_InstanceOf01 {
+
+    static final Object object = new VN_InstanceOf01();
+
+    public static boolean test(int arg) {
+        if (arg == 0) {
+            return foo1();
+        }
+        if (arg == 1) {
+            return foo2();
+        }
+        if (arg == 2) {
+            return foo3();
+        }
+        // do nothing
+        return false;
+    }
+
+    private static boolean foo1() {
+        boolean a = object instanceof VN_InstanceOf01;
+        boolean b = object instanceof VN_InstanceOf01;
+        return a | b;
+    }
+
+    private static boolean foo2() {
+        Object obj = new VN_InstanceOf01();
+        boolean a = obj instanceof VN_InstanceOf01;
+        boolean b = obj instanceof VN_InstanceOf01;
+        return a | b;
+    }
+
+    private static boolean foo3() {
+        boolean a = null instanceof VN_InstanceOf01;
+        boolean b = null instanceof VN_InstanceOf01;
+        return a | b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_InstanceOf02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests value numbering of instanceof operations.
+ */
+public class VN_InstanceOf02 {
+
+    private static boolean cond = true;
+
+    static final Object object = new VN_InstanceOf02();
+
+    public static boolean test(int arg) {
+        if (arg == 0) {
+            return foo1();
+        }
+        if (arg == 1) {
+            return foo2();
+        }
+        if (arg == 2) {
+            return foo3();
+        }
+        // do nothing
+        return false;
+    }
+
+    private static boolean foo1() {
+        boolean a = object instanceof VN_InstanceOf02;
+        if (cond) {
+            boolean b = object instanceof VN_InstanceOf02;
+            return a | b;
+        }
+        return false;
+    }
+
+    private static boolean foo2() {
+        Object obj = new VN_InstanceOf02();
+        boolean a = obj instanceof VN_InstanceOf02;
+        if (cond) {
+            boolean b = obj instanceof VN_InstanceOf02;
+            return a | b;
+        }
+        return false;
+    }
+
+    private static boolean foo3() {
+        boolean a = null instanceof VN_InstanceOf02;
+        if (cond) {
+            boolean b = null instanceof VN_InstanceOf02;
+            return a | b;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(false, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_InstanceOf03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests value numbering of instanceof operations.
+ */
+public class VN_InstanceOf03 {
+
+    private static boolean cond = true;
+
+    static final Object object = new VN_InstanceOf03();
+
+    public static boolean test() {
+        return foo();
+    }
+
+    private static boolean foo() {
+        Object obj = new VN_InstanceOf03();
+        boolean a = obj instanceof VN_InstanceOf03;
+        if (cond) {
+            boolean b = obj instanceof VN_InstanceOf03;
+            return a | b;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_Int01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests value numbering of integer operations.
+ */
+public class VN_Int01 {
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return add(arg);
+        }
+        if (arg == 1) {
+            return sub(arg);
+        }
+        if (arg == 2) {
+            return mul(arg);
+        }
+        if (arg == 3) {
+            return div(arg);
+        }
+        if (arg == 4) {
+            return mod(arg);
+        }
+        if (arg == 5) {
+            return and(arg);
+        }
+        if (arg == 6) {
+            return or(arg);
+        }
+        if (arg == 7) {
+            return xor(arg);
+        }
+        return 0;
+    }
+
+    public static int add(int x) {
+        int c = 3;
+        int t = x + c;
+        int u = x + c;
+        return t + u;
+    }
+
+    public static int sub(int x) {
+        int c = 3;
+        int t = x - c;
+        int u = x - c;
+        return t - u;
+    }
+
+    public static int mul(int x) {
+        int i = 3;
+        int t = x * i;
+        int u = x * i;
+        return t * u;
+    }
+
+    public static int div(int x) {
+        int i = 9;
+        int t = i / x;
+        int u = i / x;
+        return t / u;
+    }
+
+    public static int mod(int x) {
+        int i = 7;
+        int t = i % x;
+        int u = i % x;
+        return t % u;
+    }
+
+    public static int and(int x) {
+        int i = 7;
+        int t = i & x;
+        int u = i & x;
+        return t & u;
+    }
+
+    public static int or(int x) {
+        int i = 7;
+        int t = i | x;
+        int u = i | x;
+        return t | u;
+    }
+
+    public static int xor(int x) {
+        int i = 7;
+        int t = i ^ x;
+        int u = i ^ x;
+        return t ^ u;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(6, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(36, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(5, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(7, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(0, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_Int02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests optimization of integer operations.
+ */
+public class VN_Int02 {
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return shift0(arg + 10);
+        }
+        if (arg == 1) {
+            return shift1(arg + 10);
+        }
+        if (arg == 2) {
+            return shift2(arg + 10);
+        }
+        return 0;
+    }
+
+    public static int shift0(int x) {
+        int c = 1;
+        int t = x >> c;
+        int u = x >> c;
+        return t + u;
+    }
+
+    public static int shift1(int x) {
+        int c = 1;
+        int t = x >>> c;
+        int u = x >>> c;
+        return t + u;
+    }
+
+    public static int shift2(int x) {
+        int c = 1;
+        int t = x << c;
+        int u = x << c;
+        return t + u;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(10, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(48, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_Int03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests value numbering of integer operations.
+ */
+public class VN_Int03 {
+
+    private static boolean cond = true;
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return add(arg);
+        }
+        if (arg == 1) {
+            return sub(arg);
+        }
+        if (arg == 2) {
+            return mul(arg);
+        }
+        if (arg == 3) {
+            return div(arg);
+        }
+        if (arg == 4) {
+            return mod(arg);
+        }
+        if (arg == 5) {
+            return and(arg);
+        }
+        if (arg == 6) {
+            return or(arg);
+        }
+        if (arg == 7) {
+            return xor(arg);
+        }
+        return 0;
+    }
+
+    public static int add(int x) {
+        int c = 3;
+        int t = x + c;
+        if (cond) {
+            int u = x + c;
+            return t + u;
+        }
+        return 0;
+    }
+
+    public static int sub(int x) {
+        int c = 3;
+        int t = x - c;
+        if (cond) {
+            int u = x - c;
+            return t - u;
+        }
+        return 3;
+    }
+
+    public static int mul(int x) {
+        int i = 3;
+        int t = x * i;
+        if (cond) {
+            int u = x * i;
+            return t * u;
+        }
+        return 3;
+    }
+
+    public static int div(int x) {
+        int i = 9;
+        int t = i / x;
+        if (cond) {
+            int u = i / x;
+            return t / u;
+        }
+        return 9;
+    }
+
+    public static int mod(int x) {
+        int i = 7;
+        int t = i % x;
+        if (cond) {
+            int u = i % x;
+            return t % u;
+        }
+        return 7;
+    }
+
+    public static int and(int x) {
+        int i = 7;
+        int t = i & x;
+        if (cond) {
+            int u = i & x;
+            return t & u;
+        }
+        return 7;
+    }
+
+    public static int or(int x) {
+        int i = 7;
+        int t = i | x;
+        if (cond) {
+            int u = i | x;
+            return t | u;
+        }
+        return 7;
+    }
+
+    public static int xor(int x) {
+        int i = 7;
+        int t = i ^ x;
+        if (cond) {
+            int u = i ^ x;
+            return t ^ u;
+        }
+        return 7;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(6, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(36, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(5, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(7, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(0, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_Long01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests value numbering of long operations.
+ */
+public class VN_Long01 {
+
+    public static long test(int arg) {
+        if (arg == 0) {
+            return add(arg);
+        }
+        if (arg == 1) {
+            return sub(arg);
+        }
+        if (arg == 2) {
+            return mul(arg);
+        }
+        if (arg == 3) {
+            return div(arg);
+        }
+        if (arg == 4) {
+            return mod(arg);
+        }
+        if (arg == 5) {
+            return and(arg);
+        }
+        if (arg == 6) {
+            return or(arg);
+        }
+        if (arg == 7) {
+            return xor(arg);
+        }
+        return 0;
+    }
+
+    public static long add(long x) {
+        long t = x + 3;
+        long u = x + 3;
+        return t + u;
+    }
+
+    public static long sub(long x) {
+        long t = x - 3;
+        long u = x - 3;
+        return t - u;
+    }
+
+    public static long mul(long x) {
+        long t = x * 3;
+        long u = x * 3;
+        return t * u;
+    }
+
+    public static long div(long x) {
+        long t = 9 / x;
+        long u = 9 / x;
+        return t / u;
+    }
+
+    public static long mod(long x) {
+        long t = 7 % x;
+        long u = 7 % x;
+        return t % u;
+    }
+
+    public static long and(long x) {
+        long t = 7 & x;
+        long u = 7 & x;
+        return t & u;
+    }
+
+    public static long or(long x) {
+        long t = 7 | x;
+        long u = 7 | x;
+        return t | u;
+    }
+
+    public static long xor(long x) {
+        long t = 7 ^ x;
+        long u = 7 ^ x;
+        return t ^ u;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(6L, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0L, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(36L, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1L, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0L, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(5L, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(7L, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(0L, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_Long02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests optimization of integer operations.
+ */
+public class VN_Long02 {
+
+    public static long test(int arg) {
+        if (arg == 0) {
+            return shift0(arg + 10);
+        }
+        if (arg == 1) {
+            return shift1(arg + 10);
+        }
+        if (arg == 2) {
+            return shift2(arg + 10);
+        }
+        return 0;
+    }
+
+    public static long shift0(long x) {
+        long c = 1;
+        long t = x >> c;
+        long u = x >> c;
+        return t + u;
+    }
+
+    public static long shift1(long x) {
+        long c = 1;
+        long t = x >>> c;
+        long u = x >>> c;
+        return t + u;
+    }
+
+    public static long shift2(long x) {
+        long c = 1;
+        long t = x << c;
+        long u = x << c;
+        return t + u;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(10L, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(10L, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(48L, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_Long03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests value numbering of long operations.
+ */
+public class VN_Long03 {
+
+    private static boolean cond = true;
+
+    public static long test(int arg) {
+        if (arg == 0) {
+            return add(arg);
+        }
+        if (arg == 1) {
+            return sub(arg);
+        }
+        if (arg == 2) {
+            return mul(arg);
+        }
+        if (arg == 3) {
+            return div(arg);
+        }
+        if (arg == 4) {
+            return mod(arg);
+        }
+        if (arg == 5) {
+            return and(arg);
+        }
+        if (arg == 6) {
+            return or(arg);
+        }
+        if (arg == 7) {
+            return xor(arg);
+        }
+        return 0;
+    }
+
+    public static long add(long x) {
+        long t = x + 3;
+        if (cond) {
+            long u = x + 3;
+            return t + u;
+        }
+        return 3;
+    }
+
+    public static long sub(long x) {
+        long t = x - 3;
+        if (cond) {
+            long u = x - 3;
+            return t - u;
+        }
+        return 3;
+    }
+
+    public static long mul(long x) {
+        long t = x * 3;
+        if (cond) {
+            long u = x * 3;
+            return t * u;
+        }
+        return 3;
+    }
+
+    public static long div(long x) {
+        long t = 9 / x;
+        if (cond) {
+            long u = 9 / x;
+            return t / u;
+        }
+        return 9;
+    }
+
+    public static long mod(long x) {
+        long t = 7 % x;
+        if (cond) {
+            long u = 7 % x;
+            return t % u;
+        }
+        return 7;
+    }
+
+    public static long and(long x) {
+        long t = 7 & x;
+        if (cond) {
+            long u = 7 & x;
+            return t & u;
+        }
+        return 7;
+    }
+
+    public static long or(long x) {
+        long t = 7 | x;
+        if (cond) {
+            long u = 7 | x;
+            return t | u;
+        }
+        return 7;
+    }
+
+    public static long xor(long x) {
+        long t = 7 ^ x;
+        if (cond) {
+            long u = 7 ^ x;
+            return t ^ u;
+        }
+        return 7;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(6L, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(0L, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(36L, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(1L, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0L, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(5L, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(7L, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(0L, test(7));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/optimize/VN_Loop01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests value numbering of integer operations.
+ */
+public class VN_Loop01 {
+
+    private static boolean cond1 = true;
+    private static boolean cond2 = true;
+
+    public static int test(int arg) {
+        if (arg == 0) {
+            return test1(arg);
+        }
+        if (arg == 1) {
+            return test2(arg);
+        }
+        if (arg == 2) {
+            return test3(arg);
+        }
+        if (arg == 3) {
+            return test4(arg);
+        }
+        return 0;
+    }
+
+    public static int test1(int x) {
+        int c = 3;
+        int t = x + c;
+        while (cond1) {
+            if (cond2) {
+                int u = x + c; // GVN should recognize u == t
+                return t + u;
+            }
+        }
+        return 3; // GVN should recognize 3 == 3
+    }
+
+    public static int test2(int x) {
+        int c = 3;
+        while (cond1) {
+            int t = x + c;
+            if (cond2) {
+                int u = x + c; // GVN should recognize u == t
+                return t + u;
+            }
+        }
+        return 3;
+    }
+
+    public static int test3(int x) {
+        int c = 3;
+        int t = x + c;
+        while (cond1) {
+            if (cond2) {
+                int u = x + c; // GVN should recognize u == t
+                return t + u;
+            }
+            int u = x + c; // GVN should recognize u == t
+            return t + u;
+        }
+        return 3; // GVN should recognize 3 == 3
+    }
+
+    public static int test4(int x) {
+        int c = 3;
+        int t = x + c;
+        while (cond1) {
+            if (!cond2) {
+                int u = x + c;
+                return t + u;
+            }
+            int u = x + c;
+            return t + u;
+        }
+        return 3;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(6, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(8, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(10, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(12, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(0, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_get01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_get01 {
+
+    private static final String[] array = {"0", "1", "2"};
+
+    public static String test(int i) {
+        return (String) Array.get(array, i);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("0", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("1", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("2", test(2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_get02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_get02 {
+
+    private static final int[] array = {11, 21, 42};
+
+    public static int test(int i) {
+        return (Integer) Array.get(array, i);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(21, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(42, test(2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_get03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_get03 {
+
+    private static final byte[] array = {11, 21, 42};
+
+    public static byte test(int i) {
+        return (Byte) Array.get(array, i);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((byte) 11), test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((byte) 21), test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((byte) 42), test(2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_getBoolean01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_getBoolean01 {
+
+    private static final boolean[] array = {true, false, true};
+
+    public static boolean test(int i) {
+        return Array.getBoolean(array, i);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_getByte01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_getByte01 {
+
+    private static final byte[] array = {11, 21, 42};
+
+    public static byte test(int i) {
+        return Array.getByte(array, i);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((byte) 11), test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((byte) 21), test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((byte) 42), test(2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_getChar01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_getChar01 {
+
+    private static final char[] array = {11, 21, 42};
+
+    public static char test(int i) {
+        return Array.getChar(array, i);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((char) 11), test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((char) 21), test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((char) 42), test(2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_getDouble01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_getDouble01 {
+
+    private static final double[] array = {11.1d, 21.1d, 42.1d};
+
+    public static double test(int i) {
+        return Array.getDouble(array, i);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11.1d, test(0), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(21.1d, test(1), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(42.1d, test(2), 0);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_getFloat01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_getFloat01 {
+
+    private static final float[] array = {11.1f, 21.1f, 42.1f};
+
+    public static float test(int i) {
+        return Array.getFloat(array, i);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11.1f, test(0), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(21.1f, test(1), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(42.1f, test(2), 0);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_getInt01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_getInt01 {
+
+    private static final int[] array = {11, 21, 42};
+
+    public static int test(int i) {
+        return Array.getInt(array, i);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(21, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(42, test(2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_getLength01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_getLength01 {
+
+    private static final int[] array0 = {11, 21, 42};
+    private static final boolean[] array1 = {true, true, false, false};
+    private static final String[] array2 = {"String"};
+
+    public static int test(int i) {
+        Object array = null;
+        if (i == 0) {
+            array = array0;
+        } else if (i == 1) {
+            array = array1;
+        } else if (i == 2) {
+            array = array2;
+        }
+        return Array.getLength(array);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(4, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(1, test(2));
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_getLong01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_getLong01 {
+
+    private static final long[] array = {11, 21, 42};
+
+    public static long test(int i) {
+        return Array.getLong(array, i);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11L, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(21L, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(42L, test(2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_getShort01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_getShort01 {
+
+    private static final short[] array = {11, 21, 42};
+
+    public static short test(int i) {
+        return Array.getShort(array, i);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((short) 11), test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((short) 21), test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((short) 42), test(2));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_newInstance01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_newInstance01 {
+
+    public static boolean test(int i) {
+        return Array.newInstance(Array_newInstance01.class, i) != null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+    @Test(expected = java.lang.NegativeArraySizeException.class)
+    public void run3() throws Throwable {
+        test(-1);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_newInstance02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_newInstance02 {
+
+    public static boolean test(int i) {
+        Class< ? > javaClass;
+        if (i == 2) {
+            javaClass = void.class;
+        } else if (i == 3) {
+            javaClass = null;
+        } else {
+            javaClass = int.class;
+        }
+        return Array.newInstance(javaClass, 0) != null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test(expected = java.lang.IllegalArgumentException.class)
+    public void run1() throws Throwable {
+        test(2);
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run2() throws Throwable {
+        test(3);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_newInstance03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_newInstance03 {
+
+    public static boolean test(int i) {
+        Class< ? > javaClass;
+        if (i == 2) {
+            javaClass = int.class;
+        } else if (i == 3) {
+            javaClass = Object.class;
+        } else {
+            javaClass = Array_newInstance03.class;
+        }
+        return Array.newInstance(javaClass, 0).getClass().getComponentType() == javaClass;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_newInstance04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_newInstance04 {
+
+    public static boolean test(int i, int j) {
+        final int[] dims = {i, j};
+        return Array.newInstance(Array_newInstance04.class, dims) != null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(1, 0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(2, 2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(3, 2));
+    }
+
+    @Test(expected = java.lang.NegativeArraySizeException.class)
+    public void run3() throws Throwable {
+        test(0, -1);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_newInstance05.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_newInstance05 {
+
+    public static boolean test(int i, int j) {
+        final int[] dims = {i, j};
+        Class< ? > javaClass;
+        if (i == 2) {
+            javaClass = void.class;
+        } else if (i == 3) {
+            javaClass = null;
+        } else {
+            javaClass = int.class;
+        }
+        return Array.newInstance(javaClass, dims) != null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(1, 3));
+    }
+
+    @Test(expected = java.lang.IllegalArgumentException.class)
+    public void run1() throws Throwable {
+        test(2, 3);
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run2() throws Throwable {
+        test(3, 4);
+    }
+
+    @Test(expected = java.lang.NegativeArraySizeException.class)
+    public void run3() throws Throwable {
+        test(1, -1);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_newInstance06.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_newInstance06 {
+
+    public static boolean test(int i) {
+        final int[] dims = {i, 3};
+        Class< ? > javaClass;
+        if (i == 2) {
+            javaClass = int.class;
+        } else if (i == 3) {
+            javaClass = Object.class;
+        } else {
+            javaClass = Array_newInstance06.class;
+        }
+        return Array.newInstance(javaClass, dims).getClass().getComponentType().getComponentType() == javaClass;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_set01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_set01 {
+
+    private static final String[] array = {"x", "x", "x"};
+
+    public static String test(int i, String value) {
+        Array.set(array, i, value);
+        return array[i];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("1", test(0, "1"));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("2", test(1, "2"));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("XXd", test(0, "XXd"));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3, "--");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_set02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_set02 {
+
+    private static final int[] array = {-1, -1, -1};
+
+    public static int test(int i, int value) {
+        Array.set(array, i, value);
+        return array[i];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11, test(0, 11));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(21, test(1, 21));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(42, test(0, 42));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3, 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_set03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_set03 {
+
+    private static final byte[] array = {-1, -1, -1};
+
+    public static byte test(int i, byte value) {
+        Array.set(array, i, value);
+        return array[i];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((byte) 11), test(0, ((byte) 11)));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((byte) 21), test(1, ((byte) 21)));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((byte) 42), test(0, ((byte) 42)));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3, ((byte) 0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_setBoolean01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_setBoolean01 {
+
+    private static final boolean[] array = {false, false, false};
+
+    public static boolean test(int i, boolean value) {
+        Array.setBoolean(array, i, value);
+        return array[i];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0, true));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1, false));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2, true));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3, false);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_setByte01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_setByte01 {
+
+    private static final byte[] array = {-1, -1, -1};
+
+    public static byte test(int i, byte value) {
+        Array.setByte(array, i, value);
+        return array[i];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((byte) 11), test(0, ((byte) 11)));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((byte) 21), test(1, ((byte) 21)));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((byte) 42), test(0, ((byte) 42)));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3, ((byte) 0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_setChar01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_setChar01 {
+
+    private static final char[] array = {0, 0, 0};
+
+    public static char test(int i, char value) {
+        Array.setChar(array, i, value);
+        return array[i];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((char) 11), test(0, ((char) 11)));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((char) 21), test(1, ((char) 21)));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((char) 42), test(0, ((char) 42)));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3, ((char) 0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_setDouble01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_setDouble01 {
+
+    private static final double[] array = {-1, -1, -1};
+
+    public static double test(int i, double value) {
+        Array.setDouble(array, i, value);
+        return array[i];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11.1d, test(0, 11.1d), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(21.1d, test(1, 21.1d), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(42.1d, test(0, 42.1d), 0);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3, 0.1d);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_setFloat01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_setFloat01 {
+
+    private static final float[] array = {-1, -1, -1};
+
+    public static float test(int i, float value) {
+        Array.setFloat(array, i, value);
+        return array[i];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11.1f, test(0, 11.1f), 0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(21.1f, test(1, 21.1f), 0);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(42.1f, test(0, 42.1f), 0);
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3, 0.1f);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_setInt01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_setInt01 {
+
+    private static final int[] array = {-1, -1, -1};
+
+    public static int test(int i, int value) {
+        Array.setInt(array, i, value);
+        return array[i];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11, test(0, 11));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(21, test(1, 21));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(42, test(0, 42));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3, 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_setLong01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_setLong01 {
+
+    private static final long[] array = {-1, -1, -1};
+
+    public static long test(int i, long value) {
+        Array.setLong(array, i, value);
+        return array[i];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(11L, test(0, 11L));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(21L, test(1, 21L));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(42L, test(0, 42L));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3, 0L);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Array_setShort01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class Array_setShort01 {
+
+    private static final short[] array = {-1, -1, -1};
+
+    public static short test(int i, short value) {
+        Array.setShort(array, i, value);
+        return array[i];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(((short) 11), test(0, ((short) 11)));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(((short) 21), test(1, ((short) 21)));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(((short) 42), test(0, ((short) 42)));
+    }
+
+    @Test(expected = java.lang.ArrayIndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(3, ((short) 0));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Class_getDeclaredField01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+/*
+ */
+public class Class_getDeclaredField01 {
+
+    static String field;
+    static int f2;
+
+    public static String test(String input) throws NoSuchFieldException {
+        return Class_getDeclaredField01.class.getDeclaredField(input).getName();
+    }
+
+    public static void main(String[] args) {
+        field = args[0];
+    }
+
+    @Test(expected = java.lang.NoSuchFieldException.class)
+    public void run0() throws Throwable {
+        test("test");
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("field", test("field"));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("f2", test("f2"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Class_getDeclaredMethod01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+/*
+ */
+public class Class_getDeclaredMethod01 {
+
+    static String field;
+
+    public static String test(String input) throws NoSuchMethodException {
+        return Class_getDeclaredMethod01.class.getDeclaredMethod(input, String[].class).getName();
+    }
+
+    public static void main(String[] args) {
+        field = args[0];
+    }
+
+    @Test(expected = java.lang.NoSuchMethodException.class)
+    public void run0() throws Throwable {
+        test("test");
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("main", test("main"));
+    }
+
+    @Test(expected = java.lang.NoSuchMethodException.class)
+    public void run2() throws Throwable {
+        test("xx");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Class_getField01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+/*
+ */
+public class Class_getField01 {
+
+    public static String field;
+    public String field2;
+    String field3;
+
+    public static String test(String input) throws NoSuchFieldException {
+        return Class_getField01.class.getField(input).getName();
+    }
+
+    @Test(expected = java.lang.NoSuchFieldException.class)
+    public void run0() throws Throwable {
+        test("test");
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("field", test("field"));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("field2", test("field2"));
+    }
+
+    @Test(expected = java.lang.NoSuchFieldException.class)
+    public void run3() throws Throwable {
+        test("field3");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Class_getField02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+/*
+ */
+public class Class_getField02 {
+
+    public static String field;
+    public String field2;
+    String field3;
+
+    public static String test(String input) throws NoSuchFieldException {
+        return Class_getField02b.class.getField(input).getName();
+    }
+
+    static class Class_getField02b extends Class_getField02 {
+
+        public String field4;
+    }
+
+    @Test(expected = java.lang.NoSuchFieldException.class)
+    public void run0() throws Throwable {
+        test("test");
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("field", test("field"));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("field2", test("field2"));
+    }
+
+    @Test(expected = java.lang.NoSuchFieldException.class)
+    public void run3() throws Throwable {
+        test("field3");
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals("field4", test("field4"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Class_getMethod01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+/*
+ */
+public class Class_getMethod01 {
+
+    static String field;
+
+    public static String test(String input) throws NoSuchMethodException {
+        return Class_getMethod01.class.getMethod(input, String[].class).getName();
+    }
+
+    public static void main(String[] args) {
+        field = args[0];
+    }
+
+    @Test(expected = java.lang.NoSuchMethodException.class)
+    public void run0() throws Throwable {
+        test("test");
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("main", test("main"));
+    }
+
+    @Test(expected = java.lang.NoSuchMethodException.class)
+    public void run2() throws Throwable {
+        test("xx");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Class_getMethod02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+/*
+ */
+public class Class_getMethod02 {
+
+    static String field;
+
+    public static String test(int arg) throws NoSuchMethodException {
+        if (arg == 0) {
+            return Class_getMethod02.class.getMethod("test").getName();
+        } else if (arg == 1) {
+            return Class_getMethod02.class.getMethod("test", int.class).getName();
+        } else if (arg == 2) {
+            return Class_getMethod02.class.getMethod("main").getName();
+        } else if (arg == 3) {
+            return Class_getMethod02.class.getMethod("main", String[].class).getName();
+        } else if (arg == 4) {
+            return Class_getMethod02.class.getMethod("<init>").getName();
+        } else if (arg == 5) {
+            return Class_getMethod02.class.getMethod("<clinit>").getName();
+        }
+        return null;
+    }
+
+    public static void main(String[] args) {
+        field = args[0];
+    }
+
+    @Test(expected = java.lang.NoSuchMethodException.class)
+    public void run0() throws Throwable {
+        test(0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("test", test(1));
+    }
+
+    @Test(expected = java.lang.NoSuchMethodException.class)
+    public void run2() throws Throwable {
+        test(2);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals("main", test(3));
+    }
+
+    @Test(expected = java.lang.NoSuchMethodException.class)
+    public void run4() throws Throwable {
+        test(4);
+    }
+
+    @Test(expected = java.lang.NoSuchMethodException.class)
+    public void run5() throws Throwable {
+        test(5);
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(null, test(6));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Class_newInstance01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_newInstance01 {
+
+    public static boolean test(int i) throws IllegalAccessException, InstantiationException {
+        if (i == 0) {
+            return Class_newInstance01.class.newInstance() != null;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Class_newInstance02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_newInstance02 {
+
+    public static boolean test(int i) throws IllegalAccessException, InstantiationException {
+        if (i == 0) {
+            // note: we rely on the other class here.
+            return Class_newInstance07.Class_newInstance.class.newInstance() != null;
+        }
+        return false;
+    }
+
+    @Test(expected = java.lang.IllegalAccessException.class)
+    public void run0() throws Throwable {
+        test(0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Class_newInstance03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+public class Class_newInstance03 {
+
+    public abstract static class AbstractClass {
+    }
+
+    public static boolean test(int i) throws IllegalAccessException, InstantiationException {
+        if (i == 0) {
+            return AbstractClass.class.newInstance() != null;
+        } else if (i == 1) {
+            return Cloneable.class.newInstance() != null;
+        } else if (i == 2) {
+            return int[].class.newInstance() != null;
+        } else if (i == 3) {
+            return int.class.newInstance() != null;
+        }
+        return false;
+    }
+
+    @Test(expected = java.lang.InstantiationException.class)
+    public void run0() throws Throwable {
+        test(0);
+    }
+
+    @Test(expected = java.lang.InstantiationException.class)
+    public void run1() throws Throwable {
+        test(1);
+    }
+
+    @Test(expected = java.lang.InstantiationException.class)
+    public void run2() throws Throwable {
+        test(2);
+    }
+
+    @Test(expected = java.lang.InstantiationException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Class_newInstance06.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_newInstance06 {
+
+    public static final class Class_newInstance {
+
+        @SuppressWarnings("unused")
+        private Class_newInstance(int i) {
+            // do nothing. xx
+        }
+    }
+
+    public static boolean test(int i) throws IllegalAccessException, InstantiationException {
+        if (i == 0) {
+            return Class_newInstance.class.newInstance() != null;
+        }
+        return false;
+    }
+
+    @Test(expected = java.lang.InstantiationException.class)
+    public void run0() throws Throwable {
+        test(0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Class_newInstance07.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_newInstance07 {
+
+    public static final class Class_newInstance {
+
+        private Class_newInstance() throws Exception {
+            throw new Exception();
+        }
+    }
+
+    public static boolean test(int i) throws IllegalAccessException, InstantiationException {
+        if (i == 0) {
+            return Class_newInstance.class.newInstance() != null;
+        }
+        return false;
+    }
+
+    @Test(expected = java.lang.Exception.class)
+    public void run0() throws Throwable {
+        test(0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Field_get01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+/*
+ */
+public class Field_get01 {
+
+    public static final byte byteField = 11;
+    public static final short shortField = 12;
+    public static final char charField = 13;
+    public static final int intField = 14;
+    public static final long longField = 15;
+    public static final float floatField = 16;
+    public static final double doubleField = 17;
+    public static final boolean booleanField = true;
+
+    public static boolean test(int arg) throws NoSuchFieldException, IllegalAccessException {
+        if (arg == 0) {
+            return Field_get01.class.getField("byteField").get(null).equals(byteField);
+        } else if (arg == 1) {
+            return Field_get01.class.getField("shortField").get(null).equals(shortField);
+        } else if (arg == 2) {
+            return Field_get01.class.getField("charField").get(null).equals(charField);
+        } else if (arg == 3) {
+            return Field_get01.class.getField("intField").get(null).equals(intField);
+        } else if (arg == 4) {
+            return Field_get01.class.getField("longField").get(null).equals(longField);
+        } else if (arg == 5) {
+            return Field_get01.class.getField("floatField").get(null).equals(floatField);
+        } else if (arg == 6) {
+            return Field_get01.class.getField("doubleField").get(null).equals(doubleField);
+        } else if (arg == 7) {
+            return Field_get01.class.getField("booleanField").get(null).equals(booleanField);
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(true, test(7));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(false, test(8));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Field_get02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+/*
+ */
+public class Field_get02 {
+
+    private static final Field_get02 object = new Field_get02();
+
+    public final byte byteField = 11;
+    public final short shortField = 12;
+    public final char charField = 13;
+    public final int intField = 14;
+    public final long longField = 15;
+    public final float floatField = 16;
+    public final double doubleField = 17;
+    public final boolean booleanField = true;
+
+    public static boolean test(int arg) throws NoSuchFieldException, IllegalAccessException {
+        if (arg == 0) {
+            return Field_get02.class.getField("byteField").get(object).equals(object.byteField);
+        } else if (arg == 1) {
+            return Field_get02.class.getField("shortField").get(object).equals(object.shortField);
+        } else if (arg == 2) {
+            return Field_get02.class.getField("charField").get(object).equals(object.charField);
+        } else if (arg == 3) {
+            return Field_get02.class.getField("intField").get(object).equals(object.intField);
+        } else if (arg == 4) {
+            return Field_get02.class.getField("longField").get(object).equals(object.longField);
+        } else if (arg == 5) {
+            return Field_get02.class.getField("floatField").get(object).equals(object.floatField);
+        } else if (arg == 6) {
+            return Field_get02.class.getField("doubleField").get(object).equals(object.doubleField);
+        } else if (arg == 7) {
+            return Field_get02.class.getField("booleanField").get(object).equals(object.booleanField);
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(true, test(7));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(false, test(8));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Field_get03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+/*
+ */
+public class Field_get03 {
+
+    private static Field ByteField;
+    private static Field ShortField;
+    private static Field CharField;
+    private static Field IntField;
+    private static Field LongField;
+    private static Field FloatField;
+    private static Field DoubleField;
+    private static Field BooleanField;
+
+    static {
+        try {
+            ByteField = Field_get03.class.getField("byteField");
+            ShortField = Field_get03.class.getField("shortField");
+            CharField = Field_get03.class.getField("charField");
+            IntField = Field_get03.class.getField("intField");
+            LongField = Field_get03.class.getField("longField");
+            FloatField = Field_get03.class.getField("floatField");
+            DoubleField = Field_get03.class.getField("doubleField");
+            BooleanField = Field_get03.class.getField("booleanField");
+        } catch (SecurityException e) {
+            e.printStackTrace();
+        } catch (NoSuchFieldException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static final Field_get03 object = new Field_get03();
+
+    public final byte byteField = 11;
+    public final short shortField = 12;
+    public final char charField = 13;
+    public final int intField = 14;
+    public final long longField = 15;
+    public final float floatField = 16;
+    public final double doubleField = 17;
+    public final boolean booleanField = true;
+
+    public static boolean test(int arg) throws IllegalAccessException {
+        if (arg == 0) {
+            return ByteField.get(object).equals(object.byteField);
+        } else if (arg == 1) {
+            return ShortField.get(object).equals(object.shortField);
+        } else if (arg == 2) {
+            return CharField.get(object).equals(object.charField);
+        } else if (arg == 3) {
+            return IntField.get(object).equals(object.intField);
+        } else if (arg == 4) {
+            return LongField.get(object).equals(object.longField);
+        } else if (arg == 5) {
+            return FloatField.get(object).equals(object.floatField);
+        } else if (arg == 6) {
+            return DoubleField.get(object).equals(object.doubleField);
+        } else if (arg == 7) {
+            return BooleanField.get(object).equals(object.booleanField);
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(true, test(7));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(false, test(8));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Field_get04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+/*
+ */
+public class Field_get04 {
+
+    private static final Field_get04 object = new Field_get04();
+
+    public final byte byteField = 11;
+    public final short shortField = 12;
+    public final char charField = 13;
+    public final int intField = 14;
+    public final long longField = 15;
+    public final float floatField = 16;
+    public final double doubleField = 17;
+    public final boolean booleanField = true;
+
+    public static boolean test(int arg) throws NoSuchFieldException, IllegalAccessException {
+        if (arg == 0) {
+            return Field_get04.class.getField("byteField").getByte(object) == object.byteField;
+        } else if (arg == 1) {
+            return Field_get04.class.getField("shortField").getShort(object) == object.shortField;
+        } else if (arg == 2) {
+            return Field_get04.class.getField("charField").getChar(object) == object.charField;
+        } else if (arg == 3) {
+            return Field_get04.class.getField("intField").getInt(object) == object.intField;
+        } else if (arg == 4) {
+            return Field_get04.class.getField("longField").getLong(object) == object.longField;
+        } else if (arg == 5) {
+            return Field_get04.class.getField("floatField").getFloat(object) == object.floatField;
+        } else if (arg == 6) {
+            return Field_get04.class.getField("doubleField").getDouble(object) == object.doubleField;
+        } else if (arg == 7) {
+            return Field_get04.class.getField("booleanField").getBoolean(object) == object.booleanField;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(true, test(7));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(false, test(8));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Field_getType01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+/*
+ */
+public class Field_getType01 {
+
+    public static final byte byteField = 11;
+    public static final short shortField = 12;
+    public static final char charField = 13;
+    public static final int intField = 14;
+    public static final long longField = 15;
+    public static final float floatField = 16;
+    public static final double doubleField = 17;
+    public static final boolean booleanField = true;
+
+    public static boolean test(int arg) throws NoSuchFieldException {
+        if (arg == 0) {
+            return Field_getType01.class.getField("byteField").getType() == byte.class;
+        } else if (arg == 1) {
+            return Field_getType01.class.getField("shortField").getType() == short.class;
+        } else if (arg == 2) {
+            return Field_getType01.class.getField("charField").getType() == char.class;
+        } else if (arg == 3) {
+            return Field_getType01.class.getField("intField").getType() == int.class;
+        } else if (arg == 4) {
+            return Field_getType01.class.getField("longField").getType() == long.class;
+        } else if (arg == 5) {
+            return Field_getType01.class.getField("floatField").getType() == float.class;
+        } else if (arg == 6) {
+            return Field_getType01.class.getField("doubleField").getType() == double.class;
+        } else if (arg == 7) {
+            return Field_getType01.class.getField("booleanField").getType() == boolean.class;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(true, test(7));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(false, test(8));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Field_set01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+/*
+ */
+public class Field_set01 {
+
+    public static byte byteField;
+    public static short shortField;
+    public static char charField;
+    public static int intField;
+    public static long longField;
+    public static float floatField;
+    public static double doubleField;
+    public static boolean booleanField;
+
+    public static boolean test(int arg) throws NoSuchFieldException, IllegalAccessException {
+        if (arg == 0) {
+            Field_set01.class.getField("byteField").set(null, Byte.valueOf((byte) 11));
+            return byteField == 11;
+        } else if (arg == 1) {
+            Field_set01.class.getField("shortField").set(null, Short.valueOf((short) 12));
+            return shortField == 12;
+        } else if (arg == 2) {
+            Field_set01.class.getField("charField").set(null, Character.valueOf((char) 13));
+            return charField == 13;
+        } else if (arg == 3) {
+            Field_set01.class.getField("intField").set(null, Integer.valueOf(14));
+            return intField == 14;
+        } else if (arg == 4) {
+            Field_set01.class.getField("longField").set(null, Long.valueOf(15L));
+            return longField == 15;
+        } else if (arg == 5) {
+            Field_set01.class.getField("floatField").set(null, Float.valueOf(16));
+            return floatField == 16;
+        } else if (arg == 6) {
+            Field_set01.class.getField("doubleField").set(null, Double.valueOf(17));
+            return doubleField == 17;
+        } else if (arg == 7) {
+            Field_set01.class.getField("booleanField").set(null, true);
+            return booleanField == true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(true, test(7));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(false, test(8));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Field_set02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+/*
+ */
+public class Field_set02 {
+
+    private static final Field_set02 object = new Field_set02();
+
+    public byte byteField;
+    public short shortField;
+    public char charField;
+    public int intField;
+    public long longField;
+    public float floatField;
+    public double doubleField;
+    public boolean booleanField;
+
+    public static boolean test(int arg) throws NoSuchFieldException, IllegalAccessException {
+        if (arg == 0) {
+            Field_set02.class.getField("byteField").set(object, Byte.valueOf((byte) 11));
+            return object.byteField == 11;
+        } else if (arg == 1) {
+            Field_set02.class.getField("shortField").set(object, Short.valueOf((short) 12));
+            return object.shortField == 12;
+        } else if (arg == 2) {
+            Field_set02.class.getField("charField").set(object, Character.valueOf((char) 13));
+            return object.charField == 13;
+        } else if (arg == 3) {
+            Field_set02.class.getField("intField").set(object, Integer.valueOf(14));
+            return object.intField == 14;
+        } else if (arg == 4) {
+            Field_set02.class.getField("longField").set(object, Long.valueOf(15L));
+            return object.longField == 15;
+        } else if (arg == 5) {
+            Field_set02.class.getField("floatField").set(object, Float.valueOf(16));
+            return object.floatField == 16;
+        } else if (arg == 6) {
+            Field_set02.class.getField("doubleField").set(object, Double.valueOf(17));
+            return object.doubleField == 17;
+        } else if (arg == 7) {
+            Field_set02.class.getField("booleanField").set(object, true);
+            return object.booleanField == true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(true, test(7));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(false, test(8));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Field_set03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+/*
+ */
+public class Field_set03 {
+
+    private static final Field_set03 object = new Field_set03();
+
+    public byte byteField;
+    public short shortField;
+    public char charField;
+    public int intField;
+    public long longField;
+    public float floatField;
+    public double doubleField;
+    public boolean booleanField;
+
+    public static boolean test(int arg) throws NoSuchFieldException, IllegalAccessException {
+        if (arg == 0) {
+            Field_set03.class.getField("byteField").setByte(object, (byte) 11);
+            return object.byteField == 11;
+        } else if (arg == 1) {
+            Field_set03.class.getField("shortField").setShort(object, (short) 12);
+            return object.shortField == 12;
+        } else if (arg == 2) {
+            Field_set03.class.getField("charField").setChar(object, (char) 13);
+            return object.charField == 13;
+        } else if (arg == 3) {
+            Field_set03.class.getField("intField").setInt(object, 14);
+            return object.intField == 14;
+        } else if (arg == 4) {
+            Field_set03.class.getField("longField").setLong(object, 15L);
+            return object.longField == 15;
+        } else if (arg == 5) {
+            Field_set03.class.getField("floatField").setFloat(object, 16);
+            return object.floatField == 16;
+        } else if (arg == 6) {
+            Field_set03.class.getField("doubleField").setDouble(object, 17);
+            return object.doubleField == 17;
+        } else if (arg == 7) {
+            Field_set03.class.getField("booleanField").setBoolean(object, true);
+            return object.booleanField == true;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(5));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(true, test(6));
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        Assert.assertEquals(true, test(7));
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertEquals(false, test(8));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Invoke_except01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+/*
+ */
+public class Invoke_except01 {
+
+    public static int test(int arg) throws IllegalAccessException, InvocationTargetException {
+        Object[] args;
+        if (arg == 0) {
+            args = new Object[]{new int[0]};
+        } else if (arg == 1) {
+            args = new Object[]{new int[3]};
+        } else if (arg == 2) {
+            args = new Object[]{null};
+        } else if (arg == 3) {
+            args = new Object[]{new char[3]};
+        } else {
+            args = null;
+        }
+        for (Method m : Invoke_except01.class.getDeclaredMethods()) {
+            if ("method".equals(m.getName())) {
+                return (Integer) m.invoke(null, args);
+            }
+        }
+        return 42;
+    }
+
+    public static int method(int[] arg) {
+        return arg.length;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(3, test(1));
+    }
+
+    @Test(expected = java.lang.reflect.InvocationTargetException.class)
+    public void run2() throws Throwable {
+        test(2);
+    }
+
+    @Test(expected = java.lang.IllegalArgumentException.class)
+    public void run3() throws Throwable {
+        test(3);
+    }
+
+    @Test(expected = java.lang.IllegalArgumentException.class)
+    public void run4() throws Throwable {
+        test(4);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Invoke_main01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+/*
+ */
+public class Invoke_main01 {
+
+    static String field;
+
+    public static String test(String input) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+        field = null;
+        final String[] args = {input};
+        Invoke_main01.class.getMethod("main", String[].class).invoke(null, new Object[]{args});
+        return field;
+    }
+
+    public static void main(String[] args) {
+        field = args[0];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("test1", test("test1"));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("test2", test("test2"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Invoke_main02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+/*
+ */
+public class Invoke_main02 {
+
+    static String field;
+
+    public static String test(String input) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+        field = null;
+        final String[] args = {input};
+        Invoke_main02.class.getDeclaredMethod("main", String[].class).invoke(null, new Object[]{args});
+        return field;
+    }
+
+    public static void main(String[] args) {
+        field = args[0];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("test1", test("test1"));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("test2", test("test2"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Invoke_main03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+/*
+ */
+public class Invoke_main03 {
+
+    static String field;
+
+    public static String test(String input) throws IllegalAccessException, InvocationTargetException {
+        field = null;
+        final String[] args = {input};
+        for (Method m : Invoke_main03.class.getDeclaredMethods()) {
+            if ("main".equals(m.getName())) {
+                m.invoke(null, new Object[]{args});
+            }
+        }
+        return field;
+    }
+
+    public static void main(String[] args) {
+        field = args[0];
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("test1", test("test1"));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("test2", test("test2"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Invoke_virtual01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+/*
+ */
+public class Invoke_virtual01 {
+
+    static final HelperTest helper = new HelperTest(55);
+
+    public static int test(int input) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+        if (input == 1) {
+            final Method m = HelperTest.class.getDeclaredMethod("getInt");
+            Object o = m.invoke(helper);
+            return ((Integer) o).intValue();
+        }
+        return 0;
+    }
+
+    public static class HelperTest {
+
+        private int intField;
+
+        public int getInt() {
+            return intField;
+        }
+
+        public HelperTest(int i) {
+            intField = i;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(55, test(1));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Method_getParameterTypes01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+/*
+ */
+@SuppressWarnings("unused")
+public class Method_getParameterTypes01 {
+
+    public static int test(int arg) throws NoSuchMethodException {
+        if (arg == 0) {
+            return Method_getParameterTypes01.class.getMethod("method1").getParameterTypes().length;
+        } else if (arg == 1) {
+            return Method_getParameterTypes01.class.getMethod("method2", int.class).getParameterTypes().length;
+        } else if (arg == 2) {
+            return Method_getParameterTypes01.class.getMethod("method3", int.class, Object.class).getParameterTypes().length;
+        }
+        return -1;
+    }
+
+    public int method1() {
+        return 0;
+    }
+
+    public void method2(int arg1) {
+    }
+
+    public void method3(int arg1, Object arg2) {
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(1, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(2, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(-1, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Method_getReturnType01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+/*
+ */
+public class Method_getReturnType01 {
+
+    public static String test(int arg) throws NoSuchMethodException {
+        if (arg == 0) {
+            return Method_getReturnType01.class.getMethod("method1").getReturnType().getName();
+        } else if (arg == 1) {
+            return Method_getReturnType01.class.getMethod("method2").getReturnType().getName();
+        } else if (arg == 2) {
+            return Method_getReturnType01.class.getMethod("method3").getReturnType().getName();
+        }
+        return null;
+    }
+
+    public int method1() {
+        return 0;
+    }
+
+    public String method2() {
+        return null;
+    }
+
+    public void method3() {
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("int", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("java.lang.String", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("void", test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(null, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/reflect/Reflection_getCallerClass01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.reflect;
+
+import org.junit.*;
+
+import sun.reflect.*;
+
+/*
+ */
+@SuppressWarnings("static-method")
+public final class Reflection_getCallerClass01 {
+
+    public static final class Caller1 {
+
+        private Caller1() {
+        }
+
+        static String caller1(int depth) {
+            return Reflection.getCallerClass(depth).getName();
+        }
+    }
+
+    public static final class Caller2 {
+
+        private Caller2() {
+        }
+
+        static String caller2(int depth) {
+            return Caller1.caller1(depth);
+        }
+    }
+
+    public static String test(int depth) {
+        return Caller2.caller2(depth);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals("sun.reflect.Reflection", test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals("com.oracle.max.graal.jtt.reflect.Reflection_getCallerClass01$Caller1", test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals("com.oracle.max.graal.jtt.reflect.Reflection_getCallerClass01$Caller2", test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Monitor_contended01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Monitor_contended01 implements Runnable {
+
+    static final Object cond = new Object();
+    static final Object obj = new Object();
+
+    boolean started = false;
+    boolean acquired = false;
+
+    public static boolean test() throws InterruptedException {
+        // test contention for monitor
+        final Monitor_contended01 object = new Monitor_contended01();
+        synchronized (obj) {
+            new Thread(object).start();
+            // wait for other thread to startup and contend
+            synchronized (cond) {
+                cond.wait(1000);
+                if (!object.started) {
+                    return false;
+                }
+            }
+        }
+        // wait for other thread to acquire monitor and then exit
+        synchronized (cond) {
+            cond.wait(1000);
+        }
+        return object.acquired;
+    }
+
+    public void run() {
+        // signal that we have started up so first thread will release lock
+        synchronized (cond) {
+            started = true;
+            cond.notifyAll();
+        }
+        synchronized (obj) {
+
+        }
+        // signal that we have successfully acquired and released the monitor
+        synchronized (cond) {
+            acquired = true;
+            cond.notifyAll();
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Monitor_notowner01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+public class Monitor_notowner01 {
+
+    static Object monitor = new Object();
+    static Object finished = new Object();
+
+    public static boolean test() throws InterruptedException {
+        final BadRunnable badRunnable = new BadRunnable();
+        synchronized (monitor) {
+            new Thread(badRunnable).start();
+            synchronized (finished) {
+                finished.wait(1000);
+            }
+        }
+        return badRunnable.caught;
+    }
+
+    static class BadRunnable implements Runnable {
+
+        protected boolean caught = false;
+
+        public void run() {
+            try {
+                // we don't own this!
+                monitor.wait();
+            } catch (InterruptedException ex) {
+
+            } catch (IllegalMonitorStateException ex) {
+                caught = true;
+                synchronized (finished) {
+                    finished.notifyAll();
+                }
+            }
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Monitorenter01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Monitorenter01 {
+
+    static final Object object = new Object();
+
+    public static boolean test() {
+        // test nested locking.
+        synchronized (object) {
+            synchronized (object) {
+                return true;
+            }
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Monitorenter02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Monitorenter02 {
+
+    static final Object object = new Object();
+
+    public static boolean test() {
+        // test nested locking.
+        synchronized (object) {
+            return test2();
+        }
+    }
+
+    private static boolean test2() {
+        synchronized (object) {
+            return true;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Object_wait01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+public class Object_wait01 implements Runnable {
+
+    static volatile int count = 0;
+    static volatile boolean done;
+    static final Object object = new Object();
+
+    public static boolean test(int i) throws InterruptedException {
+        count = 0;
+        done = false;
+        new Thread(new Object_wait01()).start();
+        synchronized (object) {
+            while (count < i) {
+                object.wait();
+            }
+            done = true;
+            return count >= i;
+        }
+
+    }
+
+    public void run() {
+        int i = 0;
+        while (i++ < 1000000 && !done) {
+            synchronized (object) {
+                count++;
+                object.notifyAll();
+            }
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(15));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Object_wait02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+public class Object_wait02 implements Runnable {
+
+    static volatile boolean done;
+    static final Object object = new Object();
+    static int sleep;
+
+    public static boolean test(int i) throws InterruptedException {
+        done = false;
+        sleep = i * 200;
+        new Thread(new Object_wait02()).start();
+        synchronized (object) {
+            while (!done) {
+                object.wait(200);
+            }
+        }
+        return done;
+    }
+
+    public void run() {
+        try {
+            Thread.sleep(sleep);
+        } catch (InterruptedException ex) {
+
+        }
+        synchronized (object) {
+            done = true;
+            object.notifyAll();
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Object_wait03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+public class Object_wait03 implements Runnable {
+
+    static volatile boolean done;
+    static final Object object = new Object();
+    static int sleep;
+
+    public static boolean test(int i) throws InterruptedException {
+        done = false;
+        sleep = i * 200;
+        synchronized (object) {
+            new Thread(new Object_wait03()).start();
+            dowait();
+        }
+        return done;
+    }
+
+    private static void dowait() throws InterruptedException {
+        synchronized (object) {
+            while (!done) {
+                object.wait(200);
+            }
+        }
+    }
+
+    public void run() {
+        try {
+            Thread.sleep(sleep);
+        } catch (InterruptedException ex) {
+
+        }
+        synchronized (object) {
+            done = true;
+            object.notifyAll();
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Object_wait04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+public class Object_wait04 implements Runnable {
+
+    static volatile boolean done;
+    static final Object object = new Object();
+    static int sleep;
+
+    public static boolean test(int i) throws InterruptedException {
+        done = false;
+        sleep = i * 50;
+        synchronized (object) {
+            new Thread(new Object_wait04()).start();
+            dowait(i);
+        }
+        return done;
+    }
+
+    private static void dowait(int i) throws InterruptedException {
+        if (i == 0) {
+            while (!done) {
+                object.wait(100);
+            }
+        } else {
+            synchronized (object) {
+                dowait(i - 1);
+            }
+        }
+    }
+
+    public void run() {
+        try {
+            Thread.sleep(sleep);
+        } catch (InterruptedException ex) {
+
+        }
+        synchronized (object) {
+            done = true;
+            object.notifyAll();
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(true, test(4));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(true, test(5));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/ThreadLocal01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.threads;
+
+import org.junit.*;
+
+/*
+ */
+public class ThreadLocal01 {
+
+    private static final ThreadLocal<Integer> local = new ThreadLocal<>();
+
+    public static int test(int i) {
+        local.set(i + 5);
+        return local.get();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(5, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(6, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(7, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/ThreadLocal02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.threads;
+
+import org.junit.*;
+
+/*
+ */
+public class ThreadLocal02 {
+
+    public static int test(int i) {
+        ThreadLocal<Integer> local = new ThreadLocal<>();
+        local.set(i + 5);
+        return local.get();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(5, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(6, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(7, test(2));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/ThreadLocal03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.threads;
+
+import org.junit.*;
+
+/*
+ */
+public class ThreadLocal03 {
+
+    static final ThreadLocal<Integer> local = new ThreadLocal<>();
+
+    public static int test(int i) {
+        int sum = 0;
+        for (int j = 0; j < i; j++) {
+            TThread t = new TThread();
+            t.input = 10 + j;
+            t.run();
+            try {
+                t.join();
+            } catch (InterruptedException e) {
+                return -1;
+            }
+            sum += t.output;
+        }
+        return sum;
+    }
+
+    private static class TThread extends Thread {
+
+        int input;
+        int output;
+
+        @Override
+        public void run() {
+            local.set(input + 5);
+            output = local.get();
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(0, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(15, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(31, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(48, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Thread_currentThread01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Thread_currentThread01 {
+
+    public static boolean test() {
+        return Thread.currentThread() != null;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Thread_getState01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Thread_getState01 {
+
+    public static boolean test() {
+        return Thread.currentThread().getState() == Thread.State.RUNNABLE;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Thread_getState02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Thread_getState02 {
+
+    public static boolean test() {
+        return new Thread().getState() == Thread.State.NEW;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Thread_holdsLock01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Thread_holdsLock01 {
+
+    static final Object monitor = new Object();
+
+    public static boolean test(int i) {
+        if (i == 0) {
+            synchronized (monitor) {
+                return Thread.holdsLock(monitor);
+            }
+        } else if (i == 1) {
+            synchronized (monitor) {
+                // do nothing.
+            }
+            return Thread.holdsLock(monitor);
+        } else if (i == 2) {
+            return Thread.holdsLock(null);
+        }
+        return Thread.holdsLock(monitor);
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(false, test(1));
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void run2() throws Throwable {
+        test(2);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(false, test(3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Thread_isAlive01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Thread_isAlive01 {
+
+    public static boolean test() {
+        return Thread.currentThread().isAlive();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Thread_isInterrupted01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Thread_isInterrupted01 {
+
+    public static boolean test() {
+        return Thread.currentThread().isInterrupted();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Thread_isInterrupted02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+//Test all, mainly monitors
+public class Thread_isInterrupted02 {
+
+    private static final Object start = new Object();
+    private static final Object end = new Object();
+    private static int waitTime;
+
+    @SuppressWarnings("unused")
+    public static boolean test(int i, int time) throws InterruptedException {
+        waitTime = time;
+        final Thread thread = new Thread();
+        synchronized (thread) {
+            // start the thread and wait for it
+            thread.setDaemon(true); // in case the thread gets stuck
+            thread.start();
+            thread.wait();
+        }
+        synchronized (start) {
+            thread.interrupt();
+        }
+        synchronized (end) {
+            end.wait(200);
+        }
+        return thread.interrupted;
+    }
+
+    private static class Thread extends java.lang.Thread {
+
+        private boolean interrupted;
+
+        @Override
+        public void run() {
+            try {
+                synchronized (start) {
+                    synchronized (this) {
+                        // signal test thread that we are running
+                        notify();
+                    }
+                    // wait for the condition, which should be interrupted
+                    if (waitTime == 0) {
+                        start.wait();
+                    } else {
+                        start.wait(waitTime);
+                    }
+                }
+            } catch (InterruptedException e) {
+                // interrupted successfully.
+                interrupted = true;
+                synchronized (end) {
+                    // notify the other thread we are done
+                    end.notify();
+                }
+            }
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0, 0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1, 500));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Thread_isInterrupted03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+/*
+ */
+
+// Interrupted while sleeping, throws an interrupted exception
+public class Thread_isInterrupted03 {
+
+    public static boolean test() throws InterruptedException {
+        final Thread1 thread = new Thread1();
+        thread.start();
+        Thread.sleep(1000);
+        thread.interrupt();
+        Thread.sleep(1000);
+        // Did thread get interrupted?
+        final boolean result = thread.getInterrupted();
+        // This stops the thread even if the interrupt didn't!
+        thread.setInterrupted(true);
+        return result;
+    }
+
+    private static class Thread1 extends java.lang.Thread {
+
+        private boolean interrupted = false;
+
+        @Override
+        public void run() {
+            while (!interrupted) {
+                try {
+                    sleep(10000);
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                }
+            }
+        }
+
+        public void setInterrupted(boolean val) {
+            interrupted = val;
+        }
+
+        public boolean getInterrupted() {
+            return interrupted;
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Thread_isInterrupted04.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+/*
+ */
+
+// Interrupted while running, do nothing, just set the flag and continue
+// (tw) This test will exercise deoptimization on HotSpot, because a volatile unloaded field is accessed.
+// (tw) The temporary result variable is needed, because in order to query the isInterrupted flag, the thread must be alive.
+public class Thread_isInterrupted04 {
+
+    public static boolean test() throws InterruptedException {
+        final Thread1 thread = new Thread1();
+        thread.start();
+        while (!thread.running) {
+            Thread.sleep(10);
+        }
+        Thread.sleep(100);
+        thread.interrupt();
+        boolean result = thread.isInterrupted();
+        thread.setStop(true);
+        return result;
+    }
+
+    public static class Thread1 extends java.lang.Thread {
+
+        private volatile boolean stop = false;
+        public volatile boolean running = false;
+        public long i = 0;
+
+        @Override
+        public void run() {
+            running = true;
+            while (!stop) {
+                i++;
+            }
+        }
+
+        public void setStop(boolean value) {
+            stop = value;
+        }
+
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Thread_isInterrupted05.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.jtt.threads;
+
+import org.junit.*;
+
+/*
+ */
+
+// Interrupted during wait, with interrupter joining
+public class Thread_isInterrupted05 {
+
+    public static boolean test() throws InterruptedException {
+        final WaitInterruptee waitInterruptee = new WaitInterruptee();
+        waitInterruptee.start();
+        waitInterruptee.interrupt();
+        waitInterruptee.join();
+
+        if (waitInterruptee.throwable != null) {
+            throw new RuntimeException(waitInterruptee.throwable);
+        }
+        return true;
+    }
+
+    static class WaitInterruptee extends Thread {
+
+        Throwable throwable;
+
+        public WaitInterruptee() {
+            super("WaitInterruptee");
+        }
+
+        @Override
+        public void run() {
+            try {
+                synchronized (this) {
+                    try {
+                        wait();
+                    } catch (InterruptedException ex) {
+                    }
+                }
+            } catch (Throwable t) {
+                throwable = t;
+            }
+        }
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Thread_join01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+public class Thread_join01 implements Runnable {
+
+    static volatile boolean cont;
+
+    public static boolean test() throws InterruptedException {
+        cont = true;
+        final Thread thread = new Thread(new Thread_join01());
+        thread.start();
+        thread.join();
+        return cont;
+    }
+
+    public void run() {
+        cont = false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Thread_join02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ *
+ * This test sleeps the thread that is joined to, which should ensure that the joining thread
+ * actually does wait for completeion.
+ */
+package com.oracle.max.graal.jtt.threads;
+
+import org.junit.*;
+
+public class Thread_join02 implements Runnable {
+
+    static volatile boolean cont;
+
+    public static boolean test() throws InterruptedException {
+        cont = true;
+        final Thread thread = new Thread(new Thread_join02());
+        thread.start();
+        thread.join();
+        return cont;
+    }
+
+    public void run() {
+        try {
+            Thread.sleep(200);
+        } catch (InterruptedException ex) {
+        }
+        cont = false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Thread_join03.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ *
+ * This test sleeps the joining thread, which should enure that the joinee is
+ * terminated by the time the join occurs.
+ */
+package com.oracle.max.graal.jtt.threads;
+
+import org.junit.*;
+
+public class Thread_join03 implements Runnable {
+
+    static volatile boolean cont;
+
+    public static boolean test() throws InterruptedException {
+        cont = true;
+        final Thread thread = new Thread(new Thread_join03());
+        thread.start();
+        Thread.sleep(200);
+        thread.join();
+        return cont;
+    }
+
+    public void run() {
+        cont = false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(false, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Thread_new01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Thread_new01 {
+
+    public static boolean test(int i) {
+        if (i == 0) {
+            return new Thread() != null;
+        }
+        if (i == 1) {
+            return new Thread("Thread_new01") != null;
+        }
+        if (i == 2) {
+            return new Thread(new Thread()) != null;
+        }
+        if (i == 3) {
+            return new Thread(new Thread(), "Thread_new01") != null;
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Thread_new02.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+public class Thread_new02 implements Runnable {
+
+    static final Thread_new02 thisObject = new Thread_new02();
+
+    public static boolean test(int i) {
+        if (i == 0) {
+            return new Thread() != null;
+        }
+        if (i == 1) {
+            return new Thread("Thread_new01") != null;
+        }
+        if (i == 2) {
+            return new Thread(thisObject) != null;
+        }
+        if (i == 3) {
+            return new Thread(thisObject, "Thread_new01") != null;
+        }
+        return false;
+    }
+
+    public void run() {
+        // do nothing.
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(0));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(2));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(3));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(false, test(4));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Thread_setPriority01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Thread_setPriority01 {
+
+    public static boolean test(int i) {
+        final Thread currentThread = Thread.currentThread();
+        final int prev = currentThread.getPriority();
+        currentThread.setPriority(i);
+        currentThread.setPriority(prev);
+        return true;
+    }
+
+    @Test(expected = java.lang.IllegalArgumentException.class)
+    public void run0() throws Throwable {
+        test(0);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(1));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(5));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(true, test(10));
+    }
+
+    @Test(expected = java.lang.IllegalArgumentException.class)
+    public void run4() throws Throwable {
+        test(11);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Thread_sleep01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Thread_sleep01 {
+
+    public static boolean test(int i) throws InterruptedException {
+        final long before = System.currentTimeMillis();
+        Thread.sleep(i);
+        return System.currentTimeMillis() - before >= i;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test(10));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(true, test(20));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(true, test(100));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.jtt/src/com/oracle/max/graal/jtt/threads/Thread_yield01.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2007, 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.max.graal.jtt.threads;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Thread_yield01 {
+
+    public static boolean test() {
+        Thread.yield();
+        return true;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(true, test());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64Arithmetic.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,559 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.lir.amd64;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.asm.*;
+
+public enum AMD64Arithmetic {
+    IADD, ISUB, IMUL, IDIV, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR,
+    LADD, LSUB, LMUL, LDIV, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR,
+    FADD, FSUB, FMUL, FDIV, FAND, FOR, FXOR,
+    DADD, DSUB, DMUL, DDIV, DAND, DOR, DXOR,
+    INEG, LNEG,
+    I2L, L2I, I2B, I2C, I2S,
+    F2D, D2F,
+    I2F, I2D, F2I, D2I,
+    L2F, L2D, F2L, D2L,
+    MOV_I2F, MOV_L2D, MOV_F2I, MOV_D2L;
+
+
+    public static class Op1Reg extends AMD64LIRInstruction {
+        public Op1Reg(AMD64Arithmetic opcode, CiValue result, CiValue x) {
+            super(opcode, new CiValue[] {result}, null, new CiValue[] {x}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            CiValue result = output(0);
+            CiValue x = input(0);
+
+            emit(tasm, masm, (AMD64Arithmetic) code, result, x, null);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    public static class Op1Stack extends AMD64LIRInstruction {
+        public Op1Stack(AMD64Arithmetic opcode, CiValue result, CiValue x) {
+            super(opcode, new CiValue[] {result}, null, new CiValue[] {x}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            CiValue result = output(0);
+            CiValue x = input(0);
+
+            AMD64Move.move(tasm, masm, result, x);
+            emit(tasm, masm, (AMD64Arithmetic) code, result);
+        }
+
+        @Override
+        public EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    public static class Op2Stack extends AMD64LIRInstruction {
+        public Op2Stack(AMD64Arithmetic opcode, CiValue result, CiValue x, CiValue y) {
+            super(opcode, new CiValue[] {result}, null, new CiValue[] {x}, new CiValue[] {y}, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            CiValue result = output(0);
+            CiValue x = input(0);
+            CiValue y = alive(0);
+
+            AMD64Move.move(tasm, masm, result, x);
+            emit(tasm, masm, (AMD64Arithmetic) code, result, y, null);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            } else if (mode == OperandMode.Alive && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        @Override
+        public void verify() {
+            CiValue result = output(0);
+            CiValue x = input(0);
+            CiValue y = alive(0);
+
+            super.verify();
+            assert differentRegisters(result, y) || sameRegister(x, y);
+            verifyKind((AMD64Arithmetic) code, result, x, y);
+        }
+    }
+
+    public static class Op2Reg extends AMD64LIRInstruction {
+        public Op2Reg(AMD64Arithmetic opcode, CiValue result, CiValue x, CiValue y) {
+            super(opcode, new CiValue[] {result}, null, new CiValue[] {x}, new CiValue[] {y}, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            CiValue result = output(0);
+            CiValue x = input(0);
+            CiValue y = alive(0);
+
+            AMD64Move.move(tasm, masm, result, x);
+            emit(tasm, masm, (AMD64Arithmetic) code, result, y, null);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            } else if (mode == OperandMode.Alive && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Constant);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        @Override
+        public void verify() {
+            CiValue result = output(0);
+            CiValue x = input(0);
+            CiValue y = alive(0);
+
+            super.verify();
+            assert differentRegisters(result, y) || sameRegister(x, y);
+            verifyKind((AMD64Arithmetic) code, result, x, y);
+        }
+    }
+
+    public static class Op2RegCommutative extends AMD64LIRInstruction {
+        public Op2RegCommutative(AMD64Arithmetic opcode, CiValue result, CiValue x, CiValue y) {
+            super(opcode, new CiValue[] {result}, null, new CiValue[] {x, y}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            CiValue result = output(0);
+            CiValue x = input(0);
+            CiValue y = input(1);
+
+            if (sameRegister(result, y)) {
+                emit(tasm, masm, (AMD64Arithmetic) code, result, x, null);
+            } else {
+                AMD64Move.move(tasm, masm, result, x);
+                emit(tasm, masm, (AMD64Arithmetic) code, result, y, null);
+            }
+        }
+
+        @Override
+        public EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            } else if (mode == OperandMode.Input && index == 1) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Constant);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        @Override
+        protected void verify() {
+            CiValue result = output(0);
+            CiValue x = input(0);
+            CiValue y = input(1);
+
+            super.verify();
+            verifyKind((AMD64Arithmetic) code, result, x, y);
+        }
+    }
+
+    public static class ShiftOp extends AMD64LIRInstruction {
+        public ShiftOp(AMD64Arithmetic opcode, CiValue result, CiValue x, CiValue y) {
+            super(opcode, new CiValue[] {result}, null, new CiValue[] {x}, new CiValue[] {y}, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            CiValue result = output(0);
+            CiValue x = input(0);
+            CiValue y = alive(0);
+
+            AMD64Move.move(tasm, masm, result, x);
+            emit(tasm, masm, (AMD64Arithmetic) code, result, y, null);
+        }
+
+        @Override
+        public EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            } else if (mode == OperandMode.Alive && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Constant);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        @Override
+        public void verify() {
+            CiValue result = output(0);
+            CiValue x = input(0);
+            CiValue y = alive(0);
+
+            super.verify();
+            assert isConstant(y) || asRegister(y) == AMD64.rcx;
+            assert differentRegisters(result, y) || sameRegister(x, y);
+            verifyKind((AMD64Arithmetic) code, result, x, x);
+            assert y.kind.stackKind() == CiKind.Int;
+        }
+    }
+
+    public static class DivOp extends AMD64LIRInstruction {
+        public DivOp(AMD64Arithmetic opcode, CiValue result, CiValue x, CiValue y, LIRDebugInfo info) {
+            super(opcode, new CiValue[] {result}, info, new CiValue[] {x}, new CiValue[] {y}, new CiValue[] {asRegister(result) == AMD64.rax ? AMD64.rdx.asValue(result.kind) : AMD64.rax.asValue(result.kind)});
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            CiValue result = output(0);
+            CiValue y = alive(0);
+
+            emit(tasm, masm, (AMD64Arithmetic) code, result, y, info);
+        }
+
+        @Override
+        public EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Alive && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Temp && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        @Override
+        protected void verify() {
+            CiValue result = output(0);
+            CiValue x = input(0);
+            CiValue y = alive(0);
+
+            super.verify();
+            // left input in rax, right input in any register but rax and rdx, result quotient in rax, result remainder in rdx
+            assert asRegister(x) == AMD64.rax;
+            assert differentRegisters(y, AMD64.rax.asValue(), AMD64.rdx.asValue());
+            assert (name().endsWith("DIV") && asRegister(result) == AMD64.rax) || (name().endsWith("REM") && asRegister(result) == AMD64.rdx);
+            verifyKind((AMD64Arithmetic) code, result, x, y);
+        }
+    }
+
+
+    @SuppressWarnings("unused")
+    protected static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Arithmetic opcode, CiValue result) {
+        switch (opcode) {
+            case INEG: masm.negl(asIntReg(result)); break;
+            case LNEG: masm.negq(asLongReg(result)); break;
+            case L2I:  masm.andl(asIntReg(result), 0xFFFFFFFF); break;
+            case I2B:  masm.signExtendByte(asIntReg(result)); break;
+            case I2C:  masm.andl(asIntReg(result), 0xFFFF); break;
+            case I2S:  masm.signExtendShort(asIntReg(result)); break;
+            default:   throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    public static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Arithmetic opcode, CiValue dst, CiValue src, LIRDebugInfo info) {
+        int exceptionOffset = -1;
+        if (isRegister(src)) {
+            switch (opcode) {
+                case IADD: masm.addl(asIntReg(dst),  asIntReg(src)); break;
+                case ISUB: masm.subl(asIntReg(dst),  asIntReg(src)); break;
+                case IAND: masm.andl(asIntReg(dst),  asIntReg(src)); break;
+                case IMUL: masm.imull(asIntReg(dst), asIntReg(src)); break;
+                case IOR:  masm.orl(asIntReg(dst),   asIntReg(src)); break;
+                case IXOR: masm.xorl(asIntReg(dst),  asIntReg(src)); break;
+                case ISHL: masm.shll(asIntReg(dst)); break;
+                case ISHR: masm.sarl(asIntReg(dst)); break;
+                case IUSHR:masm.shrl(asIntReg(dst)); break;
+
+                case LADD: masm.addq(asLongReg(dst),  asLongReg(src)); break;
+                case LSUB: masm.subq(asLongReg(dst),  asLongReg(src)); break;
+                case LMUL: masm.imulq(asLongReg(dst), asLongReg(src)); break;
+                case LAND: masm.andq(asLongReg(dst),  asLongReg(src)); break;
+                case LOR:  masm.orq(asLongReg(dst),   asLongReg(src)); break;
+                case LXOR: masm.xorq(asLongReg(dst),  asLongReg(src)); break;
+                case LSHL: masm.shlq(asLongReg(dst)); break;
+                case LSHR: masm.sarq(asLongReg(dst)); break;
+                case LUSHR:masm.shrq(asLongReg(dst)); break;
+
+                case FADD: masm.addss(asFloatReg(dst), asFloatReg(src)); break;
+                case FSUB: masm.subss(asFloatReg(dst), asFloatReg(src)); break;
+                case FMUL: masm.mulss(asFloatReg(dst), asFloatReg(src)); break;
+                case FDIV: masm.divss(asFloatReg(dst), asFloatReg(src)); break;
+                case FAND: masm.andps(asFloatReg(dst), asFloatReg(src)); break;
+                case FOR:  masm.orps(asFloatReg(dst),  asFloatReg(src)); break;
+                case FXOR: masm.xorps(asFloatReg(dst), asFloatReg(src)); break;
+
+                case DADD: masm.addsd(asDoubleReg(dst), asDoubleReg(src)); break;
+                case DSUB: masm.subsd(asDoubleReg(dst), asDoubleReg(src)); break;
+                case DMUL: masm.mulsd(asDoubleReg(dst), asDoubleReg(src)); break;
+                case DDIV: masm.divsd(asDoubleReg(dst), asDoubleReg(src)); break;
+                case DAND: masm.andpd(asDoubleReg(dst), asDoubleReg(src)); break;
+                case DOR:  masm.orpd(asDoubleReg(dst),  asDoubleReg(src)); break;
+                case DXOR: masm.xorpd(asDoubleReg(dst), asDoubleReg(src)); break;
+
+                case I2L: masm.movslq(asLongReg(dst), asIntReg(src)); break;
+                case F2D: masm.cvtss2sd(asDoubleReg(dst), asFloatReg(src)); break;
+                case D2F: masm.cvtsd2ss(asFloatReg(dst), asDoubleReg(src)); break;
+                case I2F: masm.cvtsi2ssl(asFloatReg(dst), asIntReg(src)); break;
+                case I2D: masm.cvtsi2sdl(asDoubleReg(dst), asIntReg(src)); break;
+                case L2F: masm.cvtsi2ssq(asFloatReg(dst), asLongReg(src)); break;
+                case L2D: masm.cvtsi2sdq(asDoubleReg(dst), asLongReg(src)); break;
+                case F2I:
+                    masm.cvttss2sil(asIntReg(dst), asFloatReg(src));
+                    emitConvertFixup(tasm, masm, dst, src);
+                    break;
+                case D2I:
+                    masm.cvttsd2sil(asIntReg(dst), asDoubleReg(src));
+                    emitConvertFixup(tasm, masm, dst, src);
+                    break;
+                case F2L:
+                    masm.cvttss2siq(asLongReg(dst), asFloatReg(src));
+                    emitConvertFixup(tasm, masm, dst, src);
+                    break;
+                case D2L:
+                    masm.cvttsd2siq(asLongReg(dst), asDoubleReg(src));
+                    emitConvertFixup(tasm, masm, dst, src);
+                    break;
+                case MOV_I2F: masm.movdl(asFloatReg(dst), asIntReg(src)); break;
+                case MOV_L2D: masm.movdq(asDoubleReg(dst), asLongReg(src)); break;
+                case MOV_F2I: masm.movdl(asIntReg(dst), asFloatReg(src)); break;
+                case MOV_D2L: masm.movdq(asLongReg(dst), asDoubleReg(src)); break;
+
+                case IDIV:
+                case IREM:
+                    masm.cdql();
+                    exceptionOffset = masm.codeBuffer.position();
+                    masm.idivl(asRegister(src));
+                    break;
+
+                case LDIV:
+                case LREM:
+                    Label continuation = new Label();
+                    if (opcode == LDIV) {
+                        // check for special case of Long.MIN_VALUE / -1
+                        Label normalCase = new Label();
+                        masm.movq(AMD64.rdx, java.lang.Long.MIN_VALUE);
+                        masm.cmpq(AMD64.rax, AMD64.rdx);
+                        masm.jcc(ConditionFlag.notEqual, normalCase);
+                        masm.cmpl(asRegister(src), -1);
+                        masm.jcc(ConditionFlag.equal, continuation);
+                        masm.bind(normalCase);
+                    }
+
+                    masm.cdqq();
+                    exceptionOffset = masm.codeBuffer.position();
+                    masm.idivq(asRegister(src));
+                    masm.bind(continuation);
+                    break;
+
+                case IUDIV:
+                case IUREM:
+                    // Must zero the high 64-bit word (in RDX) of the dividend
+                    masm.xorq(AMD64.rdx, AMD64.rdx);
+                    exceptionOffset = masm.codeBuffer.position();
+                    masm.divl(asRegister(src));
+                    break;
+
+                case LUDIV:
+                case LUREM:
+                    // Must zero the high 64-bit word (in RDX) of the dividend
+                    masm.xorq(AMD64.rdx, AMD64.rdx);
+                    exceptionOffset = masm.codeBuffer.position();
+                    masm.divq(asRegister(src));
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        } else if (isConstant(src)) {
+            switch (opcode) {
+                case IADD: masm.incrementl(asIntReg(dst), tasm.asIntConst(src)); break;
+                case ISUB: masm.decrementl(asIntReg(dst), tasm.asIntConst(src)); break;
+                case IMUL: masm.imull(asIntReg(dst), asIntReg(dst), tasm.asIntConst(src)); break;
+                case IAND: masm.andl(asIntReg(dst), tasm.asIntConst(src)); break;
+                case IOR:  masm.orl(asIntReg(dst),  tasm.asIntConst(src)); break;
+                case IXOR: masm.xorl(asIntReg(dst), tasm.asIntConst(src)); break;
+                case ISHL: masm.shll(asIntReg(dst), tasm.asIntConst(src) & 31); break;
+                case ISHR: masm.sarl(asIntReg(dst), tasm.asIntConst(src) & 31); break;
+                case IUSHR:masm.shrl(asIntReg(dst), tasm.asIntConst(src) & 31); break;
+
+                case LADD: masm.addq(asLongReg(dst), tasm.asIntConst(src)); break;
+                case LSUB: masm.subq(asLongReg(dst), tasm.asIntConst(src)); break;
+                case LMUL: masm.imulq(asLongReg(dst), asLongReg(dst), tasm.asIntConst(src)); break;
+                case LAND: masm.andq(asLongReg(dst), tasm.asIntConst(src)); break;
+                case LOR:  masm.orq(asLongReg(dst),  tasm.asIntConst(src)); break;
+                case LXOR: masm.xorq(asLongReg(dst), tasm.asIntConst(src)); break;
+                case LSHL: masm.shlq(asLongReg(dst), tasm.asIntConst(src) & 63); break;
+                case LSHR: masm.sarq(asLongReg(dst), tasm.asIntConst(src) & 63); break;
+                case LUSHR:masm.shrq(asLongReg(dst), tasm.asIntConst(src) & 63); break;
+
+                case FADD: masm.addss(asFloatReg(dst), tasm.asFloatConstRef(src)); break;
+                case FSUB: masm.subss(asFloatReg(dst), tasm.asFloatConstRef(src)); break;
+                case FMUL: masm.mulss(asFloatReg(dst), tasm.asFloatConstRef(src)); break;
+                case FAND: masm.andps(asFloatReg(dst), tasm.asFloatConstRef(src, 16)); break;
+                case FOR:  masm.orps(asFloatReg(dst),  tasm.asFloatConstRef(src, 16)); break;
+                case FXOR: masm.xorps(asFloatReg(dst), tasm.asFloatConstRef(src, 16)); break;
+                case FDIV: masm.divss(asFloatReg(dst), tasm.asFloatConstRef(src)); break;
+
+                case DADD: masm.addsd(asDoubleReg(dst), tasm.asDoubleConstRef(src)); break;
+                case DSUB: masm.subsd(asDoubleReg(dst), tasm.asDoubleConstRef(src)); break;
+                case DMUL: masm.mulsd(asDoubleReg(dst), tasm.asDoubleConstRef(src)); break;
+                case DDIV: masm.divsd(asDoubleReg(dst), tasm.asDoubleConstRef(src)); break;
+                case DAND: masm.andpd(asDoubleReg(dst), tasm.asDoubleConstRef(src, 16)); break;
+                case DOR:  masm.orpd(asDoubleReg(dst),  tasm.asDoubleConstRef(src, 16)); break;
+                case DXOR: masm.xorpd(asDoubleReg(dst), tasm.asDoubleConstRef(src, 16)); break;
+                default:   throw GraalInternalError.shouldNotReachHere();
+            }
+        } else {
+            switch (opcode) {
+                case IADD: masm.addl(asIntReg(dst), tasm.asIntAddr(src)); break;
+                case ISUB: masm.subl(asIntReg(dst), tasm.asIntAddr(src)); break;
+                case IAND: masm.andl(asIntReg(dst), tasm.asIntAddr(src)); break;
+                case IOR:  masm.orl(asIntReg(dst),  tasm.asIntAddr(src)); break;
+                case IXOR: masm.xorl(asIntReg(dst), tasm.asIntAddr(src)); break;
+
+                case LADD: masm.addq(asLongReg(dst), tasm.asLongAddr(src)); break;
+                case LSUB: masm.subq(asLongReg(dst), tasm.asLongAddr(src)); break;
+                case LAND: masm.andq(asLongReg(dst), tasm.asLongAddr(src)); break;
+                case LOR:  masm.orq(asLongReg(dst),  tasm.asLongAddr(src)); break;
+                case LXOR: masm.xorq(asLongReg(dst), tasm.asLongAddr(src)); break;
+
+                case FADD: masm.addss(asFloatReg(dst), tasm.asFloatAddr(src)); break;
+                case FSUB: masm.subss(asFloatReg(dst), tasm.asFloatAddr(src)); break;
+                case FMUL: masm.mulss(asFloatReg(dst), tasm.asFloatAddr(src)); break;
+                case FDIV: masm.divss(asFloatReg(dst), tasm.asFloatAddr(src)); break;
+
+                case DADD: masm.addsd(asDoubleReg(dst), tasm.asDoubleAddr(src)); break;
+                case DSUB: masm.subsd(asDoubleReg(dst), tasm.asDoubleAddr(src)); break;
+                case DMUL: masm.mulsd(asDoubleReg(dst), tasm.asDoubleAddr(src)); break;
+                case DDIV: masm.divsd(asDoubleReg(dst), tasm.asDoubleAddr(src)); break;
+                default:   throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+
+        if (info != null) {
+            assert exceptionOffset != -1;
+            tasm.recordImplicitException(exceptionOffset, info);
+        }
+    }
+
+    private static void emitConvertFixup(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x) {
+        ConvertSlowPath slowPath = new ConvertSlowPath(result, x);
+        tasm.slowPaths.add(slowPath);
+        switch (result.kind) {
+            case Int:  masm.cmpl(asIntReg(result),  Integer.MIN_VALUE); break;
+            case Long: masm.cmpq(asLongReg(result), tasm.asLongConstRef(CiConstant.forLong(java.lang.Long.MIN_VALUE))); break;
+            default:   throw GraalInternalError.shouldNotReachHere();
+        }
+        masm.jcc(ConditionFlag.equal, slowPath.start);
+        masm.bind(slowPath.continuation);
+    }
+
+    private static class ConvertSlowPath extends AMD64SlowPath {
+        public final Label start = new Label();
+        public final Label continuation = new Label();
+        private final CiValue result;
+        private final CiValue x;
+
+        public ConvertSlowPath(CiValue result, CiValue x) {
+            this.result = result;
+            this.x = x;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            masm.bind(start);
+            switch (x.kind) {
+                case Float:  masm.ucomiss(asFloatReg(x),  tasm.asFloatConstRef(CiConstant.FLOAT_0)); break;
+                case Double: masm.ucomisd(asDoubleReg(x), tasm.asDoubleConstRef(CiConstant.DOUBLE_0)); break;
+                default:     throw GraalInternalError.shouldNotReachHere();
+            }
+            Label nan = new Label();
+            masm.jcc(ConditionFlag.parity, nan);
+            masm.jcc(ConditionFlag.below, continuation);
+
+            // input is > 0 -> return maxInt
+            // result register already contains 0x80000000, so subtracting 1 gives 0x7fffffff
+            switch (result.kind) {
+                case Int:  masm.decrementl(asIntReg(result),  1); break;
+                case Long: masm.decrementq(asLongReg(result), 1); break;
+                default:   throw GraalInternalError.shouldNotReachHere();
+            }
+            masm.jmp(continuation);
+
+            // input is NaN -> return 0
+            masm.bind(nan);
+            masm.xorptr(asRegister(result), asRegister(result));
+            masm.jmp(continuation);
+        }
+    }
+
+
+    private static void verifyKind(AMD64Arithmetic opcode, CiValue result, CiValue x, CiValue y) {
+        assert (opcode.name().startsWith("I") && result.kind == CiKind.Int && x.kind.stackKind() == CiKind.Int && y.kind.stackKind() == CiKind.Int)
+            || (opcode.name().startsWith("L") && result.kind == CiKind.Long && x.kind == CiKind.Long && y.kind == CiKind.Long)
+            || (opcode.name().startsWith("F") && result.kind == CiKind.Float && x.kind == CiKind.Float && y.kind == CiKind.Float)
+            || (opcode.name().startsWith("D") && result.kind == CiKind.Double && x.kind == CiKind.Double && y.kind == CiKind.Double);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64Call.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.lir.amd64;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiTargetMethod.Mark;
+import com.oracle.max.cri.xir.CiXirAssembler.XirMark;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.asm.*;
+
+public class AMD64Call {
+
+    public static class DirectCallOp extends AMD64LIRInstruction implements StandardOp.CallOp {
+        private final Object targetMethod;
+        private final Map<XirMark, Mark> marks;
+
+        public DirectCallOp(Object targetMethod, CiValue result, CiValue[] parameters, LIRDebugInfo info, Map<XirMark, Mark> marks) {
+            super("CALL_DIRECT", new CiValue[] {result}, info, parameters, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+            this.targetMethod = targetMethod;
+            this.marks = marks;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            callAlignment(tasm, masm);
+            if (marks != null) {
+                marks.put(XirMark.CALLSITE, tasm.recordMark(null, new Mark[0]));
+            }
+            directCall(tasm, masm, targetMethod, info);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
+            } else if (mode == OperandMode.Output) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Illegal);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    public static class IndirectCallOp extends AMD64LIRInstruction implements StandardOp.CallOp {
+        private final Object targetMethod;
+        private final Map<XirMark, Mark> marks;
+
+        private static CiValue[] concat(CiValue[] parameters, CiValue targetAddress) {
+            CiValue[] result = Arrays.copyOf(parameters, parameters.length + 1);
+            result[result.length - 1] = targetAddress;
+            return result;
+        }
+
+        public IndirectCallOp(Object targetMethod, CiValue result, CiValue[] parameters, CiValue targetAddress, LIRDebugInfo info, Map<XirMark, Mark> marks) {
+            super("CALL_INDIRECT", new CiValue[] {result}, info, concat(parameters, targetAddress), LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+            this.targetMethod = targetMethod;
+            this.marks = marks;
+        }
+
+        private CiValue targetAddress() {
+            return input(inputs.length - 1);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            callAlignment(tasm, masm);
+            if (marks != null) {
+                marks.put(XirMark.CALLSITE, tasm.recordMark(null, new Mark[0]));
+            }
+            indirectCall(tasm, masm, asRegister(targetAddress()), targetMethod, info);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
+            } else if (mode == OperandMode.Output) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Illegal);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    public static void callAlignment(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        // make sure that the displacement word of the call ends up word aligned
+        int offset = masm.codeBuffer.position();
+        offset += tasm.target.arch.machineCodeCallDisplacementOffset;
+        while (offset++ % tasm.target.wordSize != 0) {
+            masm.nop();
+        }
+    }
+
+    public static void directCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Object target, LIRDebugInfo info) {
+        int before = masm.codeBuffer.position();
+        if (target instanceof CiRuntimeCall) {
+            long maxOffset = tasm.runtime.getMaxCallTargetOffset((CiRuntimeCall) target);
+            if (maxOffset != (int) maxOffset) {
+                // offset might not fit a 32-bit immediate, generate an
+                // indirect call with a 64-bit immediate
+                CiRegister scratch = tasm.frameMap.registerConfig.getScratchRegister();
+                // TODO(cwi): we want to get rid of a generally reserved scratch register.
+                masm.movq(scratch, 0L);
+                masm.call(scratch);
+            } else {
+                masm.call();
+            }
+        } else {
+            masm.call();
+        }
+        int after = masm.codeBuffer.position();
+        tasm.recordDirectCall(before, after, tasm.runtime.asCallTarget(target), info);
+        tasm.recordExceptionHandlers(after, info);
+        masm.ensureUniquePC();
+    }
+
+    public static void directJmp(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Object target) {
+        int before = masm.codeBuffer.position();
+        masm.jmp(0, true);
+        int after = masm.codeBuffer.position();
+        tasm.recordDirectCall(before, after, tasm.runtime.asCallTarget(target), null);
+        masm.ensureUniquePC();
+    }
+
+    public static void indirectCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiRegister dst, Object target, LIRDebugInfo info) {
+        int before = masm.codeBuffer.position();
+        masm.call(dst);
+        int after = masm.codeBuffer.position();
+        tasm.recordIndirectCall(before, after, tasm.runtime.asCallTarget(target), info);
+        tasm.recordExceptionHandlers(after, info);
+        masm.ensureUniquePC();
+    }
+
+    public static void shouldNotReachHere(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        boolean assertions = false;
+        assert (assertions = true) == true;
+
+        if (assertions) {
+            directCall(tasm, masm, CiRuntimeCall.Debug, null);
+            masm.hlt();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64Compare.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.lir.amd64;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.asm.*;
+
+public enum AMD64Compare {
+    ICMP, LCMP, ACMP, FCMP, DCMP;
+
+    public static class CompareOp extends AMD64LIRInstruction {
+        public CompareOp(AMD64Compare opcode, CiValue x, CiValue y) {
+            super(opcode, LIRInstruction.NO_OPERANDS, null, new CiValue[] {x, y}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            CiValue x = input(0);
+            CiValue y = input(1);
+            emit(tasm, masm, (AMD64Compare) code, x, y);
+        }
+
+        @Override
+        public EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Input && index == 1) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        @Override
+        protected void verify() {
+            CiValue x = input(0);
+            CiValue y = input(1);
+
+            super.verify();
+            assert (name().startsWith("I") && x.kind == CiKind.Int && y.kind.stackKind() == CiKind.Int)
+                || (name().startsWith("I") && x.kind == CiKind.Jsr && y.kind == CiKind.Jsr)
+                || (name().startsWith("L") && x.kind == CiKind.Long && y.kind == CiKind.Long)
+                || (name().startsWith("A") && x.kind == CiKind.Object && y.kind == CiKind.Object)
+                || (name().startsWith("F") && x.kind == CiKind.Float && y.kind == CiKind.Float)
+                || (name().startsWith("D") && x.kind == CiKind.Double && y.kind == CiKind.Double);
+        }
+    }
+
+    public static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Compare opcode, CiValue x, CiValue y) {
+        if (isRegister(y)) {
+            switch (opcode) {
+                case ICMP: masm.cmpl(asIntReg(x), asIntReg(y)); break;
+                case LCMP: masm.cmpq(asLongReg(x), asLongReg(y)); break;
+                case ACMP: masm.cmpptr(asObjectReg(x), asObjectReg(y)); break;
+                case FCMP: masm.ucomiss(asFloatReg(x), asFloatReg(y)); break;
+                case DCMP: masm.ucomisd(asDoubleReg(x), asDoubleReg(y)); break;
+                default:   throw GraalInternalError.shouldNotReachHere();
+            }
+        } else if (isConstant(y)) {
+            switch (opcode) {
+                case ICMP: masm.cmpl(asIntReg(x), tasm.asIntConst(y)); break;
+                case LCMP: masm.cmpq(asLongReg(x), tasm.asIntConst(y)); break;
+                case ACMP:
+                    if (((CiConstant) y).isNull()) {
+                        masm.cmpq(asObjectReg(x), 0); break;
+                    } else {
+                        throw GraalInternalError.shouldNotReachHere("Only null object constants are allowed in comparisons");
+                    }
+                case FCMP: masm.ucomiss(asFloatReg(x), tasm.asFloatConstRef(y)); break;
+                case DCMP: masm.ucomisd(asDoubleReg(x), tasm.asDoubleConstRef(y)); break;
+                default:   throw GraalInternalError.shouldNotReachHere();
+            }
+        } else {
+            switch (opcode) {
+                case ICMP: masm.cmpl(asIntReg(x), tasm.asIntAddr(y)); break;
+                case LCMP: masm.cmpq(asLongReg(x), tasm.asLongAddr(y)); break;
+                case ACMP: masm.cmpptr(asObjectReg(x), tasm.asObjectAddr(y)); break;
+                case FCMP: masm.ucomiss(asFloatReg(x), tasm.asFloatAddr(y)); break;
+                case DCMP: masm.ucomisd(asDoubleReg(x), tasm.asDoubleAddr(y)); break;
+                default:  throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64ControlFlow.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.lir.amd64;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiAddress.Scale;
+import com.oracle.max.cri.ci.CiTargetMethod.JumpTable;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.asm.*;
+import com.oracle.max.graal.nodes.calc.*;
+
+public class AMD64ControlFlow {
+
+    public static class ReturnOp extends AMD64LIRInstruction {
+        public ReturnOp(CiValue input) {
+            super("RETURN", LIRInstruction.NO_OPERANDS, null, new CiValue[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            masm.ret(0);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Illegal);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    public static class BranchOp extends AMD64LIRInstruction implements StandardOp.BranchOp {
+        protected Condition condition;
+        protected LabelRef destination;
+
+        public BranchOp(Condition condition, LabelRef destination, LIRDebugInfo info) {
+            super("BRANCH", LIRInstruction.NO_OPERANDS, info, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+            this.condition = condition;
+            this.destination = destination;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            masm.jcc(intCond(condition), destination.label());
+        }
+
+        @Override
+        public LabelRef destination() {
+            return destination;
+        }
+
+        @Override
+        public void negate(LabelRef newDestination) {
+            destination = newDestination;
+            condition = condition.negate();
+        }
+
+        @Override
+        public String operationString() {
+            return condition.operator + " [" + destination + "]";
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    public static class FloatBranchOp extends BranchOp {
+        protected boolean unorderedIsTrue;
+
+        public FloatBranchOp(Condition condition, boolean unorderedIsTrue, LabelRef destination, LIRDebugInfo info) {
+            super(condition, destination, info);
+            this.unorderedIsTrue = unorderedIsTrue;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            floatJcc(masm, condition, unorderedIsTrue, destination.label());
+        }
+
+        @Override
+        public void negate(LabelRef newDestination) {
+            super.negate(newDestination);
+            unorderedIsTrue = !unorderedIsTrue;
+        }
+
+        @Override
+        public String operationString() {
+            return condition.operator + " [" + destination + "]" + (unorderedIsTrue ? " unorderedIsTrue" : " unorderedIsFalse");
+        }
+    }
+
+
+    public static class TableSwitchOp extends AMD64LIRInstruction {
+        private final int lowKey;
+        private final LabelRef defaultTarget;
+        private final LabelRef[] targets;
+
+        public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, final LabelRef[] targets, Variable index, Variable scratch) {
+            super("TABLE_SWITCH", LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, new CiValue[] {index}, new CiValue[] {scratch});
+            this.lowKey = lowKey;
+            this.defaultTarget = defaultTarget;
+            this.targets = targets;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            tableswitch(tasm, masm, lowKey, defaultTarget, targets, asIntReg(alive(0)), asLongReg(temp(0)));
+        }
+
+        @Override
+        public String operationString() {
+            StringBuilder buf = new StringBuilder(super.operationString());
+            buf.append("\ndefault: [").append(defaultTarget).append(']');
+            int key = lowKey;
+            for (LabelRef l : targets) {
+                buf.append("\ncase ").append(key).append(": [").append(l).append(']');
+                key++;
+            }
+            return buf.toString();
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Alive && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Temp && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    public static class CondMoveOp extends AMD64LIRInstruction {
+        private final Condition condition;
+
+        public CondMoveOp(Variable result, Condition condition, Variable trueValue, CiValue falseValue) {
+            super("CMOVE", new CiValue[] {result}, null, new CiValue[] {falseValue}, new CiValue[] {trueValue}, LIRInstruction.NO_OPERANDS);
+            this.condition = condition;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            cmove(tasm, masm, output(0), false, condition, false, alive(0), input(0));
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            } else if (mode == OperandMode.Alive && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        @Override
+        public String operationString() {
+            return condition.toString() + " " + super.operationString();
+        }
+    }
+
+
+    public static class FloatCondMoveOp extends AMD64LIRInstruction {
+        private final Condition condition;
+        private final boolean unorderedIsTrue;
+
+        public FloatCondMoveOp(Variable result, Condition condition, boolean unorderedIsTrue, Variable trueValue, Variable falseValue) {
+            super("FLOAT_CMOVE", new CiValue[] {result}, null, LIRInstruction.NO_OPERANDS, new CiValue[] {trueValue, falseValue}, LIRInstruction.NO_OPERANDS);
+            this.condition = condition;
+            this.unorderedIsTrue = unorderedIsTrue;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            cmove(tasm, masm, output(0), true, condition, unorderedIsTrue, alive(0), alive(1));
+        }
+
+        @Override
+        public String operationString() {
+            return condition.toString() + " unordered=" + unorderedIsTrue + " " + super.operationString();
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Alive && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Alive && index == 1) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    private static void tableswitch(TargetMethodAssembler tasm, AMD64MacroAssembler masm, int lowKey, LabelRef defaultTarget, LabelRef[] targets, CiRegister value, CiRegister scratch) {
+        Buffer buf = masm.codeBuffer;
+        // Compare index against jump table bounds
+        int highKey = lowKey + targets.length - 1;
+        if (lowKey != 0) {
+            // subtract the low value from the switch value
+            masm.subl(value, lowKey);
+            masm.cmpl(value, highKey - lowKey);
+        } else {
+            masm.cmpl(value, highKey);
+        }
+
+        // Jump to default target if index is not within the jump table
+        masm.jcc(ConditionFlag.above, defaultTarget.label());
+
+        // Set scratch to address of jump table
+        int leaPos = buf.position();
+        masm.leaq(scratch, new CiAddress(tasm.target.wordKind, AMD64.rip.asValue(), 0));
+        int afterLea = buf.position();
+
+        // Load jump table entry into scratch and jump to it
+        masm.movslq(value, new CiAddress(CiKind.Int, scratch.asValue(), value.asValue(), Scale.Times4, 0));
+        masm.addq(scratch, value);
+        masm.jmp(scratch);
+
+        // Inserting padding so that jump table address is 4-byte aligned
+        if ((buf.position() & 0x3) != 0) {
+            masm.nop(4 - (buf.position() & 0x3));
+        }
+
+        // Patch LEA instruction above now that we know the position of the jump table
+        int jumpTablePos = buf.position();
+        buf.setPosition(leaPos);
+        masm.leaq(scratch, new CiAddress(tasm.target.wordKind, AMD64.rip.asValue(), jumpTablePos - afterLea));
+        buf.setPosition(jumpTablePos);
+
+        // Emit jump table entries
+        for (LabelRef target : targets) {
+            Label label = target.label();
+            int offsetToJumpTableBase = buf.position() - jumpTablePos;
+            if (label.isBound()) {
+                int imm32 = label.position() - jumpTablePos;
+                buf.emitInt(imm32);
+            } else {
+                label.addPatchAt(buf.position());
+
+                buf.emitByte(0); // psuedo-opcode for jump table entry
+                buf.emitShort(offsetToJumpTableBase);
+                buf.emitByte(0); // padding to make jump table entry 4 bytes wide
+            }
+        }
+
+        JumpTable jt = new JumpTable(jumpTablePos, lowKey, highKey, 4);
+        tasm.targetMethod.addAnnotation(jt);
+    }
+
+    private static void floatJcc(AMD64MacroAssembler masm, Condition condition, boolean unorderedIsTrue, Label label) {
+        ConditionFlag cond = floatCond(condition);
+        Label endLabel = new Label();
+        if (unorderedIsTrue && !trueOnUnordered(cond)) {
+            masm.jcc(ConditionFlag.parity, label);
+        } else if (!unorderedIsTrue && trueOnUnordered(cond)) {
+            masm.jcc(ConditionFlag.parity, endLabel);
+        }
+        masm.jcc(cond, label);
+        masm.bind(endLabel);
+    }
+
+    private static void cmove(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, boolean isFloat, Condition condition, boolean unorderedIsTrue, CiValue trueValue, CiValue falseValue) {
+        ConditionFlag cond = isFloat ? floatCond(condition) : intCond(condition);
+        // check that we don't overwrite an input operand before it is used.
+        assert !result.equals(trueValue);
+
+        AMD64Move.move(tasm, masm, result, falseValue);
+        cmove(tasm, masm, result, cond, trueValue);
+
+        if (isFloat) {
+            if (unorderedIsTrue && !trueOnUnordered(cond)) {
+                cmove(tasm, masm, result, ConditionFlag.parity, trueValue);
+            } else if (!unorderedIsTrue && trueOnUnordered(cond)) {
+                cmove(tasm, masm, result, ConditionFlag.parity, falseValue);
+            }
+        }
+    }
+
+    private static void cmove(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, ConditionFlag cond, CiValue other) {
+        if (isRegister(other)) {
+            assert asRegister(other) != asRegister(result) : "other already overwritten by previous move";
+            switch (other.kind) {
+                case Int:  masm.cmovl(cond, asRegister(result), asRegister(other)); break;
+                case Long: masm.cmovq(cond, asRegister(result), asRegister(other)); break;
+                default:   throw GraalInternalError.shouldNotReachHere();
+            }
+        } else {
+            switch (other.kind) {
+                case Int:  masm.cmovl(cond, asRegister(result), tasm.asAddress(other)); break;
+                case Long: masm.cmovq(cond, asRegister(result), tasm.asAddress(other)); break;
+                default:   throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
+
+    private static ConditionFlag intCond(Condition cond) {
+        switch (cond) {
+            case EQ: return ConditionFlag.equal;
+            case NE: return ConditionFlag.notEqual;
+            case LT: return ConditionFlag.less;
+            case LE: return ConditionFlag.lessEqual;
+            case GE: return ConditionFlag.greaterEqual;
+            case GT: return ConditionFlag.greater;
+            case BE: return ConditionFlag.belowEqual;
+            case AE: return ConditionFlag.aboveEqual;
+            case AT: return ConditionFlag.above;
+            case BT: return ConditionFlag.below;
+            case OF: return ConditionFlag.overflow;
+            case NOF: return ConditionFlag.noOverflow;
+            default: throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private static ConditionFlag floatCond(Condition cond) {
+        switch (cond) {
+            case EQ: return ConditionFlag.equal;
+            case NE: return ConditionFlag.notEqual;
+            case LT: return ConditionFlag.below;
+            case LE: return ConditionFlag.belowEqual;
+            case GE: return ConditionFlag.aboveEqual;
+            case GT: return ConditionFlag.above;
+            default: throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private static boolean trueOnUnordered(ConditionFlag condition) {
+        switch(condition) {
+            case aboveEqual:
+            case notEqual:
+            case above:
+            case less:
+            case overflow:
+                return false;
+            case equal:
+            case belowEqual:
+            case below:
+            case greaterEqual:
+            case noOverflow:
+                return true;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64LIRInstruction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.lir.amd64;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.asm.*;
+
+/**
+ * Convenience class to provide AMD64MacroAssembler for the {@link #emitCode} method.
+ */
+public abstract class AMD64LIRInstruction extends LIRInstruction {
+
+    public AMD64LIRInstruction(Object opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps) {
+        super(opcode, outputs, info, inputs, alives, temps);
+    }
+
+    @Override
+    public final void emitCode(TargetMethodAssembler tasm) {
+        emitCode(tasm, (AMD64MacroAssembler) tasm.asm);
+    }
+
+    public abstract void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64Move.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,489 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.lir.amd64;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static java.lang.Double.*;
+import static java.lang.Float.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.StandardOp.*;
+import com.oracle.max.graal.lir.asm.*;
+
+public class AMD64Move {
+
+    public static class SpillMoveOp extends AMD64LIRInstruction implements MoveOp {
+        public SpillMoveOp(CiValue result, CiValue input) {
+            super("MOVE", new CiValue[] {result}, null, new CiValue[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            move(tasm, masm, getResult(), getInput());
+        }
+
+        @Override
+        public CiValue getInput() {
+            return input(0);
+        }
+        @Override
+        public CiValue getResult() {
+            return output(0);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    public static class MoveToRegOp extends AMD64LIRInstruction implements MoveOp {
+        public MoveToRegOp(CiValue result, CiValue input) {
+            super("MOVE", new CiValue[] {result}, null, new CiValue[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            move(tasm, masm, getResult(), getInput());
+        }
+
+        @Override
+        public CiValue getInput() {
+            return input(0);
+        }
+        @Override
+        public CiValue getResult() {
+            return output(0);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.RegisterHint);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    public static class MoveFromRegOp extends AMD64LIRInstruction implements MoveOp {
+        public MoveFromRegOp(CiValue result, CiValue input) {
+            super("MOVE", new CiValue[] {result}, null, new CiValue[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            move(tasm, masm, getResult(), getInput());
+        }
+
+        @Override
+        public CiValue getInput() {
+            return input(0);
+        }
+        @Override
+        public CiValue getResult() {
+            return output(0);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Constant, OperandFlag.RegisterHint);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    public static class LoadOp extends AMD64LIRInstruction {
+        public LoadOp(CiValue result, CiValue address, LIRDebugInfo info) {
+            super("LOAD", new CiValue[] {result}, info, new CiValue[] {address}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            load(tasm, masm, output(0), (CiAddress) input(0), info);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Address);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    public static class StoreOp extends AMD64LIRInstruction {
+        public StoreOp(CiValue address, CiValue input, LIRDebugInfo info) {
+            super("STORE", LIRInstruction.NO_OPERANDS, info, new CiValue[] {address, input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            store(tasm, masm, (CiAddress) input(0), input(1), info);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Address);
+            } else if (mode == OperandMode.Input && index == 1) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Constant);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    public static class LeaOp extends AMD64LIRInstruction {
+        public LeaOp(CiValue result, CiValue address) {
+            super("LEA", new CiValue[] {result}, null, new CiValue[] {address}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            masm.leaq(asLongReg(output(0)), tasm.asAddress(input(0)));
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Address, OperandFlag.Stack, OperandFlag.Uninitialized);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    public static class MembarOp extends AMD64LIRInstruction {
+        private final int barriers;
+
+        public MembarOp(final int barriers) {
+            super("MEMBAR", LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+            this.barriers = barriers;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            masm.membar(barriers);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    public static class NullCheckOp extends AMD64LIRInstruction {
+        public NullCheckOp(Variable input, LIRDebugInfo info) {
+            super("NULL_CHECK", LIRInstruction.NO_OPERANDS, info, new CiValue[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            tasm.recordImplicitException(masm.codeBuffer.position(), info);
+            masm.nullCheck(asRegister(input(0)));
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    public static class CompareAndSwapOp extends AMD64LIRInstruction {
+        public CompareAndSwapOp(CiValue result, CiAddress address, CiValue cmpValue, CiValue newValue) {
+            super("CAS", new CiValue[] {result}, null, new CiValue[] {address, cmpValue, newValue}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            compareAndSwap(tasm, masm, output(0), asAddress(input(0)), input(1), input(2));
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Input && index == 0) {
+                return EnumSet.of(OperandFlag.Address);
+            } else if (mode == OperandMode.Input && index == 1) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Input && index == 2) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Output && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    public static void move(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue input) {
+        if (isRegister(input)) {
+            if (isRegister(result)) {
+                reg2reg(masm, result, input);
+            } else if (isStackSlot(result)) {
+                reg2stack(tasm, masm, result, input);
+            } else {
+                throw GraalInternalError.shouldNotReachHere();
+            }
+        } else if (isStackSlot(input)) {
+            if (isRegister(result)) {
+                stack2reg(tasm, masm, result, input);
+            } else {
+                throw GraalInternalError.shouldNotReachHere();
+            }
+        } else if (isConstant(input)) {
+            if (isRegister(result)) {
+                const2reg(tasm, masm, result, (CiConstant) input);
+            } else if (isStackSlot(result)) {
+                const2stack(tasm, masm, result, (CiConstant) input);
+            } else {
+                throw GraalInternalError.shouldNotReachHere();
+            }
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private static void reg2reg(AMD64MacroAssembler masm, CiValue result, CiValue input) {
+        if (input.equals(result)) {
+            return;
+        }
+        switch (input.kind) {
+            case Jsr:
+            case Int:    masm.movl(asRegister(result),    asRegister(input)); break;
+            case Long:   masm.movq(asRegister(result),    asRegister(input)); break;
+            case Float:  masm.movflt(asFloatReg(result),  asFloatReg(input)); break;
+            case Double: masm.movdbl(asDoubleReg(result), asDoubleReg(input)); break;
+            case Object: masm.movq(asRegister(result),    asRegister(input)); break;
+            default:     throw GraalInternalError.shouldNotReachHere("kind=" + result.kind);
+        }
+    }
+
+    private static void reg2stack(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue input) {
+        switch (input.kind) {
+            case Jsr:
+            case Int:    masm.movl(tasm.asAddress(result),   asRegister(input)); break;
+            case Long:   masm.movq(tasm.asAddress(result),   asRegister(input)); break;
+            case Float:  masm.movflt(tasm.asAddress(result), asFloatReg(input)); break;
+            case Double: masm.movsd(tasm.asAddress(result),  asDoubleReg(input)); break;
+            case Object: masm.movq(tasm.asAddress(result),   asRegister(input)); break;
+            default:     throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private static void stack2reg(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue input) {
+        switch (input.kind) {
+            case Jsr:
+            case Int:    masm.movl(asRegister(result),    tasm.asAddress(input)); break;
+            case Long:   masm.movq(asRegister(result),    tasm.asAddress(input)); break;
+            case Float:  masm.movflt(asFloatReg(result),  tasm.asAddress(input)); break;
+            case Double: masm.movdbl(asDoubleReg(result), tasm.asAddress(input)); break;
+            case Object: masm.movq(asRegister(result),    tasm.asAddress(input)); break;
+            default:     throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private static void const2reg(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiConstant input) {
+        // Note: we use the kind of the input operand (and not the kind of the result operand) because they don't match
+        // in all cases. For example, an object constant can be loaded to a long register when unsafe casts occurred (e.g.,
+        // for a write barrier where arithmetic operations are then performed on the pointer).
+        switch (input.kind.stackKind()) {
+            case Jsr:
+            case Int:
+                // Do not optimize with an XOR as this instruction may be between
+                // a CMP and a Jcc in which case the XOR will modify the condition
+                // flags and interfere with the Jcc.
+                masm.movl(asRegister(result), tasm.asIntConst(input));
+                break;
+            case Long:
+                // Do not optimize with an XOR as this instruction may be between
+                // a CMP and a Jcc in which case the XOR will modify the condition
+                // flags and interfere with the Jcc.
+                masm.movq(asRegister(result), input.asLong());
+                break;
+            case Float:
+                // This is *not* the same as 'constant == 0.0f' in the case where constant is -0.0f
+                if (Float.floatToRawIntBits(input.asFloat()) == Float.floatToRawIntBits(0.0f)) {
+                    masm.xorps(asFloatReg(result), asFloatReg(result));
+                } else {
+                    masm.movflt(asFloatReg(result), tasm.asFloatConstRef(input));
+                }
+                break;
+            case Double:
+                // This is *not* the same as 'constant == 0.0d' in the case where constant is -0.0d
+                if (Double.doubleToRawLongBits(input.asDouble()) == Double.doubleToRawLongBits(0.0d)) {
+                    masm.xorpd(asDoubleReg(result), asDoubleReg(result));
+                } else {
+                    masm.movdbl(asDoubleReg(result), tasm.asDoubleConstRef(input));
+                }
+                break;
+            case Object:
+                // Do not optimize with an XOR as this instruction may be between
+                // a CMP and a Jcc in which case the XOR will modify the condition
+                // flags and interfere with the Jcc.
+                if (input.isNull()) {
+                    masm.movq(asRegister(result), 0x0L);
+                } else if (tasm.target.inlineObjects) {
+                    tasm.recordDataReferenceInCode(input, 0);
+                    masm.movq(asRegister(result), 0xDEADDEADDEADDEADL);
+                } else {
+                    masm.movq(asRegister(result), tasm.recordDataReferenceInCode(input, 0));
+                }
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private static void const2stack(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiConstant input) {
+        switch (input.kind.stackKind()) {
+            case Jsr:
+            case Int:    masm.movl(tasm.asAddress(result), input.asInt()); break;
+            case Long:   masm.movlong(tasm.asAddress(result), input.asLong()); break;
+            case Float:  masm.movl(tasm.asAddress(result), floatToRawIntBits(input.asFloat())); break;
+            case Double: masm.movlong(tasm.asAddress(result), doubleToRawLongBits(input.asDouble())); break;
+            case Object:
+                if (input.isNull()) {
+                    masm.movlong(tasm.asAddress(result), 0L);
+                } else {
+                    throw GraalInternalError.shouldNotReachHere("Non-null object constants must be in register");
+                }
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    public static void load(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiAddress loadAddr, LIRDebugInfo info) {
+        if (info != null) {
+            tasm.recordImplicitException(masm.codeBuffer.position(), info);
+        }
+        switch (loadAddr.kind) {
+            case Boolean:
+            case Byte:   masm.movsxb(asRegister(result),  loadAddr); break;
+            case Char:   masm.movzxl(asRegister(result),  loadAddr); break;
+            case Short:  masm.movswl(asRegister(result),  loadAddr); break;
+            case Int:    masm.movslq(asRegister(result),  loadAddr); break;
+            case Long:   masm.movq(asRegister(result),    loadAddr); break;
+            case Float:  masm.movflt(asFloatReg(result),  loadAddr); break;
+            case Double: masm.movdbl(asDoubleReg(result), loadAddr); break;
+            case Object: masm.movq(asRegister(result),    loadAddr); break;
+            default:     throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    public static void store(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiAddress storeAddr, CiValue input, LIRDebugInfo info) {
+        if (info != null) {
+            tasm.recordImplicitException(masm.codeBuffer.position(), info);
+        }
+
+        if (isRegister(input)) {
+            switch (storeAddr.kind) {
+                case Boolean:
+                case Byte:   masm.movb(storeAddr,   asRegister(input)); break;
+                case Char:
+                case Short:  masm.movw(storeAddr,   asRegister(input)); break;
+                case Int:    masm.movl(storeAddr,   asRegister(input)); break;
+                case Long:   masm.movq(storeAddr,   asRegister(input)); break;
+                case Float:  masm.movflt(storeAddr, asFloatReg(input)); break;
+                case Double: masm.movsd(storeAddr,  asDoubleReg(input)); break;
+                case Object: masm.movq(storeAddr,   asRegister(input)); break;
+                default:     throw GraalInternalError.shouldNotReachHere();
+            }
+        } else if (isConstant(input)) {
+            CiConstant c = (CiConstant) input;
+            switch (storeAddr.kind) {
+                case Boolean:
+                case Byte:   masm.movb(storeAddr, c.asInt() & 0xFF); break;
+                case Char:
+                case Short:  masm.movw(storeAddr, c.asInt() & 0xFFFF); break;
+                case Jsr:
+                case Int:    masm.movl(storeAddr, c.asInt()); break;
+                case Long:
+                    if (NumUtil.isInt(c.asLong())) {
+                        masm.movslq(storeAddr, (int) c.asLong());
+                    } else {
+                        throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
+                    }
+                    break;
+                case Float:  masm.movl(storeAddr, floatToRawIntBits(c.asFloat())); break;
+                case Double: throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
+                case Object:
+                    if (c.isNull()) {
+                        masm.movptr(storeAddr, 0);
+                    } else {
+                        throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
+                    }
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    protected static void compareAndSwap(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiAddress address, CiValue cmpValue, CiValue newValue) {
+        assert asRegister(cmpValue) == AMD64.rax && asRegister(result) == AMD64.rax;
+
+        if (tasm.target.isMP) {
+            masm.lock();
+        }
+        switch (cmpValue.kind) {
+            case Int:    masm.cmpxchgl(asRegister(newValue), address); break;
+            case Long:
+            case Object: masm.cmpxchgq(asRegister(newValue), address); break;
+            default:     throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir.amd64/src/com/oracle/max/graal/lir/amd64/AMD64SlowPath.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 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.max.graal.lir.amd64;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.asm.*;
+
+/**
+ * Convenience class to provide AMD64MacroAssembler for the {@link #emitCode} method.
+ */
+public abstract class AMD64SlowPath implements LIR.SlowPath {
+    @Override
+    public final void emitCode(TargetMethodAssembler tasm) {
+        emitCode(tasm, (AMD64MacroAssembler) tasm.asm);
+    }
+
+    public abstract void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/FrameMap.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.lir;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ci.CiCallingConvention.Type;
+import com.oracle.max.cri.ri.*;
+
+/**
+ * This class is used to build the stack frame layout for a compiled method.
+ * A {@link CiStackSlot} is used to index slots of the frame relative to the stack pointer.
+ * The frame size is only fixed after register allocation when all spill slots have
+ * been allocated. Both the outgoing argument area and the spill are can grow until then.
+ * Therefore, outgoing arguments are indexed from the stack pointer, while spill slots
+ * are indexed from the beginning of the frame (and the total frame size has to be added
+ * to get the actual offset from the stack pointer).
+ * <br>
+ * This is the format of a stack frame:
+ * <pre>
+ *   Base       Contents
+ *
+ *            :                                :  -----
+ *   caller   | incoming overflow argument n   |    ^
+ *   frame    :     ...                        :    | positive
+ *            | incoming overflow argument 0   |    | offsets
+ *   ---------+--------------------------------+---------------------
+ *            | return address                 |    |            ^
+ *   current  +--------------------------------+    |            |    -----
+ *   frame    |                                |    |            |      ^
+ *            : callee save area               :    |            |      |
+ *            |                                |    |            |      |
+ *            +--------------------------------+    |            |      |
+ *            | spill slot 0                   |    | negative   |      |
+ *            :     ...                        :    v offsets    |      |
+ *            | spill slot n                   |  -----        total  frame
+ *            +--------------------------------+               frame  size
+ *            | alignment padding              |               size     |
+ *            +--------------------------------+  -----          |      |
+ *            | outgoing overflow argument n   |    ^            |      |
+ *            :     ...                        :    | positive   |      |
+ *            | outgoing overflow argument 0   |    | offsets    v      v
+ *    %sp-->  +--------------------------------+---------------------------
+ *
+ * </pre>
+ * The spill slot area also includes stack allocated memory blocks (ALLOCA blocks). The size
+ * of such a block may be greater than the size of a normal spill slot or the word size.
+ * <br>
+ * A runtime has two ways to reserve space in the stack frame for its own use: <ul>
+ * <li>A memory block somewhere in the frame of size {@link RiRuntime#getCustomStackAreaSize()}. The offset
+ *     to this block is returned in {@link CiTargetMethod#customStackAreaOffset()}.
+ * <li>At the beginning of the overflow argument area: The calling convention can specify that the first
+ *     overflow stack argument is not at offset 0, but at a specified offset o. Use
+ *     {@link RiRuntime#getMinimumOutgoingSize()} to make sure that call-free methods also have this space
+ *     reserved. Then the VM can use memory the memory at offset 0 relative to the stack pointer.
+ * </ul>
+ */
+public final class FrameMap {
+    public final RiRuntime runtime;
+    public final CiTarget target;
+    public final RiRegisterConfig registerConfig;
+
+    /**
+     * The final frame size, not including the size of the return address.
+     * The value is only set after register allocation is complete, i.e., after all spill slots have been allocated.
+     */
+    private int frameSize;
+
+    /**
+     * Size of the area occupied by spill slots and other stack-allocated memory blocks.
+     */
+    private int spillSize;
+
+    /**
+     * Size of the area occupied by outgoing overflow arguments.
+     * This value is adjusted as calling conventions for outgoing calls are retrieved.
+     */
+    private int outgoingSize;
+
+    /**
+     * The list of stack areas allocated in this frame that are present in every reference map.
+     */
+    private final List<CiStackSlot> objectStackBlocks;
+
+    /**
+     * The stack area reserved for use by the VM, or {@code null} if the VM does not request stack space.
+     */
+    private final CiStackSlot customArea;
+
+    /**
+     * Creates a new frame map for the specified method.
+     */
+    public FrameMap(RiRuntime runtime, CiTarget target, RiRegisterConfig registerConfig) {
+        this.runtime = runtime;
+        this.target = target;
+        this.registerConfig = registerConfig;
+        this.frameSize = -1;
+        this.spillSize = returnAddressSize() + calleeSaveAreaSize();
+        this.outgoingSize = runtime.getMinimumOutgoingSize();
+        this.objectStackBlocks = new ArrayList<>();
+        this.customArea = allocateStackBlock(runtime.getCustomStackAreaSize(), false);
+    }
+
+
+    private int returnAddressSize() {
+        return target.arch.returnAddressSize;
+    }
+
+    private int calleeSaveAreaSize() {
+        CiCalleeSaveLayout csl = registerConfig.getCalleeSaveLayout();
+        return csl != null ? csl.size : 0;
+    }
+
+    /**
+     * Gets the frame size of the compiled frame, not including the size of the return address.
+     * @return The size of the frame (in bytes).
+     */
+    public int frameSize() {
+        assert frameSize != -1 : "frame size not computed yet";
+        return frameSize;
+    }
+
+    /**
+     * Gets the total frame size of the compiled frame, including the size of the return address.
+     * @return The total size of the frame (in bytes).
+     */
+    public int totalFrameSize() {
+        return frameSize() + returnAddressSize();
+    }
+
+    /**
+     * Sets the frame size for this frame.
+     * @param frameSize The frame size (in bytes).
+     */
+    public void setFrameSize(int frameSize) {
+        assert this.frameSize == -1 : "must only be set once";
+        this.frameSize = frameSize;
+    }
+
+    /**
+     * Computes the frame size for this frame. After this method has been called, methods that change the
+     * frame size cannot be called anymore, e.g., no more spill slots or outgoing arguments can be requested.
+     */
+    public void finish() {
+        setFrameSize(target.alignFrameSize(outgoingSize + spillSize - returnAddressSize()));
+    }
+
+    /**
+     * Computes the offset of a stack slot relative to the frame register.
+     * This is also the bit index of stack slots in the reference map.
+     *
+     * @param slot a stack slot
+     * @return the offset of the stack slot
+     */
+    public int offsetForStackSlot(CiStackSlot slot) {
+        assert (!slot.rawAddFrameSize() && slot.rawOffset() < outgoingSize) ||
+            (slot.rawAddFrameSize() && slot.rawOffset() < 0 && -slot.rawOffset() <= spillSize) ||
+            (slot.rawAddFrameSize() && slot.rawOffset() >= 0);
+        return slot.offset(totalFrameSize());
+    }
+
+    /**
+     * Gets the offset to the stack area where callee-saved registers are stored.
+     * @return The offset to the callee save area (in bytes).
+     */
+    public int offsetToCalleeSaveArea() {
+        return frameSize() - calleeSaveAreaSize();
+    }
+
+    /**
+     * Gets the offset of the stack area stack block reserved for use by the VM, or -1 if the VM does not request stack space.
+     * @return The offset to the custom area (in bytes).
+     */
+    public int offsetToCustomArea() {
+        return customArea == null ? -1 : offsetForStackSlot(customArea);
+    }
+
+    /**
+     * Informs the frame map that the compiled code calls a particular method, which
+     * may need stack space for outgoing arguments.
+     * @param cc The calling convention for the called method.
+     * @param type The type of calling convention.
+     */
+    public void callsMethod(CiCallingConvention cc, Type type) {
+        // TODO look at the actual stack offsets?
+        assert type.out;
+        reserveOutgoing(cc.stackSize);
+    }
+
+    /**
+     * Reserves space for stack-based outgoing arguments.
+     * @param argsSize The amount of space (in bytes) to reserve for stack-based outgoing arguments.
+     */
+    public void reserveOutgoing(int argsSize) {
+        assert frameSize == -1 : "frame size must not yet be fixed";
+        outgoingSize = Math.max(outgoingSize, argsSize);
+    }
+
+    private CiStackSlot getSlot(CiKind kind, int additionalOffset) {
+        return CiStackSlot.get(kind, -spillSize + additionalOffset, true);
+    }
+
+    /**
+     * Reserves a spill slot in the frame of the method being compiled. The returned slot is aligned on its natural alignment,
+     * i.e., an 8-byte spill slot is aligned at an 8-byte boundary.
+     * @param kind The kind of the spill slot to be reserved.
+     * @return A spill slot denoting the reserved memory area.
+     */
+    public CiStackSlot allocateSpillSlot(CiKind kind) {
+        assert frameSize == -1 : "frame size must not yet be fixed";
+        int size = target.sizeInBytes(kind);
+        spillSize = NumUtil.roundUp(spillSize + size, size);
+        return getSlot(kind, 0);
+    }
+
+    /**
+     * Reserves a block of memory in the frame of the method being compiled. The returned block is aligned on a word boundary.
+     * If the requested size is 0, the method returns {@code null}.
+     *
+     * @param size The size to reserve (in bytes).
+     * @param refs Specifies if the block is all references. If true, the block will be in all reference maps for this method.
+     *             The caller is responsible to initialize the memory block before the first instruction that uses a reference map.
+     * @return A stack slot describing the begin of the memory block.
+     */
+    public CiStackSlot allocateStackBlock(int size, boolean refs) {
+        assert frameSize == -1 : "frame size must not yet be fixed";
+        if (size == 0) {
+            return null;
+        }
+        spillSize = NumUtil.roundUp(spillSize + size, target.wordSize);
+
+        if (refs) {
+            assert size % target.wordSize == 0;
+            CiStackSlot result = getSlot(CiKind.Object, 0);
+            objectStackBlocks.add(result);
+            for (int i = target.wordSize; i < size; i += target.wordSize) {
+                objectStackBlocks.add(getSlot(CiKind.Object, i));
+            }
+            return result;
+
+        } else {
+            return getSlot(target.wordKind, 0);
+        }
+    }
+
+
+    private int frameRefMapIndex(CiStackSlot slot) {
+        assert offsetForStackSlot(slot) % target.wordSize == 0;
+        return offsetForStackSlot(slot) / target.wordSize;
+    }
+
+    /**
+     * Initializes a reference map that covers all registers of the target architecture.
+     */
+    public CiBitMap initRegisterRefMap() {
+        return new CiBitMap(target.arch.registerReferenceMapBitCount);
+    }
+
+    /**
+     * Initializes a reference map. Initially, the size is large enough to cover all the
+     * slots in the frame. If the method has incoming reference arguments on the stack,
+     * the reference map might grow later when such a reference is set.
+     */
+    public CiBitMap initFrameRefMap() {
+        CiBitMap frameRefMap = new CiBitMap(frameSize() / target.wordSize);
+        for (CiStackSlot slot : objectStackBlocks) {
+            setReference(slot, null, frameRefMap);
+        }
+        return frameRefMap;
+    }
+
+    /**
+     * Marks the specified location as a reference in the reference map of the debug information.
+     * The tracked location can be a {@link CiRegisterValue} or a {@link CiStackSlot}. Note that a
+     * {@link CiConstant} is automatically tracked.
+     *
+     * @param location The location to be added to the reference map.
+     * @param registerRefMap A register reference map, as created by {@link #initRegisterRefMap()}.
+     * @param frameRefMap A frame reference map, as created by {@link #initFrameRefMap()}.
+     */
+    public void setReference(CiValue location, CiBitMap registerRefMap, CiBitMap frameRefMap) {
+        if (location.kind == CiKind.Object) {
+            if (isRegister(location)) {
+                assert registerRefMap.size() == target.arch.registerReferenceMapBitCount;
+                registerRefMap.set(asRegister(location).number);
+            } else if (isStackSlot(location)) {
+                int index = frameRefMapIndex(asStackSlot(location));
+                frameRefMap.grow(index + 1);
+                frameRefMap.set(index);
+            } else {
+                assert isConstant(location);
+            }
+        }
+    }
+
+    /**
+     * Clears the specified location as a reference in the reference map of the debug information.
+     * The tracked location can be a {@link CiRegisterValue} or a {@link CiStackSlot}. Note that a
+     * {@link CiConstant} is automatically tracked.
+     *
+     * @param location The location to be removed from the reference map.
+     * @param registerRefMap A register reference map, as created by {@link #initRegisterRefMap()}.
+     * @param frameRefMap A frame reference map, as created by {@link #initFrameRefMap()}.
+     */
+    public void clearReference(CiValue location, CiBitMap registerRefMap, CiBitMap frameRefMap) {
+        if (location.kind == CiKind.Object) {
+            if (location instanceof CiRegisterValue) {
+                assert registerRefMap.size() == target.arch.registerReferenceMapBitCount;
+                registerRefMap.clear(asRegister(location).number);
+            } else if (isStackSlot(location)) {
+                int index = frameRefMapIndex(asStackSlot(location));
+                if (index < frameRefMap.size()) {
+                    frameRefMap.clear(index);
+                }
+            } else {
+                assert isConstant(location);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LIR.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.lir;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.asm.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+/**
+ * This class implements the overall container for the LIR graph
+ * and directs its construction, optimization, and finalization.
+ */
+public class LIR {
+
+    public final ControlFlowGraph cfg;
+
+    /**
+     * The nodes for the blocks.
+     * TODO: This should go away, we want all nodes connected with a next-pointer.
+     */
+    private final BlockMap<List<Node>> nodesFor;
+
+    /**
+     * The linear-scan ordered list of blocks.
+     */
+    private final List<Block> linearScanOrder;
+
+    /**
+     * The order in which the code is emitted.
+     */
+    private final List<Block> codeEmittingOrder;
+
+
+    public final List<SlowPath> slowPaths;
+
+    public final List<SlowPath> deoptimizationStubs;
+
+    /**
+     * The last slow path emitted, which can be used emit marker bytes.
+     */
+    public SlowPath methodEndMarker;
+
+    private int numVariables;
+
+    public SpillMoveFactory spillMoveFactory;
+
+    public interface SpillMoveFactory {
+        LIRInstruction createMove(CiValue result, CiValue input);
+        LIRInstruction createExchange(CiValue input1, CiValue input2);
+    }
+
+    public interface SlowPath {
+        void emitCode(TargetMethodAssembler tasm);
+    }
+
+    /**
+     * Creates a new LIR instance for the specified compilation.
+     * @param numLoops number of loops
+     * @param compilation the compilation
+     */
+    public LIR(ControlFlowGraph cfg, BlockMap<List<Node>> nodesFor, List<Block> linearScanOrder, List<Block> codeEmittingOrder) {
+        this.cfg = cfg;
+        this.nodesFor = nodesFor;
+        this.codeEmittingOrder = codeEmittingOrder;
+        this.linearScanOrder = linearScanOrder;
+
+        slowPaths = new ArrayList<>();
+        deoptimizationStubs = new ArrayList<>();
+    }
+
+    public List<Node> nodesFor(Block block) {
+        return nodesFor.get(block);
+    }
+
+    /**
+     * Gets the linear scan ordering of blocks as a list.
+     * @return the blocks in linear scan order
+     */
+    public List<Block> linearScanOrder() {
+        return linearScanOrder;
+    }
+
+    public List<Block> codeEmittingOrder() {
+        return codeEmittingOrder;
+    }
+
+    public int numVariables() {
+        return numVariables;
+    }
+
+    public int nextVariable() {
+        return numVariables++;
+    }
+
+    public void emitCode(TargetMethodAssembler tasm) {
+        for (Block b : codeEmittingOrder()) {
+            emitBlock(tasm, b);
+        }
+
+        // generate code for slow cases
+        for (SlowPath sp : slowPaths) {
+            emitSlowPath(tasm, sp);
+        }
+        // generate deoptimization stubs
+        for (SlowPath sp : deoptimizationStubs) {
+            emitSlowPath(tasm, sp);
+        }
+        // generate traps at the end of the method
+        emitSlowPath(tasm, methodEndMarker);
+    }
+
+    private static void emitBlock(TargetMethodAssembler tasm, Block block) {
+        if (Debug.isDumpEnabled()) {
+            tasm.blockComment(String.format("block B%d %s", block.getId(), block.getLoop()));
+        }
+
+        for (LIRInstruction op : block.lir) {
+            if (Debug.isDumpEnabled()) {
+                tasm.blockComment(String.format("%d %s", op.id(), op));
+            }
+
+            emitOp(tasm, op);
+        }
+    }
+
+    private static void emitOp(TargetMethodAssembler tasm, LIRInstruction op) {
+        try {
+            try {
+                op.emitCode(tasm);
+            } catch (AssertionError t) {
+                throw new GraalInternalError(t);
+            } catch (RuntimeException t) {
+                throw new GraalInternalError(t);
+            }
+        } catch (GraalInternalError e) {
+            throw e.addContext("lir instruction", op);
+        }
+    }
+
+    private static void emitSlowPath(TargetMethodAssembler tasm, SlowPath sp) {
+        if (Debug.isDumpEnabled()) {
+            tasm.blockComment(String.format("slow case %s", sp.getClass().getName()));
+        }
+        sp.emitCode(tasm);
+    }
+
+/*
+    private int lastDecodeStart;
+
+    private void printAssembly(TargetMethodAssembler tasm) {
+        byte[] currentBytes = tasm.asm.codeBuffer.copyData(lastDecodeStart, tasm.asm.codeBuffer.position());
+        if (currentBytes.length > 0) {
+            String disasm = tasm.runtime.disassemble(currentBytes, lastDecodeStart);
+            if (disasm.length() != 0) {
+                TTY.println(disasm);
+            } else {
+                TTY.println("Code [+%d]: %d bytes", lastDecodeStart, currentBytes.length);
+                Util.printBytes(lastDecodeStart, currentBytes, GraalOptions.PrintAssemblyBytesPerLine);
+            }
+        }
+        lastDecodeStart = tasm.asm.codeBuffer.position();
+    }
+
+
+    public static void printBlock(Block x) {
+        // print block id
+        TTY.print("B%d ", x.getId());
+
+        // print flags
+        if (x.isLoopHeader()) {
+            TTY.print("lh ");
+        }
+        if (x.isLoopEnd()) {
+            TTY.print("le ");
+        }
+
+        // print block bci range
+        TTY.print("[%d, %d] ", -1, -1);
+
+        // print predecessors and successors
+        if (x.numberOfPreds() > 0) {
+            TTY.print("preds: ");
+            for (int i = 0; i < x.numberOfPreds(); i++) {
+                TTY.print("B%d ", x.predAt(i).getId());
+            }
+        }
+
+        if (x.numberOfSux() > 0) {
+            TTY.print("sux: ");
+            for (int i = 0; i < x.numberOfSux(); i++) {
+                TTY.print("B%d ", x.suxAt(i).getId());
+            }
+        }
+
+        TTY.println();
+    }
+
+    public static void printLIR(List<Block> blocks) {
+        if (TTY.isSuppressed()) {
+            return;
+        }
+        TTY.println("LIR:");
+        int i;
+        for (i = 0; i < blocks.size(); i++) {
+            Block bb = blocks.get(i);
+            printBlock(bb);
+            TTY.println("__id_Instruction___________________________________________");
+            for (LIRInstruction op : bb.lir) {
+                TTY.println(op.toStringWithIdPrefix());
+                TTY.println();
+            }
+            TTY.println();
+        }
+    }
+*/
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LIRDebugInfo.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.lir;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.lir.LIRInstruction.OperandFlag;
+import com.oracle.max.graal.lir.LIRInstruction.OperandMode;
+import com.oracle.max.graal.lir.LIRInstruction.ValueProcedure;
+
+/**
+ * This class represents garbage collection and deoptimization information attached to a LIR instruction.
+ */
+public class LIRDebugInfo {
+    public final CiFrame topFrame;
+    private final CiVirtualObject[] virtualObjects;
+    private final List<CiStackSlot> pointerSlots;
+    public final LabelRef exceptionEdge;
+    private CiDebugInfo debugInfo;
+
+    public LIRDebugInfo(CiFrame topFrame, CiVirtualObject[] virtualObjects, List<CiStackSlot> pointerSlots, LabelRef exceptionEdge) {
+        this.topFrame = topFrame;
+        this.virtualObjects = virtualObjects;
+        this.pointerSlots = pointerSlots;
+        this.exceptionEdge = exceptionEdge;
+    }
+
+    public boolean hasDebugInfo() {
+        return debugInfo != null;
+    }
+
+    public CiDebugInfo debugInfo() {
+        assert debugInfo != null : "debug info not allocated yet";
+        return debugInfo;
+    }
+
+    /**
+     * Iterates the frame state and calls the {@link ValueProcedure} for every variable.
+     *
+     * @param proc The procedure called for variables.
+     */
+    public void forEachState(ValueProcedure proc) {
+        for (CiFrame cur = topFrame; cur != null; cur = cur.caller()) {
+            processValues(cur.values, proc);
+        }
+        if (virtualObjects != null) {
+            for (CiVirtualObject obj : virtualObjects) {
+                processValues(obj.values(), proc);
+            }
+        }
+    }
+
+    /**
+     * We filter out constant and illegal values ourself before calling the procedure, so {@link OperandFlag#Constant} and {@link OperandFlag#Illegal} need not be set.
+     */
+    private static final EnumSet<OperandFlag> STATE_FLAGS = EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
+
+    private void processValues(CiValue[] values, ValueProcedure proc) {
+        for (int i = 0; i < values.length; i++) {
+            CiValue value = values[i];
+            if (value instanceof CiMonitorValue) {
+                CiMonitorValue monitor = (CiMonitorValue) value;
+                if (processed(monitor.owner)) {
+                    monitor.owner = proc.doValue(monitor.owner, OperandMode.Alive, STATE_FLAGS);
+                }
+
+            } else if (processed(value)) {
+                values[i] = proc.doValue(value, OperandMode.Alive, STATE_FLAGS);
+            }
+        }
+    }
+
+    private boolean processed(CiValue value) {
+        if (isIllegal(value)) {
+            // Ignore dead local variables.
+            return false;
+        } else if (isConstant(value)) {
+            // Ignore constants, the register allocator does not need to see them.
+            return false;
+        } else if (isVirtualObject(value)) {
+            assert Arrays.asList(virtualObjects).contains(value);
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+
+    public void finish(CiBitMap registerRefMap, CiBitMap frameRefMap, FrameMap frameMap) {
+        debugInfo = new CiDebugInfo(topFrame, registerRefMap, frameRefMap);
+
+        // Add additional stack slots for outgoing method parameters.
+        if (pointerSlots != null) {
+            for (CiStackSlot v : pointerSlots) {
+                frameMap.setReference(v, registerRefMap, frameRefMap);
+            }
+        }
+    }
+
+
+    @Override
+    public String toString() {
+        return debugInfo != null ? debugInfo.toString() : topFrame.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LIRInsertionBuffer.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.lir;
+
+import java.util.*;
+
+/**
+ * A buffer to enqueue updates to a list. This avoids frequent re-sizing of the list and copying of list elements
+ * when insertions are done at multiple positions of the list. Additionally, it ensures that the list is not modified
+ * while it is, e.g., iterated, and instead only modified once after the iteration is done.
+ * <br>
+ * The buffer uses internal data structures to store the enqueued updates. To avoid allocations, a buffer can be re-used.
+ * Call the methods in the following order:
+ * {@link #init()}, {@link #append()}, {@link #append()}, ..., {@link #finish()}, {@link #init()}, ...
+ * <br>
+ * Note: This class does not depend on LIRInstruction, so we could make it a generic utility class.
+ */
+public final class LIRInsertionBuffer {
+
+    /**
+     * The lir list where ops of this buffer should be inserted later (null when uninitialized).
+     */
+    private List<LIRInstruction> lir;
+
+    /**
+     * List of insertion points. index and count are stored alternately:
+     * indexAndCount[i * 2]: the index into lir list where "count" ops should be inserted
+     * indexAndCount[i * 2 + 1]: the number of ops to be inserted at index
+     */
+    private final List<Integer> indexAndCount;
+
+    /**
+     * The LIROps to be inserted.
+     */
+    private final List<LIRInstruction> ops;
+
+
+    public LIRInsertionBuffer() {
+        indexAndCount = new ArrayList<>(8);
+        ops = new ArrayList<>(8);
+    }
+
+    /**
+     * Initialize this buffer. This method must be called before using {@link #append()}.
+     */
+    public void init(List<LIRInstruction> newLir) {
+        assert !initialized() : "already initialized";
+        assert indexAndCount.size() == 0 && ops.size() == 0;
+        this.lir = newLir;
+    }
+
+    public boolean initialized() {
+        return lir != null;
+    }
+
+    public List<LIRInstruction> lirList() {
+        return lir;
+    }
+
+    /**
+     * Enqueue a new instruction that will be appended to the instruction list when {@link #finish()} is called.
+     * The new instruction is added <b>before</b> the existing instruction with the given index. This method can only be called
+     * with increasing values of index, e.g., once an instruction was appended with index 4, subsequent instructions can
+     * only be appended with index 4 or higher.
+     */
+    public void append(int index, LIRInstruction op) {
+        int i = numberOfInsertionPoints() - 1;
+        if (i < 0 || indexAt(i) < index) {
+            appendNew(index, 1);
+        } else {
+            assert indexAt(i) == index : "can append LIROps in ascending order only";
+            assert countAt(i) > 0 : "check";
+            setCountAt(i, countAt(i) + 1);
+        }
+        ops.add(op);
+
+        assert verify();
+    }
+
+    /**
+     * Append all enqueued instructions to the instruction list. After that, {@link init()} can be called again to re-use this buffer.
+     */
+    public void finish() {
+        if (ops.size() > 0) {
+            int n = lir.size();
+            // increase size of instructions list
+            for (int i = 0; i < ops.size(); i++) {
+                lir.add(null);
+            }
+            // insert ops from buffer into instructions list
+            int opIndex = ops.size() - 1;
+            int ipIndex = numberOfInsertionPoints() - 1;
+            int fromIndex = n - 1;
+            int toIndex = lir.size() - 1;
+            while (ipIndex >= 0) {
+                int index = indexAt(ipIndex);
+                // make room after insertion point
+                while (fromIndex >= index) {
+                    lir.set(toIndex--, lir.get(fromIndex--));
+                }
+                // insert ops from buffer
+                for (int i = countAt(ipIndex); i > 0; i--) {
+                    lir.set(toIndex--, ops.get(opIndex--));
+                }
+                ipIndex--;
+            }
+            indexAndCount.clear();
+            ops.clear();
+        }
+        lir = null;
+    }
+
+    private void appendNew(int index, int count) {
+        indexAndCount.add(index);
+        indexAndCount.add(count);
+    }
+
+    private void setCountAt(int i, int value) {
+        indexAndCount.set((i << 1) + 1, value);
+    }
+
+    private int numberOfInsertionPoints() {
+        assert indexAndCount.size() % 2 == 0 : "must have a count for each index";
+        return indexAndCount.size() >> 1;
+    }
+
+    private int indexAt(int i) {
+        return indexAndCount.get((i << 1));
+    }
+
+    private int countAt(int i) {
+        return indexAndCount.get((i << 1) + 1);
+    }
+
+    private boolean verify() {
+        int sum = 0;
+        int prevIdx = -1;
+
+        for (int i = 0; i < numberOfInsertionPoints(); i++) {
+            assert prevIdx < indexAt(i) : "index must be ordered ascending";
+            sum += countAt(i);
+        }
+        assert sum == ops.size() : "wrong total sum";
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LIRInstruction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.lir;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.asm.*;
+
+/**
+ * The {@code LIRInstruction} class definition.
+ */
+public abstract class LIRInstruction {
+
+    public static final CiValue[] NO_OPERANDS = {};
+
+    /**
+     * Iterator for iterating over a list of values. Subclasses must overwrite one of the doValue methods.
+     * Clients of the class must only call the doValue method that takes additional parameters.
+     */
+    public abstract static class ValueProcedure {
+        /**
+         * Iterator method to be overwritten. This version of the iterator does not take additional parameters
+         * to keep the signature short.
+         *
+         * @param value The value that is iterated.
+         * @return The new value to replace the value that was passed in.
+         */
+        protected CiValue doValue(CiValue value) {
+            throw GraalInternalError.shouldNotReachHere("One of the doValue() methods must be overwritten");
+        }
+
+        /**
+         * Iterator method to be overwritten. This version of the iterator gets additional parameters about the
+         * processed value.
+         *
+         * @param value The value that is iterated.
+         * @param mode The operand mode for the value.
+         * @param flags A set of flags for the value.
+         * @return The new value to replace the value that was passed in.
+         */
+        public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+            return doValue(value);
+        }
+    }
+
+
+    /**
+     * Constants denoting how a LIR instruction uses an operand.
+     */
+    public enum OperandMode {
+        /**
+         * The value must have been defined before. It is alive before the instruction until the beginning of the
+         * instruction, but not necessarily throughout the instruction. A register assigned to it can also be assigend
+         * to a Temp or Output operand. The value can be used again after the instruction, so the instruction must not
+         * modify the register.
+         */
+        Input,
+
+        /**
+         * The value must have been defined before. It is alive before the instruction and throughout the instruction. A
+         * register assigned to it cannot be assigned to a Temp or Output operand. The value can be used again after the
+         * instruction, so the instruction must not modify the register.
+         */
+        Alive,
+
+        /**
+         * The value must not have been defined before, and must not be used after the instruction. The instruction can
+         * do whatever it wants with the register assigned to it (or not use it at all).
+         */
+        Temp,
+
+        /**
+         * The value must not have been defined before. The instruction has to assign a value to the register. The
+         * value can (and most likely will) be used after the instruction.
+         */
+        Output,
+    }
+
+    /**
+     * Flags for an operand.
+     */
+    public enum OperandFlag {
+        /**
+         * The value can be a {@link CiRegisterValue}.
+         */
+        Register,
+
+        /**
+         * The value can be a {@link CiStackSlot}.
+         */
+        Stack,
+
+        /**
+         * The value can be a {@link CiAddress}.
+         */
+        Address,
+
+        /**
+         * The value can be a {@link CiConstant}.
+         */
+        Constant,
+
+        /**
+         * The value can be {@link CiValue#IllegalValue}.
+         */
+        Illegal,
+
+        /**
+         * The register allocator should try to assign a certain register to improve code quality.
+         * Use {@link LIRInstruction#forEachRegisterHint} to access the register hints.
+         */
+        RegisterHint,
+
+        /**
+         * The value can be uninitialized, e.g., a stack slot that has not written to before. This is only
+         * used to avoid false positives in verification code.
+         */
+        Uninitialized,
+    }
+
+    /**
+     * For validity checking of the operand flags defined by instruction subclasses.
+     */
+    private static final EnumMap<OperandMode, EnumSet<OperandFlag>> ALLOWED_FLAGS;
+
+    static {
+        ALLOWED_FLAGS = new EnumMap<>(OperandMode.class);
+        ALLOWED_FLAGS.put(OperandMode.Input,  EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Address, OperandFlag.Constant, OperandFlag.Illegal, OperandFlag.RegisterHint, OperandFlag.Uninitialized));
+        ALLOWED_FLAGS.put(OperandMode.Alive,  EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Address, OperandFlag.Constant, OperandFlag.Illegal, OperandFlag.RegisterHint, OperandFlag.Uninitialized));
+        ALLOWED_FLAGS.put(OperandMode.Temp,   EnumSet.of(OperandFlag.Register, OperandFlag.Constant, OperandFlag.Illegal, OperandFlag.RegisterHint));
+        ALLOWED_FLAGS.put(OperandMode.Output, EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Illegal, OperandFlag.RegisterHint));
+    }
+
+    /**
+     * The opcode of this instruction.
+     */
+    protected final Object code;
+
+    /**
+     * The output operands for this instruction (modified by the register allocator).
+     */
+    protected CiValue[] outputs;
+
+    /**
+     * The input operands for this instruction (modified by the register allocator).
+     */
+    protected CiValue[] inputs;
+
+    /**
+     * The alive operands for this instruction (modified by the register allocator).
+     */
+    protected CiValue[] alives;
+
+    /**
+     * The temp operands for this instruction (modified by the register allocator).
+     */
+    protected CiValue[] temps;
+
+    /**
+     * Used to emit debug information.
+     */
+    public final LIRDebugInfo info;
+
+    /**
+     * Instruction id for register allocation.
+     */
+    private int id;
+
+    /**
+     * Constructs a new LIR instruction that has input and temp operands.
+     *
+     * @param opcode the opcode of the new instruction
+     * @param outputs the operands that holds the operation results of this instruction.
+     * @param info the {@link LIRDebugInfo} info that is to be preserved for the instruction. This will be {@code null} when no debug info is required for the instruction.
+     * @param inputs the input operands for the instruction.
+     * @param temps the temp operands for the instruction.
+     */
+    public LIRInstruction(Object opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps) {
+        this.code = opcode;
+        this.outputs = outputs;
+        this.inputs = inputs;
+        this.alives = alives;
+        this.temps = temps;
+        this.info = info;
+        this.id = -1;
+    }
+
+    public abstract void emitCode(TargetMethodAssembler tasm);
+
+
+    public final int id() {
+        return id;
+    }
+
+    public final void setId(int id) {
+        this.id = id;
+    }
+
+    /**
+     * Gets an input operand of this instruction.
+     *
+     * @param index the index of the operand requested.
+     * @return the {@code index}'th input operand.
+     */
+    protected final CiValue input(int index) {
+        return inputs[index];
+    }
+
+    /**
+     * Gets an alive operand of this instruction.
+     *
+     * @param index the index of the operand requested.
+     * @return the {@code index}'th alive operand.
+     */
+    protected final CiValue alive(int index) {
+        return alives[index];
+    }
+
+    /**
+     * Gets a temp operand of this instruction.
+     *
+     * @param index the index of the operand requested.
+     * @return the {@code index}'th temp operand.
+     */
+    protected final CiValue temp(int index) {
+        return temps[index];
+    }
+
+    /**
+     * Gets the result operand for this instruction.
+     *
+     * @return return the result operand
+     */
+    protected final CiValue output(int index) {
+        return outputs[index];
+    }
+
+    /**
+     * Gets the instruction name.
+     */
+    public String name() {
+        return code.toString();
+    }
+
+    public boolean hasOperands() {
+        return inputs.length > 0 || alives.length > 0 || temps.length > 0 || outputs.length > 0 || info != null || hasCall();
+    }
+
+    private static final EnumSet<OperandFlag> ADDRESS_FLAGS = EnumSet.of(OperandFlag.Register, OperandFlag.Illegal);
+
+    private void forEach(CiValue[] values, OperandMode mode, ValueProcedure proc) {
+        for (int i = 0; i < values.length; i++) {
+            assert ALLOWED_FLAGS.get(mode).containsAll(flagsFor(mode, i));
+
+            CiValue value = values[i];
+            if (isAddress(value)) {
+                assert flagsFor(mode, i).contains(OperandFlag.Address);
+                CiAddress address = asAddress(value);
+                address.base = proc.doValue(address.base, mode, ADDRESS_FLAGS);
+                address.index = proc.doValue(address.index, mode, ADDRESS_FLAGS);
+            } else {
+                values[i] = proc.doValue(values[i], mode, flagsFor(mode, i));
+            }
+        }
+    }
+
+    public final void forEachInput(ValueProcedure proc) {
+        forEach(inputs, OperandMode.Input, proc);
+    }
+
+    public final void forEachAlive(ValueProcedure proc) {
+        forEach(alives, OperandMode.Alive, proc);
+    }
+
+    public final void forEachTemp(ValueProcedure proc) {
+        forEach(temps, OperandMode.Temp, proc);
+    }
+
+    public final void forEachOutput(ValueProcedure proc) {
+        forEach(outputs, OperandMode.Output, proc);
+    }
+
+    public final void forEachState(ValueProcedure proc) {
+        if (info != null) {
+            info.forEachState(proc);
+
+            if (this instanceof LIRXirInstruction) {
+                LIRXirInstruction xir = (LIRXirInstruction) this;
+                if (xir.infoAfter != null) {
+                    xir.infoAfter.forEachState(proc);
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns true when this instruction is a call instruction that destroys all caller-saved registers.
+     */
+    public final boolean hasCall() {
+        return this instanceof StandardOp.CallOp;
+    }
+
+    /**
+     * Iterates all register hints for the specified value, i.e., all preferred candidates for the register to be
+     * assigned to the value.
+     * <br>
+     * Subclasses can override this method. The default implementation processes all Input operands as the hints for
+     * an Output operand, and all Output operands as the hints for an Input operand.
+     *
+     * @param value The value the hints are needed for.
+     * @param mode The operand mode of the value.
+     * @param proc The procedure invoked for all the hints. If the procedure returns a non-null value, the iteration is stopped
+     *             and the value is returned by this method, i.e., clients can stop the iteration once a suitable hint has been found.
+     * @return The non-null value returned by the procedure, or null.
+     */
+    public CiValue forEachRegisterHint(CiValue value, OperandMode mode, ValueProcedure proc) {
+        CiValue[] hints;
+        if (mode == OperandMode.Input) {
+            hints = outputs;
+        } else if (mode == OperandMode.Output) {
+            hints = inputs;
+        } else {
+            return null;
+        }
+
+        for (int i = 0; i < hints.length; i++) {
+            CiValue result = proc.doValue(hints[i], null, null);
+            if (result != null) {
+                return result;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Used by the register allocator to decide which kind of location can be assigned to the operand.
+     * @param mode The kind of operand.
+     * @param index The index of the operand.
+     * @return The flags for the operand.
+     */
+    // TODO this method will go away when we have named operands, the flags will be specified as annotations instead.
+    protected abstract EnumSet<OperandFlag> flagsFor(OperandMode mode, int index);
+
+    protected void verify() {
+    }
+
+
+    public final String toStringWithIdPrefix() {
+        if (id != -1) {
+            return String.format("%4d %s", id, toString());
+        }
+        return "     " + toString();
+    }
+
+    /**
+     * Gets the operation performed by this instruction in terms of its operands as a string.
+     */
+    public String operationString() {
+        StringBuilder buf = new StringBuilder();
+        String sep = "";
+        if (outputs.length > 1) {
+            buf.append("(");
+        }
+        for (CiValue output : outputs) {
+            buf.append(sep).append(output);
+            sep = ", ";
+        }
+        if (outputs.length > 1) {
+            buf.append(")");
+        }
+        if (outputs.length > 0) {
+            buf.append(" = ");
+        }
+
+        if (inputs.length + alives.length != 1) {
+            buf.append("(");
+        }
+        sep = "";
+        for (CiValue input : inputs) {
+            buf.append(sep).append(input);
+            sep = ", ";
+        }
+        for (CiValue input : alives) {
+            buf.append(sep).append(input).append(" ~");
+            sep = ", ";
+        }
+        if (inputs.length + alives.length != 1) {
+            buf.append(")");
+        }
+
+        if (temps.length > 0) {
+            buf.append(" [");
+        }
+        sep = "";
+        for (CiValue temp : temps) {
+            buf.append(sep).append(temp);
+            sep = ", ";
+        }
+        if (temps.length > 0) {
+            buf.append("]");
+        }
+        return buf.toString();
+    }
+
+    protected void appendDebugInfo(StringBuilder buf) {
+        if (info != null) {
+            buf.append(" [bci:");
+            String sep = "";
+            for (CiFrame cur = info.topFrame; cur != null; cur = cur.caller()) {
+                buf.append(sep).append(cur.bci);
+                sep = ",";
+            }
+            buf.append("]");
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder(name()).append(' ').append(operationString());
+        appendDebugInfo(buf);
+        return buf.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LIRVerifier.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.lir;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.max.graal.lir.ValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.LIRInstruction.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+public final class LIRVerifier {
+    private final LIR lir;
+    private final FrameMap frameMap;
+
+    private final boolean beforeRegisterAllocation;
+
+    private final BitSet[] blockLiveOut;
+    private final Object[] variableDefinitions;
+
+    private BitSet liveOutFor(Block block) {
+        return blockLiveOut[block.getId()];
+    }
+    private void setLiveOutFor(Block block, BitSet liveOut) {
+        blockLiveOut[block.getId()] = liveOut;
+    }
+
+    private int maxRegisterNum() {
+        return frameMap.target.arch.registers.length;
+    }
+
+    private boolean isAllocatableRegister(CiValue value) {
+        return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+    }
+
+    public static boolean verify(final LIRInstruction op) {
+        ValueProcedure allowedProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return allowed(op, value, mode, flags); } };
+
+        op.forEachInput(allowedProc);
+        op.forEachAlive(allowedProc);
+        op.forEachState(allowedProc);
+        op.forEachTemp(allowedProc);
+        op.forEachOutput(allowedProc);
+
+        op.verify();
+        return true;
+    }
+
+    public static boolean verify(boolean beforeRegisterAllocation, LIR lir, FrameMap frameMap) {
+        LIRVerifier verifier = new LIRVerifier(beforeRegisterAllocation, lir, frameMap);
+        verifier.verify();
+        return true;
+    }
+
+
+    private LIRVerifier(boolean beforeRegisterAllocation, LIR lir, FrameMap frameMap) {
+        this.beforeRegisterAllocation = beforeRegisterAllocation;
+        this.lir = lir;
+        this.frameMap = frameMap;
+        this.blockLiveOut = new BitSet[lir.linearScanOrder().size()];
+        this.variableDefinitions = new Object[lir.numVariables()];
+    }
+
+    private BitSet curVariablesLive;
+    private CiValue[] curRegistersLive;
+
+    private Block curBlock;
+    private Object curInstruction;
+    private BitSet curRegistersDefined;
+
+    private void verify() {
+        ValueProcedure useProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return use(value, mode, flags); } };
+        ValueProcedure defProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return def(value, mode, flags); } };
+
+        curRegistersDefined = new BitSet();
+        for (Block block : lir.linearScanOrder()) {
+            curBlock = block;
+            curVariablesLive = new BitSet();
+            curRegistersLive = new CiValue[maxRegisterNum()];
+
+            if (block.getDominator() != null) {
+                curVariablesLive.or(liveOutFor(block.getDominator()));
+            }
+
+            assert block.lir.get(0) instanceof StandardOp.LabelOp : "block must start with label";
+            if (block.numberOfPreds() > 1) {
+                assert block.lir.get(0) instanceof StandardOp.PhiLabelOp : "phi mapping required for multiple predecessors";
+                CiValue[] phiDefinitions = ((StandardOp.PhiLabelOp) block.lir.get(0)).getPhiDefinitions();
+                if (!beforeRegisterAllocation) {
+                    assert phiDefinitions.length == 0;
+                }
+                for (Block pred : block.getPredecessors()) {
+                    assert pred.numberOfSux() == 1;
+                    LIRInstruction last = pred.lir.get(pred.lir.size() - 1);
+                    assert last instanceof StandardOp.PhiJumpOp : "phi mapping required for multiple successors";
+                    CiValue[] phiUses = ((StandardOp.PhiJumpOp) last).getPhiInputs();
+                    if (!beforeRegisterAllocation) {
+                        assert phiUses.length == 0;
+                    }
+                }
+            }
+
+            if (block.numberOfSux() > 0) {
+                LIRInstruction last = block.lir.get(block.lir.size() - 1);
+                assert last instanceof StandardOp.JumpOp || last instanceof LIRXirInstruction : "block with successor must end with unconditional jump";
+            }
+
+            for (LIRInstruction op : block.lir) {
+                curInstruction = op;
+
+                op.forEachInput(useProc);
+                if (op.hasCall()) {
+                    for (CiRegister register : frameMap.registerConfig.getCallerSaveRegisters()) {
+                        curRegistersLive[register.number] = null;
+                    }
+                }
+                curRegistersDefined.clear();
+                op.forEachAlive(useProc);
+                op.forEachState(useProc);
+                op.forEachTemp(defProc);
+                op.forEachOutput(defProc);
+
+                curInstruction = null;
+            }
+
+            setLiveOutFor(block, curVariablesLive);
+        }
+    }
+
+    private CiValue use(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+        allowed(curInstruction, value, mode, flags);
+
+        if (isVariable(value)) {
+            assert beforeRegisterAllocation;
+
+            int variableIdx = asVariable(value).index;
+            if (!curVariablesLive.get(variableIdx)) {
+                TTY.println("block %s  instruction %s", curBlock, curInstruction);
+                TTY.println("live variables: %s", curVariablesLive);
+                if (variableDefinitions[variableIdx] != null) {
+                    TTY.println("definition of %s: %s", value, variableDefinitions[variableIdx]);
+                }
+                TTY.println("ERROR: Use of variable %s that is not defined in dominator", value);
+                throw GraalInternalError.shouldNotReachHere();
+            }
+
+        } else if (isAllocatableRegister(value)) {
+            int regNum = asRegister(value).number;
+            if (mode == OperandMode.Alive) {
+                curRegistersDefined.set(regNum);
+            }
+
+            if (beforeRegisterAllocation && curRegistersLive[regNum] != value) {
+                TTY.println("block %s  instruction %s", curBlock, curInstruction);
+                TTY.println("live registers: %s", Arrays.toString(curRegistersLive));
+                TTY.println("ERROR: Use of fixed register %s that is not defined in this block", value);
+                throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+        return value;
+    }
+
+    private CiValue def(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+        allowed(curInstruction, value, mode, flags);
+
+        if (isVariable(value)) {
+            assert beforeRegisterAllocation;
+
+            int variableIdx = asVariable(value).index;
+            if (variableDefinitions[variableIdx] != null) {
+                TTY.println("block %s  instruction %s", curBlock, curInstruction);
+                TTY.println("live variables: %s", curVariablesLive);
+                TTY.println("definition of %s: %s", value, variableDefinitions[variableIdx]);
+                TTY.println("ERROR: Variable %s defined multiple times", value);
+                throw GraalInternalError.shouldNotReachHere();
+            }
+            assert curInstruction != null;
+            variableDefinitions[variableIdx] = curInstruction;
+            assert !curVariablesLive.get(variableIdx);
+            if (mode == OperandMode.Output) {
+                curVariablesLive.set(variableIdx);
+            }
+
+        } else if (isAllocatableRegister(value)) {
+            int regNum = asRegister(value).number;
+            if (curRegistersDefined.get(regNum)) {
+                TTY.println("block %s  instruction %s", curBlock, curInstruction);
+                TTY.println("ERROR: Same register defined twice in the same instruction: %s", value);
+                throw GraalInternalError.shouldNotReachHere();
+            }
+            curRegistersDefined.set(regNum);
+
+            if (beforeRegisterAllocation) {
+                if (mode == OperandMode.Output) {
+                    curRegistersLive[regNum] = value;
+                } else {
+                    curRegistersLive[regNum] = null;
+                }
+            }
+        }
+        return value;
+    }
+
+    private static CiValue allowed(Object op, CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+        if ((isVariable(value)  && flags.contains(OperandFlag.Register)) ||
+            (isRegister(value)  && flags.contains(OperandFlag.Register)) ||
+            (isStackSlot(value) && flags.contains(OperandFlag.Stack)) ||
+            (isConstant(value)  && flags.contains(OperandFlag.Constant) && mode != OperandMode.Output) ||
+            (isIllegal(value)   && flags.contains(OperandFlag.Illegal))) {
+            return value;
+        }
+        TTY.println("instruction %s", op);
+        TTY.println("mode: %s  flags: %s", mode, flags);
+        TTY.println("Unexpected value: %s %s", value.getClass().getSimpleName(), value);
+        throw GraalInternalError.shouldNotReachHere();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LIRXirInstruction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.lir;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.xir.*;
+import com.oracle.max.graal.graph.*;
+
+public abstract class LIRXirInstruction extends LIRInstruction {
+
+    public final CiValue[] originalOperands;
+    public final int outputOperandIndex;
+    public final int[] inputOperandIndices;
+    public final int[] tempOperandIndices;
+    public final XirSnippet snippet;
+    public final LIRDebugInfo infoAfter;
+    public final LabelRef trueSuccessor;
+    public final LabelRef falseSuccessor;
+
+    public LIRXirInstruction(Object opcode,
+                             XirSnippet snippet,
+                             CiValue[] originalOperands,
+                             CiValue outputOperand,
+                             CiValue[] inputs, CiValue[] temps,
+                             int[] inputOperandIndices, int[] tempOperandIndices,
+                             int outputOperandIndex,
+                             LIRDebugInfo info,
+                             LIRDebugInfo infoAfter,
+                             LabelRef trueSuccessor,
+                             LabelRef falseSuccessor) {
+        // Note that we register the XIR input operands as Alive, because the XIR specification allows that input operands
+        // are used at any time, even when the temp operands and the actual output operands have already be assigned.
+        super(opcode, isLegal(outputOperand) ? new CiValue[] {outputOperand} : LIRInstruction.NO_OPERANDS, info, LIRInstruction.NO_OPERANDS, inputs, temps);
+        this.infoAfter = infoAfter;
+        this.snippet = snippet;
+        this.inputOperandIndices = inputOperandIndices;
+        this.tempOperandIndices = tempOperandIndices;
+        this.outputOperandIndex = outputOperandIndex;
+        this.originalOperands = originalOperands;
+        this.falseSuccessor = falseSuccessor;
+        this.trueSuccessor = trueSuccessor;
+        assert isLegal(outputOperand) || outputOperandIndex == -1;
+    }
+
+    @Override
+    protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+        if (mode == OperandMode.Alive || mode == OperandMode.Temp) {
+            return EnumSet.of(OperandFlag.Register, OperandFlag.Constant, OperandFlag.Illegal);
+        } else if (mode == OperandMode.Output && index == 0) {
+            return EnumSet.of(OperandFlag.Register);
+        }
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public CiValue[] getOperands() {
+        for (int i = 0; i < inputOperandIndices.length; i++) {
+            originalOperands[inputOperandIndices[i]] = alive(i);
+        }
+        for (int i = 0; i < tempOperandIndices.length; i++) {
+            originalOperands[tempOperandIndices[i]] = temp(i);
+        }
+        if (outputOperandIndex != -1) {
+            originalOperands[outputOperandIndex] = output(0);
+        }
+        return originalOperands;
+    }
+
+    @Override
+    public String name() {
+        return "XIR: " + snippet.template;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/LabelRef.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.lir;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.graal.lir.cfg.*;
+
+/**
+ * LIR instructions such as JUMP and BRANCH need to reference their target {@link Block}. However,
+ * direct references are not possible since the control flow graph (and therefore successors lists) can
+ * be changed by optimizations - and fixing the instructions is error prone.
+ * Therefore, we only reference of block B from block A only via the tuple (A, successor-index-of-B), i.e.,
+ * indirectly by storing the index into the successor list of A.
+ * Note that therefore it is not allowed to reorder the successor list!
+ *
+ * Labels of out-of-line stubs can be referenced directly, therefore it is also possible to construct a
+ * LabelRef for a Label directly via {@link #forLabel}.
+ */
+public abstract class LabelRef {
+
+    public abstract Label label();
+
+    /**
+     * Returns a new reference to a statically defined label.
+     * @param label The label that is always returned.
+     * @return The newly created label reference.
+     */
+    public static LabelRef forLabel(final Label label) {
+       return new LabelRef() {
+           @Override
+           public Label label() {
+               return label;
+           }
+
+           @Override
+           public String toString() {
+               return label.toString();
+           }
+       };
+    }
+
+    /**
+     * Returns a new reference to a successor of the given block.
+     * This allows to reference the given successor even when the successor list
+     * is modified between the creation of the reference and the call to {@link #getLabel}.
+     * @param block The base block that contains the successor list.
+     * @param suxIndex The index of the successor.
+     * @return The newly created label reference.
+     */
+    public static LabelRef forSuccessor(final Block block, final int suxIndex) {
+        return new LabelRef() {
+            @Override
+            public Label label() {
+                return ((StandardOp.LabelOp) block.suxAt(suxIndex).lir.get(0)).getLabel();
+            }
+
+            @Override
+            public String toString() {
+                return suxIndex < block.numberOfSux() ? block.suxAt(suxIndex).toString() : "?" + block + ":" + suxIndex + "?";
+            }
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/StandardOp.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.lir;
+
+import java.util.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.asm.*;
+
+/**
+ * A collection of machine-independent LIR operations, as well as interfaces to be implemented for specific kinds or LIR
+ * operations.
+ */
+public class StandardOp {
+
+    private static CiValue[] EMPTY = new CiValue[0];
+
+    /**
+     * LIR operation that defines the position of a label.
+     * The first operation of every block must implement this interface.
+     */
+    public static class LabelOp extends LIRInstruction {
+        private final Label label;
+        private final boolean align;
+
+        protected LabelOp(Object opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps, Label label, boolean align) {
+            super(opcode, outputs, info, inputs, alives, temps);
+            this.label = label;
+            this.align = align;
+        }
+
+        public LabelOp(Label label, boolean align) {
+            this("LABEL", LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, label, align);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm) {
+            if (align) {
+                tasm.asm.align(tasm.target.wordSize);
+            }
+            tasm.asm.bind(label);
+        }
+
+        @Override
+        public String operationString() {
+            return label.toString() + " " + super.operationString();
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        public Label getLabel() {
+            return label;
+        }
+    }
+
+    public static class PhiLabelOp extends LabelOp {
+        public PhiLabelOp(Label label, boolean align, CiValue[] phiDefinitions) {
+            super("PHI_LABEL", phiDefinitions, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, label, align);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Output) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        public void markResolved() {
+            outputs = EMPTY;
+        }
+
+        public CiValue[] getPhiDefinitions() {
+            return outputs;
+        }
+    }
+
+    /**
+     * LIR operation that is an unconditional jump to {@link #destination()}.
+     * When the LIR is constructed, the last operation of every block must implement this interface. After
+     * register allocation, unnecessary jumps can be deleted.
+     *
+     * TODO Currently, a block can also end with an XIR operation.
+     */
+    public static class JumpOp extends LIRInstruction {
+        private final LabelRef destination;
+
+        protected JumpOp(Object opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps, LabelRef destination) {
+            super(opcode, outputs, info, inputs, alives, temps);
+            this.destination = destination;
+        }
+
+        public JumpOp(LabelRef destination, LIRDebugInfo info) {
+            this("JUMP", LIRInstruction.NO_OPERANDS, info, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, destination);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm) {
+            tasm.asm.jmp(destination.label());
+        }
+
+        @Override
+        public String operationString() {
+            return  destination + " " + super.operationString();
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        public LabelRef destination() {
+            return destination;
+        }
+    }
+
+    public static class PhiJumpOp extends JumpOp {
+        public PhiJumpOp(LabelRef destination, CiValue[] phiInputs) {
+            super("PHI_JUMP", LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, phiInputs, LIRInstruction.NO_OPERANDS, destination);
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Alive) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Constant);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        public void markResolved() {
+            alives = EMPTY;
+        }
+
+        public CiValue[] getPhiInputs() {
+            return alives;
+        }
+    }
+
+    /**
+     * Marker interface for a LIR operation that is a conditional jump to {@link #destination()}.
+     * Conditional jumps may be negated or optimized away after register allocation.
+     */
+    public interface BranchOp {
+        LabelRef destination();
+        void negate(LabelRef newDestination);
+    }
+
+    /**
+     * Marker interface for a LIR operation that moves a value from {@link #getInput()} to {@link #getResult()}.
+     */
+    public interface MoveOp {
+        CiValue getInput();
+        CiValue getResult();
+    }
+
+    /**
+     * Marker interface for a LIR operation that calls a method, i.e., destroys all caller-saved registers.
+     */
+    public interface CallOp {
+    }
+
+
+    /**
+     * Meta-operation that defines the incoming method parameters. In the LIR, every register and variable must be
+     * defined before it is used. This operation is the definition point of method parameters, but is otherwise a no-op.
+     * In particular, it is not the actual method prologue.
+     */
+    public static final class ParametersOp extends LIRInstruction {
+        public ParametersOp(CiValue[] params) {
+            super("PARAMS", params, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm) {
+            // No code to emit.
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Output) {
+                return EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/ValueUtil.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.lir;
+
+import com.oracle.max.cri.ci.*;
+
+public class ValueUtil extends CiValueUtil {
+
+    public static boolean isVariable(CiValue value) {
+        assert value != null;
+        return value instanceof Variable;
+    }
+
+    public static Variable asVariable(CiValue value) {
+        assert value != null;
+        return (Variable) value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/Variable.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2010, 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.max.graal.lir;
+
+import com.oracle.max.cri.ci.*;
+
+/**
+ * Represents a value that is yet to be bound to a machine location (such as
+ * a {@link CiRegisterValue} or {@link CiStackSlot}) by a register allocator.
+ */
+public final class Variable extends CiValue {
+    private static final long serialVersionUID = 4507578431686109809L;
+
+    /**
+     * The identifier of the variable. This is a non-zero index in a contiguous 0-based name space.
+     */
+    public final int index;
+
+    /**
+     * The type of register that this variable needs to get assigned.
+     */
+    public final CiRegister.RegisterFlag flag;
+
+    /**
+     * Creates a new variable.
+     * @param kind
+     * @param index
+     */
+    public Variable(CiKind kind, int index, CiRegister.RegisterFlag flag) {
+        super(kind);
+        assert kind == kind.stackKind() : "Variables can be only created for stack kinds";
+        assert index >= 0;
+        this.index = index;
+        this.flag = flag;
+    }
+
+    @Override
+    public int hashCode() {
+        return (index << 4) | kind.ordinal();
+    }
+
+    @Override
+    public String toString() {
+        return "v" + index + kindSuffix();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/asm/TargetMethodAssembler.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.lir.asm;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.LIR.*;
+
+public class TargetMethodAssembler {
+
+    private static class ExceptionInfo {
+        public final int codeOffset;
+        public final LabelRef exceptionEdge;
+
+        public ExceptionInfo(int pcOffset, LabelRef exceptionEdge) {
+            this.codeOffset = pcOffset;
+            this.exceptionEdge = exceptionEdge;
+        }
+    }
+
+    public final AbstractAssembler asm;
+    public final CiTargetMethod targetMethod;
+    public final CiTarget target;
+    public final RiRuntime runtime;
+    public final FrameMap frameMap;
+    public final List<SlowPath> slowPaths;
+
+    private List<ExceptionInfo> exceptionInfoList;
+    private int lastSafepointPos;
+
+    public TargetMethodAssembler(CiTarget target, RiRuntime runtime, FrameMap frameMap, List<SlowPath> slowPaths, AbstractAssembler asm) {
+        this.target = target;
+        this.runtime = runtime;
+        this.frameMap = frameMap;
+        this.slowPaths = slowPaths;
+        this.asm = asm;
+        this.targetMethod = new CiTargetMethod();
+        // 0 is a valid pc for safepoints in template methods
+        this.lastSafepointPos = -1;
+    }
+
+    public void setFrameSize(int frameSize) {
+        targetMethod.setFrameSize(frameSize);
+    }
+
+    public CiTargetMethod.Mark recordMark(Object id, CiTargetMethod.Mark[] references) {
+        return targetMethod.recordMark(asm.codeBuffer.position(), id, references);
+    }
+
+    public void blockComment(String s) {
+        targetMethod.addAnnotation(new CiTargetMethod.CodeComment(asm.codeBuffer.position(), s));
+    }
+
+    public CiTargetMethod finishTargetMethod(Object name, boolean isStub) {
+        // Install code, data and frame size
+        targetMethod.setTargetCode(asm.codeBuffer.close(false), asm.codeBuffer.position());
+
+        // Record exception handlers if they exist
+        if (exceptionInfoList != null) {
+            for (ExceptionInfo ei : exceptionInfoList) {
+                int codeOffset = ei.codeOffset;
+                targetMethod.recordExceptionHandler(codeOffset, ei.exceptionEdge.label().position());
+            }
+        }
+
+        Debug.metric("TargetMethods").increment();
+        Debug.metric("CodeBytesEmitted").add(targetMethod.targetCodeSize());
+        Debug.metric("SafepointsEmitted").add(targetMethod.safepoints.size());
+        Debug.metric("DataPatches").add(targetMethod.dataReferences.size());
+        Debug.metric("ExceptionHandlersEmitted").add(targetMethod.exceptionHandlers.size());
+
+        Debug.log("Finished target method %s, isStub %b", name, isStub);
+/*
+        if (GraalOptions.PrintAssembly && !TTY.isSuppressed() && !isStub) {
+            Util.printSection("Target Method", Util.SECTION_CHARACTER);
+            TTY.println("Name: " + name);
+            TTY.println("Frame size: " + targetMethod.frameSize());
+            TTY.println("Register size: " + asm.target.arch.registerReferenceMapBitCount);
+
+            if (GraalOptions.PrintCodeBytes) {
+                Util.printSection("Code", Util.SUB_SECTION_CHARACTER);
+                TTY.println("Code: %d bytes", targetMethod.targetCodeSize());
+                Util.printBytes(0L, targetMethod.targetCode(), 0, targetMethod.targetCodeSize(), GraalOptions.PrintAssemblyBytesPerLine);
+            }
+
+            Util.printSection("Disassembly", Util.SUB_SECTION_CHARACTER);
+            String disassembly = runtime.disassemble(targetMethod);
+            TTY.println(disassembly);
+            boolean noDis = disassembly == null || disassembly.length() == 0;
+
+            Util.printSection("Safepoints", Util.SUB_SECTION_CHARACTER);
+            for (CiTargetMethod.Safepoint x : targetMethod.safepoints) {
+                TTY.println(x.toString());
+                if (noDis && x.debugInfo != null) {
+                    TTY.println(CiUtil.indent(x.debugInfo.toString(), "  "));
+                }
+            }
+
+            Util.printSection("Data Patches", Util.SUB_SECTION_CHARACTER);
+            for (CiTargetMethod.DataPatch x : targetMethod.dataReferences) {
+                TTY.println(x.toString());
+            }
+
+            Util.printSection("Marks", Util.SUB_SECTION_CHARACTER);
+            for (CiTargetMethod.Mark x : targetMethod.marks) {
+                TTY.println(x.toString());
+            }
+
+            Util.printSection("Exception Handlers", Util.SUB_SECTION_CHARACTER);
+            for (CiTargetMethod.ExceptionHandler x : targetMethod.exceptionHandlers) {
+                TTY.println(x.toString());
+            }
+        }
+*/
+
+        return targetMethod;
+    }
+
+    public void recordExceptionHandlers(int pcOffset, LIRDebugInfo info) {
+        if (info != null) {
+            if (info.exceptionEdge != null) {
+                if (exceptionInfoList == null) {
+                    exceptionInfoList = new ArrayList<>(4);
+                }
+                exceptionInfoList.add(new ExceptionInfo(pcOffset, info.exceptionEdge));
+            }
+        }
+    }
+
+    public void recordImplicitException(int pcOffset, LIRDebugInfo info) {
+        // record an implicit exception point
+        if (info != null) {
+            assert lastSafepointPos < pcOffset : lastSafepointPos + "<" + pcOffset;
+            lastSafepointPos = pcOffset;
+            targetMethod.recordSafepoint(pcOffset, info.debugInfo());
+            assert info.exceptionEdge == null;
+        }
+    }
+
+    public void recordDirectCall(int posBefore, int posAfter, Object callTarget, LIRDebugInfo info) {
+        CiDebugInfo debugInfo = info != null ? info.debugInfo() : null;
+        assert lastSafepointPos < posAfter;
+        lastSafepointPos = posAfter;
+        targetMethod.recordCall(posBefore, posAfter - posBefore, callTarget, debugInfo, true);
+    }
+
+    public void recordIndirectCall(int posBefore, int posAfter, Object callTarget, LIRDebugInfo info) {
+        CiDebugInfo debugInfo = info != null ? info.debugInfo() : null;
+        assert lastSafepointPos < posAfter;
+        lastSafepointPos = posAfter;
+        targetMethod.recordCall(posBefore, posAfter - posBefore, callTarget, debugInfo, false);
+    }
+
+    public void recordSafepoint(int pos, LIRDebugInfo info) {
+        // safepoints always need debug info
+        CiDebugInfo debugInfo = info.debugInfo();
+        assert lastSafepointPos < pos;
+        lastSafepointPos = pos;
+        targetMethod.recordSafepoint(pos, debugInfo);
+    }
+
+    public CiAddress recordDataReferenceInCode(CiConstant data, int alignment) {
+        assert data != null;
+        int pos = asm.codeBuffer.position();
+        Debug.log("Data reference in code: pos = %d, data = %s", pos, data.toString());
+        targetMethod.recordDataReference(pos, data, alignment);
+        return CiAddress.Placeholder;
+    }
+
+    public int lastSafepointPos() {
+        return lastSafepointPos;
+    }
+
+
+    /**
+     * Returns the integer value of any constants that can be represented by a 32-bit integer value,
+     * including long constants that fit into the 32-bit range.
+     */
+    public int asIntConst(CiValue value) {
+        assert (value.kind.stackKind() == CiKind.Int || value.kind == CiKind.Jsr || value.kind == CiKind.Long) && isConstant(value);
+        long c = ((CiConstant) value).asLong();
+        if (!(NumUtil.isInt(c))) {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+        return (int) c;
+    }
+
+    /**
+     * Returns the address of a float constant that is embedded as a data references into the code.
+     */
+    public CiAddress asFloatConstRef(CiValue value) {
+        return asFloatConstRef(value, 4);
+    }
+
+    public CiAddress asFloatConstRef(CiValue value, int alignment) {
+        assert value.kind == CiKind.Float && isConstant(value);
+        return recordDataReferenceInCode((CiConstant) value, alignment);
+    }
+
+    /**
+     * Returns the address of a double constant that is embedded as a data references into the code.
+     */
+    public CiAddress asDoubleConstRef(CiValue value) {
+        return asDoubleConstRef(value, 8);
+    }
+
+    public CiAddress asDoubleConstRef(CiValue value, int alignment) {
+        assert value.kind == CiKind.Double && isConstant(value);
+        return recordDataReferenceInCode((CiConstant) value, alignment);
+    }
+
+    /**
+     * Returns the address of a long constant that is embedded as a data references into the code.
+     */
+    public CiAddress asLongConstRef(CiValue value) {
+        assert value.kind == CiKind.Long && isConstant(value);
+        return recordDataReferenceInCode((CiConstant) value, 8);
+    }
+
+    public CiAddress asIntAddr(CiValue value) {
+        assert value.kind == CiKind.Int;
+        return asAddress(value);
+    }
+
+    public CiAddress asLongAddr(CiValue value) {
+        assert value.kind == CiKind.Long;
+        return asAddress(value);
+    }
+
+    public CiAddress asObjectAddr(CiValue value) {
+        assert value.kind == CiKind.Object;
+        return asAddress(value);
+    }
+
+    public CiAddress asFloatAddr(CiValue value) {
+        assert value.kind == CiKind.Float;
+        return asAddress(value);
+    }
+
+    public CiAddress asDoubleAddr(CiValue value) {
+        assert value.kind == CiKind.Double;
+        return asAddress(value);
+    }
+
+    public CiAddress asAddress(CiValue value) {
+        if (isStackSlot(value)) {
+            CiStackSlot slot = (CiStackSlot) value;
+            return new CiAddress(slot.kind, frameMap.registerConfig.getFrameRegister().asValue(), frameMap.offsetForStackSlot(slot));
+        }
+        return (CiAddress) value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/cfg/Block.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.lir.cfg;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.java.*;
+
+public class Block {
+    protected int id;
+
+    protected BeginNode beginNode;
+    protected Node endNode;
+    protected Loop loop;
+    protected double probability;
+
+    protected List<Block> predecessors;
+    protected List<Block> successors;
+
+    protected Block dominator;
+    protected List<Block> dominated;
+    protected Block postdominator;
+
+    // Fields that still need to be worked on, try to remove them later.
+    public List<LIRInstruction> lir;
+    public boolean align;
+    public int linearScanNumber;
+
+    public Block() {
+        id = ControlFlowGraph.BLOCK_ID_INITIAL;
+    }
+
+    public int getId() {
+        assert id >= 0;
+        return id;
+    }
+
+    public BeginNode getBeginNode() {
+        return beginNode;
+    }
+
+    public Node getEndNode() {
+        return endNode;
+    }
+
+    public Loop getLoop() {
+        return loop;
+    }
+
+    public int getLoopDepth() {
+        return loop == null ? 0 : loop.depth;
+    }
+
+    public boolean isLoopHeader() {
+        return getBeginNode() instanceof LoopBeginNode;
+    }
+
+    public boolean isLoopEnd() {
+        return getEndNode() instanceof LoopEndNode;
+    }
+
+    public boolean isExceptionEntry() {
+        return getBeginNode().next() instanceof ExceptionObjectNode;
+    }
+
+    public List<Block> getPredecessors() {
+        return predecessors;
+    }
+
+    public List<Block> getSuccessors() {
+        return successors;
+    }
+
+    public Block getDominator() {
+        return dominator;
+    }
+
+    public Block getEarliestPostDominated() {
+        Block b = this;
+        while (true) {
+            Block dom = b.getDominator();
+            if (dom != null && dom.getPostdominator() == b) {
+                b = dom;
+            } else {
+                break;
+            }
+        }
+        return b;
+    }
+
+    public List<Block> getDominated() {
+        if (dominated == null) {
+            return Collections.emptyList();
+        }
+        return dominated;
+    }
+
+    public Block getPostdominator() {
+        return postdominator;
+    }
+
+    private class NodeIterator implements Iterator<Node> {
+        private Node cur;
+
+        public NodeIterator() {
+            cur = getBeginNode();
+        }
+
+        @Override
+        public boolean hasNext() {
+            return cur != null;
+        }
+
+        @Override
+        public Node next() {
+            Node result = cur;
+            if (cur == getEndNode()) {
+                cur = null;
+            } else {
+                cur = ((FixedWithNextNode) cur).next();
+            }
+            assert !(cur instanceof BeginNode);
+            return result;
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    public Iterable<Node> getNodes() {
+        return new Iterable<Node>() {
+            @Override
+            public Iterator<Node> iterator() {
+                return new NodeIterator();
+            }
+        };
+    }
+
+    public int getFirstLirInstructionId() {
+        int result = lir.get(0).id();
+        assert result >= 0;
+        return result;
+    }
+
+    public int getLastLirInstructionId() {
+        int result = lir.get(lir.size() - 1).id();
+        assert result >= 0;
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "B" + id;
+    }
+
+
+// to be inlined later on
+    public int numberOfPreds() {
+        return getPredecessors().size();
+    }
+
+    public int numberOfSux() {
+        return getSuccessors().size();
+    }
+
+    public Block predAt(int i) {
+        return getPredecessors().get(i);
+    }
+
+    public Block suxAt(int i) {
+        return getSuccessors().get(i);
+    }
+// end to be inlined later on
+
+    public boolean dominates(Block block) {
+        return block.isDominatedBy(this);
+    }
+
+    public boolean isDominatedBy(Block block) {
+        if (block == this) {
+            return true;
+        }
+        if (dominator == null) {
+            return false;
+        }
+        return dominator.isDominatedBy(block);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/cfg/BlockMap.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012, 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.max.graal.lir.cfg;
+
+public class BlockMap<T> {
+    private final T[] data;
+
+    @SuppressWarnings("unchecked")
+    public BlockMap(ControlFlowGraph cfg) {
+        data = (T[]) new Object[cfg.getBlocks().length];
+    }
+
+    public T get(Block block) {
+        return data[block.getId()];
+    }
+
+    public void put(Block block, T value) {
+        data[block.getId()] = value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/cfg/CFGVerifier.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2012, 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.max.graal.lir.cfg;
+
+public class CFGVerifier {
+    public static boolean verify(ControlFlowGraph cfg) {
+        for (Block block : cfg.getBlocks()) {
+            assert cfg.getBlocks()[block.getId()] == block;
+
+            for (Block pred : block.getPredecessors()) {
+                assert pred.getSuccessors().contains(block);
+                assert pred.getId() < block.getId() || pred.isLoopEnd();
+            }
+
+            for (Block sux : block.getSuccessors()) {
+                assert sux.getPredecessors().contains(block);
+                assert sux.getId() > block.getId() || sux.isLoopHeader();
+            }
+
+            if (block.getDominator() != null) {
+                assert block.getDominator().getId() < block.getId();
+                assert block.getDominator().getDominated().contains(block);
+            }
+            for (Block dominated : block.getDominated()) {
+                assert dominated.getId() > block.getId();
+                assert dominated.getDominator() == block;
+            }
+
+            assert cfg.getLoops() == null || !block.isLoopHeader() || block.getLoop().header == block;
+        }
+
+        if (cfg.getLoops() != null) {
+            for (Loop loop : cfg.getLoops()) {
+                assert loop.header.isLoopHeader();
+
+                for (Block block : loop.blocks) {
+                    assert block.getId() >= loop.header.getId();
+
+                    Loop blockLoop = block.getLoop();
+                    while (blockLoop != loop) {
+                        blockLoop = blockLoop.parent;
+                        assert blockLoop != null;
+                    }
+                }
+
+                for (Block block : loop.exits) {
+                    assert block.getId() >= loop.header.getId();
+
+                    Loop blockLoop = block.getLoop();
+                    while (blockLoop != null) {
+                        blockLoop = blockLoop.parent;
+                        assert blockLoop != loop;
+                    }
+                }
+            }
+        }
+
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/cfg/ControlFlowGraph.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.lir.cfg;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+
+public class ControlFlowGraph {
+
+    public final StructuredGraph graph;
+
+    private final NodeMap<Block> nodeToBlock;
+    private Block[] reversePostOrder;
+    private Loop[] loops;
+
+    public static ControlFlowGraph compute(StructuredGraph graph, boolean connectBlocks, boolean computeLoops, boolean computeDominators, boolean computePostdominators) {
+        ControlFlowGraph cfg = new ControlFlowGraph(graph);
+        cfg.identifyBlocks();
+        if (connectBlocks || computeLoops || computeDominators || computePostdominators) {
+            cfg.connectBlocks();
+        }
+        if (computeLoops) {
+            cfg.computeLoopInformation();
+        }
+        if (computeDominators) {
+            cfg.computeDominators();
+        }
+        if (computePostdominators) {
+            cfg.computePostdominators();
+        }
+        assert CFGVerifier.verify(cfg);
+        return cfg;
+    }
+
+    protected ControlFlowGraph(StructuredGraph graph) {
+        this.graph = graph;
+        this.nodeToBlock = graph.createNodeMap();
+    }
+
+    public Block[] getBlocks() {
+        return reversePostOrder;
+    }
+
+    public Block getStartBlock() {
+        return reversePostOrder[0];
+    }
+
+    public NodeMap<Block> getNodeToBlock() {
+        return nodeToBlock;
+    }
+
+    public Block blockFor(Node node) {
+        return nodeToBlock.get(node);
+    }
+
+    public Loop[] getLoops() {
+        return loops;
+    }
+
+    protected static final int BLOCK_ID_INITIAL = -1;
+    protected static final int BLOCK_ID_VISITED = -2;
+
+    private void identifyBlocks() {
+        // Find all block headers
+        int numBlocks = 0;
+        for (Node node : graph.getNodes()) {
+            if (node instanceof BeginNode) {
+                Block block = new Block();
+                numBlocks++;
+
+                block.beginNode = (BeginNode) node;
+                Node cur = node;
+                do {
+                    assert !cur.isDeleted();
+                    block.endNode = cur;
+
+                    assert nodeToBlock.get(cur) == null;
+                    nodeToBlock.set(cur, block);
+                    if (cur instanceof MergeNode) {
+                        for (PhiNode phi : ((MergeNode) cur).phis()) {
+                            nodeToBlock.set(phi, block);
+                        }
+                    }
+
+                    if (cur instanceof FixedNode) {
+                        double probability = ((FixedNode) cur).probability();
+                        if (probability > block.probability) {
+                            block.probability = probability;
+                        }
+                    }
+
+                    Node next = null;
+                    for (Node sux : cur.successors()) {
+                        if (sux != null && !(sux instanceof BeginNode)) {
+                            assert next == null;
+                            next = sux;
+                        }
+                    }
+                    cur = next;
+                } while (cur != null);
+            }
+        }
+
+        // Compute reverse postorder.
+        reversePostOrder = new Block[numBlocks];
+        int reversePostOrderId = numBlocks - 1;
+
+        ArrayList<Block> stack = new ArrayList<>();
+        stack.add(blockFor(graph.start()));
+
+        do {
+            Block block = stack.get(stack.size() - 1);
+            if (block.id == BLOCK_ID_INITIAL) {
+                // First time we see this block: push all successors.
+                for (Node suxNode : block.getEndNode().cfgSuccessors()) {
+                    Block suxBlock = blockFor(suxNode);
+                    assert suxBlock.id != BLOCK_ID_VISITED : "Sux already visited?? from " + block.getEndNode() + " to " + suxNode;
+                    if (suxBlock.id == BLOCK_ID_INITIAL) {
+                        stack.add(suxBlock);
+                    }
+                }
+                block.id = BLOCK_ID_VISITED;
+            } else if (block.id == BLOCK_ID_VISITED) {
+                // Second time we see this block: All successors haved been processed, so insert block into reverse postorder list.
+                stack.remove(stack.size() - 1);
+                reversePostOrder[reversePostOrderId] = block;
+                block.id = reversePostOrderId;
+                reversePostOrderId--;
+            } else {
+                throw GraalInternalError.shouldNotReachHere();
+            }
+        } while (!stack.isEmpty());
+        assert reversePostOrderId == -1;
+    }
+
+    // Connect blocks (including loop backward edges).
+    private void connectBlocks() {
+        for (Block block : reversePostOrder) {
+            List<Block> predecessors = new ArrayList<>();
+            for (Node predNode : block.getBeginNode().cfgPredecessors()) {
+                predecessors.add(nodeToBlock.get(predNode));
+            }
+            if (block.getBeginNode() instanceof LoopBeginNode) {
+                for (LoopEndNode predNode : ((LoopBeginNode) block.getBeginNode()).orderedLoopEnds()) {
+                    predecessors.add(nodeToBlock.get(predNode));
+                }
+            }
+            block.predecessors = predecessors;
+
+            List<Block> successors = new ArrayList<>();
+            for (Node suxNode : block.getEndNode().cfgSuccessors()) {
+                successors.add(nodeToBlock.get(suxNode));
+            }
+            if (block.getEndNode() instanceof LoopEndNode) {
+                successors.add(nodeToBlock.get(((LoopEndNode) block.getEndNode()).loopBegin()));
+            }
+            block.successors = successors;
+        }
+    }
+
+    private void computeLoopInformation() {
+        List<Loop> loopsList = new ArrayList<>();
+        for (Block block : reversePostOrder) {
+            Node beginNode = block.getBeginNode();
+            if (beginNode instanceof LoopBeginNode) {
+                Loop loop = new Loop(block.getLoop(), loopsList.size(), block);
+                loopsList.add(loop);
+
+                for (LoopEndNode end : ((LoopBeginNode) beginNode).loopEnds()) {
+                    Block endBlock = nodeToBlock.get(end);
+                    computeLoopBlocks(endBlock, loop);
+                }
+            }
+        }
+        loops = loopsList.toArray(new Loop[loopsList.size()]);
+
+        for (Loop loop : loops) {
+            for (Block block : loop.blocks) {
+                for (Block sux : block.getSuccessors()) {
+                    if (sux.getLoopDepth() < loop.depth) {
+                        loop.exits.add(sux);
+                    }
+                }
+            }
+        }
+    }
+
+    private void computeLoopBlocks(Block block, Loop loop) {
+        if (block.getLoop() == loop) {
+            return;
+        }
+        assert block.loop == loop.parent;
+        block.loop = loop;
+
+        assert !loop.blocks.contains(block);
+        loop.blocks.add(block);
+
+        if (block != loop.header) {
+            for (Block pred : block.getPredecessors()) {
+                computeLoopBlocks(pred, loop);
+            }
+        }
+    }
+
+    private void computeDominators() {
+        assert reversePostOrder[0].getPredecessors().size() == 0 : "start block has no predecessor and therefore no dominator";
+        for (int i = 1; i < reversePostOrder.length; i++) {
+            Block block = reversePostOrder[i];
+            List<Block> predecessors = block.getPredecessors();
+            assert predecessors.size() > 0;
+
+            Block dominator = predecessors.get(0);
+            for (int j = 1; j < predecessors.size(); j++) {
+                Block pred = predecessors.get(j);
+                if (!pred.isLoopEnd()) {
+                    dominator = commonDominator(dominator, pred);
+                }
+            }
+            setDominator(block, dominator);
+        }
+    }
+
+    private static void setDominator(Block block, Block dominator) {
+        block.dominator = dominator;
+        if (dominator.dominated == null) {
+            dominator.dominated = new ArrayList<>();
+        }
+        dominator.dominated.add(block);
+    }
+
+    public static Block commonDominator(Block a, Block b) {
+        Block iterA = a;
+        Block iterB = b;
+        while (iterA != iterB) {
+            if (iterA.getId() > iterB.getId()) {
+                iterA = iterA.getDominator();
+            } else {
+                assert iterB.getId() > iterA.getId();
+                iterB = iterB.getDominator();
+            }
+        }
+        return iterA;
+    }
+
+    private void computePostdominators() {
+        for (Block block : reversePostOrder) {
+            if (block.isLoopEnd()) {
+                // We do not want the loop header registered as the postdominator of the loop end.
+                continue;
+            }
+            Block postdominator = null;
+            for (Block sux : block.getSuccessors()) {
+                if (sux.isExceptionEntry()) {
+                    // We ignore exception handlers.
+                } else if (postdominator == null) {
+                    postdominator = sux;
+                } else {
+                    postdominator = commonPostdominator(postdominator, sux);
+                }
+            }
+            block.postdominator = postdominator;
+        }
+    }
+
+    private static Block commonPostdominator(Block a, Block b) {
+        Block iterA = a;
+        Block iterB = b;
+        while (iterA != iterB) {
+            if (iterA.getId() < iterB.getId()) {
+                iterA = iterA.getPostdominator();
+                if (iterA == null) {
+                    return null;
+                }
+            } else {
+                assert iterB.getId() < iterA.getId();
+                iterB = iterB.getPostdominator();
+                if (iterB == null) {
+                    return null;
+                }
+            }
+        }
+        return iterA;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/cfg/Loop.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, 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.max.graal.lir.cfg;
+
+import java.util.*;
+
+public class Loop {
+    public final Loop parent;
+    public final List<Loop> children;
+
+    public final int depth;
+    public final int index;
+    public final Block header;
+    public final List<Block> blocks;
+    public final List<Block> exits;
+
+    protected Loop(Loop parent, int index, Block header) {
+        this.parent = parent;
+        if (parent != null) {
+            this.depth = parent.depth + 1;
+            parent.children.add(this);
+        } else {
+            this.depth = 1;
+        }
+        this.index = index;
+        this.header = header;
+        this.blocks = new ArrayList<>();
+        this.children = new ArrayList<>();
+        this.exits = new ArrayList<>();
+    }
+
+    @Override
+    public String toString() {
+        return "loop " + index + " depth " + depth + (parent != null ? " outer " + parent.index : "");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/cri/CiLoweringTool.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.cri;
+
+import com.oracle.max.graal.graph.*;
+
+public interface CiLoweringTool {
+    GraalRuntime getRuntime();
+    Node getGuardAnchor();
+    Node createGuard(Node condition);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/cri/GraalRuntime.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.cri;
+
+import java.util.*;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+
+/**
+ * Graal-specific extensions for the runtime interface that must be implemented by the VM.
+ */
+public interface GraalRuntime extends RiRuntime {
+
+    void lower(Node n, CiLoweringTool tool);
+
+    StructuredGraph intrinsicGraph(RiResolvedMethod caller, int bci, RiResolvedMethod method, List<? extends Node> parameters);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/AbstractStateSplit.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes;
+
+import java.util.*;
+
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code AbstractStateSplit} class is the abstract base class of all instructions
+ * that store an immutable copy of the frame state.
+ */
+public abstract class AbstractStateSplit extends FixedWithNextNode implements StateSplit {
+
+    @Input(notDataflow = true) private FrameState stateAfter;
+
+    @Override
+    public FrameState stateAfter() {
+        return stateAfter;
+    }
+
+    @Override
+    public void setStateAfter(FrameState x) {
+        assert x == null || x.isAlive() : "frame state must be in a graph";
+        updateUsages(stateAfter, x);
+        stateAfter = x;
+    }
+
+    /**
+     * Creates a new state split with the specified value type.
+     * @param kind the type of the value that this instruction produces
+     */
+    public AbstractStateSplit(Stamp stamp) {
+        super(stamp);
+    }
+
+    @Override
+    public boolean needsStateAfter() {
+        return true;
+    }
+
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> debugProperties = super.getDebugProperties();
+        if (stateAfter() != null) {
+            debugProperties.put("stateAfter", stateAfter().toString(Verbosity.Debugger));
+        }
+        return debugProperties;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/AnchorNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code AnchorNode} can be used a lower bound for a Guard. It can also be used as an upper bound if no other FixedNode can be used for that purpose.
+ */
+public final class AnchorNode extends FixedWithNextNode implements LIRLowerable, Canonicalizable {
+
+    @Input(notDataflow = true) private final NodeInputList<GuardNode> guards = new NodeInputList<>(this);
+
+    public AnchorNode() {
+        super(StampFactory.illegal());
+    }
+
+    public void addGuard(GuardNode x) {
+        guards.add(x);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (this.usages().size() == 0 && guards.size() == 0) {
+            return null;
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        // TODO is it necessary to do something for the "guards" list here?
+        // Currently, there is nothing to emit since anchors are only a structural element with no execution semantics.
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/BeginNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,101 @@
+/*
+ * 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.max.graal.nodes;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.graph.iterators.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public class BeginNode extends AbstractStateSplit implements LIRLowerable, Simplifiable, Node.IterableNodeType {
+    public BeginNode() {
+        super(StampFactory.illegal());
+    }
+
+    public static BeginNode begin(FixedNode with) {
+        if (with instanceof BeginNode) {
+            return (BeginNode) with;
+        }
+        BeginNode begin =  with.graph().add(new BeginNode());
+        begin.setNext(with);
+        return begin;
+    }
+
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> debugProperties = super.getDebugProperties();
+        debugProperties.put("shortName", "B");
+        return debugProperties;
+    }
+
+    @Override
+    public void simplify(SimplifierTool tool) {
+        FixedNode prev = (FixedNode) this.predecessor();
+        if (prev == null) {
+            // This is the start node.
+        } else if (prev instanceof ControlSplitNode) {
+            // This begin node is necessary.
+        } else {
+            // This begin node can be removed and all guards moved up to the preceding begin node.
+            if (!usages().isEmpty()) {
+                Node prevBegin = prev;
+                while (!(prevBegin instanceof BeginNode)) {
+                    prevBegin = prevBegin.predecessor();
+                }
+                for (Node usage : usages()) {
+                    tool.addToWorkList(usage);
+                }
+                replaceAtUsages(prevBegin);
+            }
+            ((StructuredGraph) graph()).removeFixed(this);
+        }
+    }
+
+    public void evacuateGuards() {
+        if (!usages().isEmpty()) {
+            Node prevBegin = predecessor();
+            assert prevBegin != null;
+            while (!(prevBegin instanceof BeginNode)) {
+                prevBegin = prevBegin.predecessor();
+            }
+            replaceAtUsages(prevBegin);
+        }
+    }
+
+    @Override
+    public boolean verify() {
+        assertTrue(predecessor() != null || this == ((StructuredGraph) graph()).start() || this instanceof MergeNode, "begin nodes must be connected");
+        return super.verify();
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        // nop
+    }
+
+    public NodeIterable<GuardNode> guards() {
+        return usages().filter(GuardNode.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/BooleanNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,36 @@
+/*
+ * 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.max.graal.nodes;
+
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.type.*;
+
+
+public abstract class BooleanNode extends FloatingNode {
+
+    public BooleanNode(Stamp stamp) {
+        super(stamp);
+    }
+
+    public abstract BooleanNode negate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/CallTargetNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * 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.max.graal.nodes;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public abstract class CallTargetNode extends ValueNode implements LIRLowerable {
+    @Input protected final NodeInputList<ValueNode> arguments;
+
+    public CallTargetNode(ValueNode[] arguments) {
+        super(StampFactory.illegal());
+        this.arguments = new NodeInputList<>(this, arguments);
+    }
+
+    public NodeInputList<ValueNode> arguments() {
+        return arguments;
+    }
+
+    public abstract RiType returnType();
+
+    public abstract CiKind returnKind();
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        //nop
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/ConstantNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.graph.iterators.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code ConstantNode} represents a constant such as an integer value,
+ * long, float, object reference, address, etc.
+ */
+@NodeInfo(shortName = "Const")
+public class ConstantNode extends BooleanNode implements LIRLowerable {
+
+    @Data public final CiConstant value;
+
+    protected ConstantNode(CiConstant value) {
+        this(value, null);
+    }
+
+    /**
+     * Constructs a new ConstantNode representing the specified constant.
+     * @param value the constant
+     */
+    protected ConstantNode(CiConstant value, RiRuntime runtime) {
+        super(StampFactory.forConstant(value, runtime));
+        this.value = value;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        if (gen.canInlineConstant(value) || onlyUsedInFrameState()) {
+            gen.setResult(this, value);
+        } else {
+            gen.setResult(this, gen.emitMove(value));
+        }
+    }
+
+    private boolean onlyUsedInFrameState() {
+        return usages().filter(NodePredicates.isNotA(FrameState.class)).isEmpty();
+    }
+
+    public static ConstantNode forCiConstant(CiConstant constant, RiRuntime runtime, Graph graph) {
+        return graph.unique(new ConstantNode(constant, runtime));
+    }
+
+    /**
+     * Returns a node for a double constant.
+     * @param d the double value for which to create the instruction
+     * @param graph
+     * @return a node for a double constant
+     */
+    public static ConstantNode forDouble(double d, Graph graph) {
+        return graph.unique(new ConstantNode(CiConstant.forDouble(d)));
+    }
+
+    /**
+     * Returns a node for a float constant.
+     * @param f the float value for which to create the instruction
+     * @param graph
+     * @return a node for a float constant
+     */
+    public static ConstantNode forFloat(float f, Graph graph) {
+        return graph.unique(new ConstantNode(CiConstant.forFloat(f)));
+    }
+
+    /**
+     * Returns a node for an long constant.
+     * @param i the long value for which to create the instruction
+     * @param graph
+     * @return a node for an long constant
+     */
+    public static ConstantNode forLong(long i, Graph graph) {
+        return graph.unique(new ConstantNode(CiConstant.forLong(i)));
+    }
+
+    /**
+     * Returns a node for an integer constant.
+     * @param i the integer value for which to create the instruction
+     * @param graph
+     * @return a node for an integer constant
+     */
+    public static ConstantNode forInt(int i, Graph graph) {
+        return graph.unique(new ConstantNode(CiConstant.forInt(i)));
+    }
+
+    /**
+     * Returns a node for a boolean constant.
+     * @param i the boolean value for which to create the instruction
+     * @param graph
+     * @return a node representing the boolean
+     */
+    public static ConstantNode forBoolean(boolean i, Graph graph) {
+        return graph.unique(new ConstantNode(CiConstant.forBoolean(i)));
+    }
+
+    /**
+     * Returns a node for a byte constant.
+     * @param i the byte value for which to create the instruction
+     * @param graph
+     * @return a node representing the byte
+     */
+    public static ConstantNode forByte(byte i, Graph graph) {
+        return graph.unique(new ConstantNode(CiConstant.forByte(i)));
+    }
+
+    /**
+     * Returns a node for a char constant.
+     * @param i the char value for which to create the instruction
+     * @param graph
+     * @return a node representing the char
+     */
+    public static ConstantNode forChar(char i, Graph graph) {
+        return graph.unique(new ConstantNode(CiConstant.forChar(i)));
+    }
+
+    /**
+     * Returns a node for a short constant.
+     * @param i the short value for which to create the instruction
+     * @param graph
+     * @return a node representing the short
+     */
+    public static ConstantNode forShort(short i, Graph graph) {
+        return graph.unique(new ConstantNode(CiConstant.forShort(i)));
+    }
+
+    /**
+     * Returns a node for an address (jsr/ret address) constant.
+     * @param i the address value for which to create the instruction
+     * @param graph
+     * @return a node representing the address
+     */
+    public static ConstantNode forJsr(int i, Graph graph) {
+        return graph.unique(new ConstantNode(CiConstant.forJsr(i)));
+    }
+
+    /**
+     * Returns a node for an object constant.
+     * @param o the object value for which to create the instruction
+     * @param graph
+     * @return a node representing the object
+     */
+    public static ConstantNode forObject(Object o, RiRuntime runtime, Graph graph) {
+        return graph.unique(new ConstantNode(CiConstant.forObject(o), runtime));
+    }
+
+    public static ConstantNode forIntegerKind(CiKind kind, long value, Graph graph) {
+        switch (kind) {
+            case Byte:
+            case Short:
+            case Int:
+                return ConstantNode.forInt((int) value, graph);
+            case Long:
+                return ConstantNode.forLong(value, graph);
+            default:
+                throw new InternalError("Should not reach here");
+        }
+    }
+
+    public static ConstantNode forFloatingKind(CiKind kind, double value, Graph graph) {
+        switch (kind) {
+            case Float:
+                return ConstantNode.forFloat((float) value, graph);
+            case Double:
+                return ConstantNode.forDouble(value, graph);
+            default:
+                throw new InternalError("Should not reach here");
+        }
+    }
+
+    public static ConstantNode defaultForKind(CiKind kind, Graph graph) {
+        switch(kind) {
+            case Boolean:
+                return ConstantNode.forBoolean(false, graph);
+            case Byte:
+            case Char:
+            case Short:
+            case Int:
+                return ConstantNode.forInt(0, graph);
+            case Double:
+                return ConstantNode.forDouble(0.0, graph);
+            case Float:
+                return ConstantNode.forFloat(0.0f, graph);
+            case Long:
+                return ConstantNode.forLong(0L, graph);
+            case Object:
+                return ConstantNode.forObject(null, null, graph);
+            default:
+                return null;
+        }
+    }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Name) {
+            return super.toString(Verbosity.Name) + "(" + value.kind.format(value.boxedValue()) + ")";
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+
+    @Override
+    public BooleanNode negate() {
+        return ConstantNode.forBoolean(!value.asBoolean(), graph());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/ControlSplitNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code ControlSplitNode} is a base class for all instructions that split the control flow (ie. have more than one successor).
+ */
+public abstract class ControlSplitNode extends FixedNode {
+
+    @Successor private final NodeSuccessorList<BeginNode> blockSuccessors;
+
+    public BeginNode blockSuccessor(int index) {
+        return blockSuccessors.get(index);
+    }
+
+    public void setBlockSuccessor(int index, BeginNode x) {
+        blockSuccessors.set(index, x);
+    }
+
+    public int blockSuccessorCount() {
+        return blockSuccessors.size();
+    }
+
+    protected final double[] branchProbability;
+
+    public ControlSplitNode(Stamp stamp, BeginNode[] blockSuccessors, double[] branchProbability) {
+        super(stamp);
+        assert branchProbability.length == blockSuccessors.length;
+        this.blockSuccessors = new NodeSuccessorList<>(this, blockSuccessors);
+        this.branchProbability = branchProbability;
+    }
+
+    public double probability(int successorIndex) {
+        return branchProbability[successorIndex];
+    }
+
+    public void setProbability(int successorIndex, double x) {
+        branchProbability[successorIndex] = x;
+    }
+
+    /**
+     * Gets the successor corresponding to the default (fall through) case.
+     * @return the default successor
+     */
+    public FixedNode defaultSuccessor() {
+        return blockSuccessor(blockSuccessorCount() - 1);
+    }
+
+    public Iterable<BeginNode> blockSuccessors() {
+        return new Iterable<BeginNode>() {
+            @Override
+            public Iterator<BeginNode> iterator() {
+                return new Iterator<BeginNode>() {
+                    int i = 0;
+                    @Override
+                    public void remove() {
+                        throw new UnsupportedOperationException();
+                    }
+                    @Override
+                    public BeginNode next() {
+                        return ControlSplitNode.this.blockSuccessor(i++);
+                    }
+
+                    @Override
+                    public boolean hasNext() {
+                        return i < ControlSplitNode.this.blockSuccessorCount();
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> properties = super.getDebugProperties();
+        StringBuilder str = new StringBuilder();
+        for (int i = 0; i < branchProbability.length; i++) {
+            str.append(i == 0 ? "" : ", ").append(String.format(Locale.ENGLISH, "%7.5f", branchProbability[i]));
+        }
+        properties.put("branchProbability", str.toString());
+        return properties;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/DeoptimizeNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+@NodeInfo(shortName = "Deopt")
+public class DeoptimizeNode extends FixedNode implements Node.IterableNodeType, LIRLowerable {
+
+    public static enum DeoptAction {
+        None,                           // just interpret, do not invalidate nmethod
+        Recompile,                      // recompile the nmethod; need not invalidate
+        InvalidateReprofile,            // invalidate the nmethod, reset IC, maybe recompile
+        InvalidateRecompile,            // invalidate the nmethod, recompile (probably)
+        InvalidateStopCompiling,        // invalidate the nmethod and do not compile
+    }
+
+    @Data private String message;
+    @Data private final DeoptAction action;
+
+    public DeoptimizeNode() {
+        this(DeoptAction.InvalidateReprofile);
+    }
+
+    public DeoptimizeNode(DeoptAction action) {
+        super(StampFactory.illegal());
+        this.action = action;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public String message() {
+        return message;
+    }
+
+    public DeoptAction action() {
+        return action;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.emitDeoptimizeOn(null, action, message);
+    }
+
+    @NodeIntrinsic
+    public static void deopt() {
+        throw new UnsupportedOperationException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/EndNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * 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.max.graal.nodes;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public class EndNode extends FixedNode implements Node.IterableNodeType, LIRLowerable {
+
+    public EndNode() {
+        super(StampFactory.illegal());
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitEndNode(this);
+    }
+
+    public MergeNode merge() {
+        return (MergeNode) usages().first();
+    }
+
+    @Override
+    public boolean verify() {
+        assertTrue(usages().size() <= 1, "at most one usage");
+        return super.verify();
+    }
+
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> debugProperties = super.getDebugProperties();
+        debugProperties.put("shortName", "E");
+        return debugProperties;
+    }
+
+    @Override
+    public Iterable< ? extends Node> cfgSuccessors() {
+        return Arrays.asList(merge());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FixedGuardNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,85 @@
+/*
+ * 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.max.graal.nodes;
+
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public final class FixedGuardNode extends FixedWithNextNode implements Simplifiable, Lowerable, LIRLowerable {
+
+    @Input private final NodeInputList<BooleanNode> conditions;
+
+    public FixedGuardNode(BooleanNode condition) {
+        super(StampFactory.illegal());
+        this.conditions = new NodeInputList<>(this, new BooleanNode[] {condition});
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        for (BooleanNode condition : conditions()) {
+            gen.emitGuardCheck(condition);
+        }
+    }
+
+    public void addCondition(BooleanNode x) {
+        conditions.add(x);
+    }
+
+    public NodeInputList<BooleanNode> conditions() {
+        return conditions;
+    }
+
+    @Override
+    public void simplify(SimplifierTool tool) {
+        for (BooleanNode n : conditions.snapshot()) {
+            if (n instanceof ConstantNode) {
+                ConstantNode c = (ConstantNode) n;
+                if (c.asConstant().asBoolean()) {
+                    conditions.remove(n);
+                } else {
+                    FixedNode next = this.next();
+                    if (next != null) {
+                        tool.deleteBranch(next);
+                    }
+                    setNext(graph().add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
+                    return;
+                }
+            }
+        }
+        if (conditions.isEmpty()) {
+            ((StructuredGraph) graph()).removeFixed(this);
+        }
+    }
+
+    @Override
+    public void lower(CiLoweringTool tool) {
+        AnchorNode newAnchor = graph().add(new AnchorNode());
+        for (BooleanNode b : conditions) {
+            newAnchor.addGuard((GuardNode) tool.createGuard(b));
+        }
+        ((StructuredGraph) graph()).replaceFixedWithFixed(this, newAnchor);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FixedNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * 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.max.graal.nodes;
+
+import java.util.*;
+
+import com.oracle.max.graal.nodes.type.*;
+
+public abstract class FixedNode extends ValueNode {
+
+    private double probability;
+
+    public FixedNode(Stamp stamp) {
+        super(stamp);
+    }
+
+    public double probability() {
+        return probability;
+    }
+
+    public void setProbability(double probability) {
+        this.probability = probability;
+    }
+
+    protected void copyInto(FixedNode newNode) {
+        newNode.setProbability(probability);
+    }
+
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> properties = super.getDebugProperties();
+        properties.put("probability", String.format(Locale.ENGLISH, "%7.5f", probability));
+        return properties;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FixedWithNextNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes;
+
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * Base class of all nodes that are fixed within the control flow graph and have an immediate successor.
+ */
+public abstract class FixedWithNextNode extends FixedNode {
+
+    public FixedNode next() {
+        assert scheduledNext() == null || scheduledNext() instanceof FixedNode : "next() cannot be used while the graph is scheduled";
+        return (FixedNode) scheduledNext();
+    }
+
+    public void setNext(FixedNode x) {
+        setScheduledNext(x);
+    }
+
+    public FixedWithNextNode(Stamp stamp) {
+        super(stamp);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FrameState.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,640 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.nodes;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.graph.iterators.*;
+import com.oracle.max.graal.nodes.PhiNode.PhiType;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.virtual.*;
+
+/**
+ * The {@code FrameState} class encapsulates the frame state (i.e. local variables and
+ * operand stack) at a particular point in the abstract interpretation.
+ */
+public final class FrameState extends Node implements FrameStateAccess, Node.IterableNodeType, LIRLowerable {
+
+    protected final int localsSize;
+
+    protected final int stackSize;
+
+    private boolean rethrowException;
+
+    private boolean duringCall;
+
+    /**
+     * This BCI should be used for frame states that are built for code with no meaningful BCI.
+     */
+    public static final int UNKNOWN_BCI = -4;
+
+    /**
+     * When a node whose frame state has this BCI value is inlined, its frame state
+     * will be replaced with the frame state before the inlined invoke node.
+     */
+    public static final int BEFORE_BCI = -1;
+
+    /**
+     * When a node whose frame state has this BCI value is inlined, its frame state
+     * will be replaced with the frame state {@linkplain Invoke#stateAfter() after}
+     * the inlined invoke node.
+     */
+    public static final int AFTER_BCI = -2;
+
+    /**
+     * When a node whose frame state has this BCI value is inlined, its frame state
+     * will be replaced with the frame state at the exception edge of the inlined
+     * invoke node.
+     */
+    public static final int AFTER_EXCEPTION_BCI = -3;
+
+    @Input private FrameState outerFrameState;
+
+    @Input private final NodeInputList<ValueNode> values;
+
+    @Input private final NodeInputList<Node> virtualObjectMappings;
+
+    /**
+     * The bytecode index to which this frame state applies. This will be {@code -1}
+     * iff this state is mutable.
+     */
+    public final int bci;
+
+    private final RiResolvedMethod method;
+
+    /**
+     * Creates a {@code FrameState} for the given scope and maximum number of stack and local variables.
+     *
+     * @param method the method for this frame state
+     * @param bci the bytecode index of the frame state
+     * @param localsSize number of locals
+     * @param stackSize size of the stack
+     * @param rethrowException if true the VM should re-throw the exception on top of the stack when deopt'ing using this framestate
+     */
+    public FrameState(RiResolvedMethod method, int bci, int localsSize, int stackSize, boolean rethrowException, boolean duringCall) {
+        assert stackSize >= 0;
+        this.method = method;
+        this.bci = bci;
+        this.localsSize = localsSize;
+        this.stackSize = stackSize;
+        this.values = new NodeInputList<>(this, localsSize + stackSize);
+        this.virtualObjectMappings = new NodeInputList<>(this);
+        this.rethrowException = rethrowException;
+        this.duringCall = duringCall;
+        assert !rethrowException || stackSize == 1 : "must have exception on top of the stack";
+    }
+
+    public FrameState(RiResolvedMethod method, int bci, ValueNode[] locals, ValueNode[] stack, int stackSize, boolean rethrowException, boolean duringCall) {
+        this.method = method;
+        this.bci = bci;
+        this.localsSize = locals.length;
+        this.stackSize = stackSize;
+        final ValueNode[] newValues = new ValueNode[locals.length + stackSize];
+        for (int i = 0; i < locals.length; i++) {
+            newValues[i] = locals[i];
+        }
+        for (int i = 0; i < stackSize; i++) {
+            newValues[localsSize + i] = stack[i];
+        }
+        this.values = new NodeInputList<>(this, newValues);
+        this.virtualObjectMappings = new NodeInputList<>(this);
+        this.rethrowException = rethrowException;
+        this.duringCall = duringCall;
+        assert !rethrowException || stackSize == 1 : "must have exception on top of the stack";
+    }
+
+    public FrameState outerFrameState() {
+        return outerFrameState;
+    }
+
+    public void setOuterFrameState(FrameState x) {
+        updateUsages(this.outerFrameState, x);
+        this.outerFrameState = x;
+    }
+
+    public FrameState outermostFrameState() {
+        FrameState fs = this;
+        while (fs.outerFrameState() != null) {
+            fs = fs.outerFrameState();
+        }
+        return fs;
+    }
+
+    public void setValueAt(int i, ValueNode x) {
+        values.set(i, x);
+    }
+
+    public boolean rethrowException() {
+        return rethrowException;
+    }
+
+    public boolean duringCall() {
+        return duringCall;
+    }
+
+    public void setDuringCall(boolean b) {
+        this.duringCall = b;
+    }
+
+    public RiResolvedMethod method() {
+        return method;
+    }
+
+    public void addVirtualObjectMapping(Node virtualObject) {
+        assert virtualObject instanceof VirtualObjectFieldNode || virtualObject instanceof PhiNode : virtualObject;
+        virtualObjectMappings.add(virtualObject);
+    }
+
+    public int virtualObjectMappingCount() {
+        return virtualObjectMappings.size();
+    }
+
+    public Node virtualObjectMappingAt(int i) {
+        return virtualObjectMappings.get(i);
+    }
+
+    public Iterable<Node> virtualObjectMappings() {
+        return virtualObjectMappings;
+    }
+
+    /**
+     * Gets a copy of this frame state.
+     */
+    public FrameState duplicate(int newBci) {
+        return duplicate(newBci, false);
+    }
+
+    public FrameState duplicate(int newBci, boolean duplicateOuter) {
+        FrameState other = graph().add(new FrameState(method, newBci, localsSize, stackSize, rethrowException, duringCall));
+        other.values.setAll(values);
+        other.virtualObjectMappings.setAll(virtualObjectMappings);
+        FrameState newOuterFrameState = outerFrameState();
+        if (duplicateOuter && newOuterFrameState != null) {
+            newOuterFrameState = newOuterFrameState.duplicate(newOuterFrameState.bci, duplicateOuter);
+        }
+        other.setOuterFrameState(newOuterFrameState);
+        return other;
+    }
+
+    @Override
+    public FrameState duplicateWithException(int newBci, ValueNode exceptionObject) {
+        return duplicateModified(newBci, true, CiKind.Void, exceptionObject);
+    }
+
+    /**
+     * Creates a copy of this frame state with one stack element of type popKind popped from the stack and the
+     * values in pushedValues pushed on the stack. The pushedValues are expected to be in slot encoding: a long
+     * or double is followed by a null slot.
+     */
+    public FrameState duplicateModified(int newBci, boolean newRethrowException, CiKind popKind, ValueNode... pushedValues) {
+        int popSlots = popKind == CiKind.Void ? 0 : isTwoSlot(popKind) ? 2 : 1;
+        int pushSlots = pushedValues.length;
+        FrameState other = graph().add(new FrameState(method, newBci, localsSize, stackSize - popSlots + pushSlots, newRethrowException, false));
+        for (int i = 0; i < localsSize; i++) {
+            other.setValueAt(i, localAt(i));
+        }
+        for (int i = 0; i < stackSize - popSlots; i++) {
+            other.setValueAt(localsSize + i, stackAt(i));
+        }
+        int slot = localsSize + stackSize - popSlots;
+        for (int i = 0; i < pushSlots; i++) {
+            other.setValueAt(slot++, pushedValues[i]);
+        }
+        other.virtualObjectMappings.setAll(virtualObjectMappings);
+        other.setOuterFrameState(outerFrameState());
+        return other;
+    }
+
+    public boolean isCompatibleWith(FrameStateAccess other) {
+        if (stackSize() != other.stackSize() || localsSize() != other.localsSize()) {
+            return false;
+        }
+        for (int i = 0; i < stackSize(); i++) {
+            ValueNode x = stackAt(i);
+            ValueNode y = other.stackAt(i);
+            if (x != y && ValueUtil.typeMismatch(x, y)) {
+                return false;
+            }
+        }
+        if (other.outerFrameState() != outerFrameState()) {
+            return false;
+        }
+        return true;
+    }
+
+    public boolean equals(FrameStateAccess other) {
+        if (stackSize() != other.stackSize() || localsSize() != other.localsSize()) {
+            return false;
+        }
+        for (int i = 0; i < stackSize(); i++) {
+            ValueNode x = stackAt(i);
+            ValueNode y = other.stackAt(i);
+            if (x != y) {
+                return false;
+            }
+        }
+        if (other.outerFrameState() != outerFrameState()) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Gets the size of the local variables.
+     */
+    public int localsSize() {
+        return localsSize;
+    }
+
+    /**
+     * Gets the current size (height) of the stack.
+     */
+    public int stackSize() {
+        return stackSize;
+    }
+
+    /**
+     * Invalidates the local variable at the specified index. If the specified index refers to a doubleword local, then
+     * invalidates the high word as well.
+     *
+     * @param i the index of the local to invalidate
+     */
+    public void invalidateLocal(int i) {
+        // note that for double word locals, the high slot should already be null
+        // unless the local is actually dead and the high slot is being reused;
+        // in either case, it is not necessary to null the high slot
+        setValueAt(i, null);
+    }
+
+    /**
+     * Stores a given local variable at the specified index. If the value is a {@linkplain CiKind#isDoubleWord() double word},
+     * then the next local variable index is also overwritten.
+     *
+     * @param i the index at which to store
+     * @param x the instruction which produces the value for the local
+     */
+    // TODO this duplicates code in FrameStateBuilder and needs to go away
+    public void storeLocal(int i, ValueNode x) {
+        assert i < localsSize : "local variable index out of range: " + i;
+        invalidateLocal(i);
+        setValueAt(i, x);
+        if (isTwoSlot(x.kind())) {
+            // (tw) if this was a double word then kill i+1
+            setValueAt(i + 1, null);
+        }
+        if (i > 0) {
+            // if there was a double word at i - 1, then kill it
+            ValueNode p = localAt(i - 1);
+            if (p != null && isTwoSlot(p.kind())) {
+                setValueAt(i - 1, null);
+            }
+        }
+    }
+
+    /**
+     * Gets the value in the local variables at the specified index.
+     *
+     * @param i the index into the locals
+     * @return the instruction that produced the value for the specified local
+     */
+    public ValueNode localAt(int i) {
+        assert i < localsSize : "local variable index out of range: " + i;
+        return valueAt(i);
+    }
+
+    /**
+     * Get the value on the stack at the specified stack index.
+     *
+     * @param i the index into the stack, with {@code 0} being the bottom of the stack
+     * @return the instruction at the specified position in the stack
+     */
+    public ValueNode stackAt(int i) {
+        assert i >= 0 && i < (localsSize + stackSize);
+        return valueAt(localsSize + i);
+    }
+
+    /**
+     * Inserts a phi statement into the stack at the specified stack index.
+     * @param block the block begin for which we are creating the phi
+     * @param i the index into the stack for which to create a phi
+     */
+    public PhiNode setupLoopPhiForStack(MergeNode block, int i) {
+        ValueNode p = stackAt(i);
+        if (p != null) {
+            if (p instanceof PhiNode) {
+                PhiNode phi = (PhiNode) p;
+                if (phi.merge() == block) {
+                    return phi;
+                }
+            }
+            PhiNode phi = graph().unique(new PhiNode(p.kind(), block, PhiType.Value));
+            phi.addInput(p);
+            setValueAt(localsSize + i, phi);
+            return phi;
+        }
+        return null;
+    }
+
+    /**
+     * Inserts a phi statement for the local at the specified index.
+     * @param block the block begin for which we are creating the phi
+     * @param i the index of the local variable for which to create the phi
+     */
+    public PhiNode setupLoopPhiForLocal(MergeNode block, int i) {
+        ValueNode p = localAt(i);
+        if (p instanceof PhiNode) {
+            PhiNode phi = (PhiNode) p;
+            if (phi.merge() == block) {
+                return phi;
+            }
+        }
+        PhiNode phi = graph().unique(new PhiNode(p.kind(), block, PhiType.Value));
+        phi.addInput(p);
+        storeLocal(i, phi);
+        return phi;
+    }
+
+    /**
+     * Gets the value at a specified index in the set of operand stack and local values represented by this frame.
+     * This method should only be used to iterate over all the values in this frame, irrespective of whether
+     * they are on the stack or in local variables.
+     * To iterate the stack slots, the {@link #stackAt(int)} and {@link #stackSize()} methods should be used.
+     * To iterate the local variables, the {@link #localAt(int)} and {@link #localsSize()} methods should be used.
+     *
+     * @param i a value in the range {@code [0 .. valuesSize()]}
+     * @return the value at index {@code i} which may be {@code null}
+     */
+    public ValueNode valueAt(int i) {
+        assert i < (localsSize + stackSize);
+        return values.isEmpty() ? null : values.get(i);
+    }
+
+    /**
+     * The number of operand stack slots and local variables in this frame.
+     * This method should typically only be used in conjunction with {@link #valueAt(int)}.
+     * To iterate the stack slots, the {@link #stackAt(int)} and {@link #stackSize()} methods should be used.
+     * To iterate the local variables, the {@link #localAt(int)} and {@link #localsSize()} methods should be used.
+     *
+     * @return the number of local variables in this frame
+     */
+    public int valuesSize() {
+        return localsSize + stackSize;
+    }
+
+    private boolean checkSize(FrameStateAccess other) {
+        assert other.stackSize() == stackSize() : "stack sizes do not match";
+        assert other.localsSize() == localsSize : "local sizes do not match";
+        return true;
+    }
+
+    public void merge(MergeNode block, FrameStateAccess other) {
+        assert checkSize(other);
+        for (int i = 0; i < valuesSize(); i++) {
+            ValueNode currentValue = valueAt(i);
+            ValueNode otherValue = other.valueAt(i);
+            if (currentValue != otherValue || block instanceof LoopBeginNode) {
+                if (block.isPhiAtMerge(currentValue)) {
+                    addToPhi((PhiNode) currentValue, otherValue, block instanceof LoopBeginNode);
+                } else {
+                    setValueAt(i, combineValues(currentValue, otherValue, block));
+                }
+            }
+        }
+    }
+
+    public void simplifyLoopState() {
+        for (PhiNode phi : values.filter(PhiNode.class).snapshot()) {
+            checkRedundantPhi(phi);
+        }
+    }
+
+    private static ValueNode combineValues(ValueNode currentValue, ValueNode otherValue, MergeNode block) {
+        if (currentValue == null || otherValue == null || currentValue.kind() != otherValue.kind()) {
+            return null;
+        }
+
+        PhiNode phi = currentValue.graph().add(new PhiNode(currentValue.kind(), block, PhiType.Value));
+        for (int j = 0; j < block.phiPredecessorCount(); ++j) {
+            phi.addInput(currentValue);
+        }
+        phi.addInput(otherValue);
+        assert phi.valueCount() == block.phiPredecessorCount() + 1 : "valueCount=" + phi.valueCount() + " predSize= " + block.phiPredecessorCount();
+        return phi;
+    }
+
+    private static void addToPhi(PhiNode phiNode, ValueNode otherValue, boolean recursiveInvalidCheck) {
+        if (otherValue == null || otherValue.kind() != phiNode.kind()) {
+            if (recursiveInvalidCheck) {
+                deleteInvalidPhi(phiNode);
+            } else {
+                phiNode.replaceAtUsages(null);
+                phiNode.safeDelete();
+            }
+        } else {
+            phiNode.addInput(otherValue);
+        }
+    }
+
+    public static void deleteRedundantPhi(PhiNode redundantPhi, ValueNode phiValue) {
+        Collection<PhiNode> phiUsages = redundantPhi.usages().filter(PhiNode.class).snapshot();
+        ((StructuredGraph) redundantPhi.graph()).replaceFloating(redundantPhi, phiValue);
+        for (PhiNode phi : phiUsages) {
+            checkRedundantPhi(phi);
+        }
+    }
+
+    private static void checkRedundantPhi(PhiNode phiNode) {
+        if (phiNode.isDeleted() || phiNode.valueCount() == 1) {
+            return;
+        }
+
+        ValueNode singleValue = phiNode.singleValue();
+        if (singleValue != null) {
+            deleteRedundantPhi(phiNode, singleValue);
+        }
+    }
+
+    private static void deleteInvalidPhi(PhiNode phiNode) {
+        if (!phiNode.isDeleted()) {
+            Collection<PhiNode> phiUsages = phiNode.usages().filter(PhiNode.class).snapshot();
+            phiNode.replaceAtUsages(null);
+            phiNode.safeDelete();
+            for (Node n : phiUsages) {
+                deleteInvalidPhi((PhiNode) n);
+            }
+        }
+    }
+
+    public MergeNode block() {
+        return usages().filter(MergeNode.class).first();
+    }
+
+    public StateSplit stateSplit() {
+        return (StateSplit) usages().filterInterface(StateSplit.class).first();
+    }
+
+    public NodeIterable<FrameState> innerFrameStates() {
+        return usages().filter(FrameState.class);
+    }
+
+    /**
+     * The interface implemented by a client of {@link FrameState#forEachPhi(MergeNode, PhiProcedure)} and
+     * {@link FrameState#forEachLivePhi(MergeNode, PhiProcedure)}.
+     */
+    public interface PhiProcedure {
+        boolean doPhi(PhiNode phi);
+    }
+
+    /**
+     * Checks whether this frame state has any {@linkplain PhiNode phi} statements.
+     */
+    public boolean hasPhis() {
+        for (int i = 0; i < valuesSize(); i++) {
+            ValueNode value = valueAt(i);
+            if (value instanceof PhiNode) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public String toDetailedString() {
+        StringBuilder sb = new StringBuilder();
+        String nl = String.format("%n");
+        sb.append("[bci: ").append(bci).append("]");
+        if (rethrowException()) {
+            sb.append(" rethrows Exception");
+        }
+        sb.append(nl);
+        for (int i = 0; i < localsSize(); ++i) {
+            ValueNode value = localAt(i);
+            sb.append(String.format("  local[%d] = %-8s : %s%n", i, value == null ? "bogus" : value.kind().javaName, value));
+        }
+        for (int i = 0; i < stackSize(); ++i) {
+            ValueNode value = stackAt(i);
+            sb.append(String.format("  stack[%d] = %-8s : %s%n", i, value == null ? "bogus" : value.kind().javaName, value));
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        // Nothing to do, frame states are processed as part of the handling of AbstractStateSplit nodes.
+    }
+
+    public static String toString(FrameState frameState) {
+        StringBuilder sb = new StringBuilder();
+        String nl = CiUtil.NEW_LINE;
+        FrameState fs = frameState;
+        while (fs != null) {
+            CiUtil.appendLocation(sb, fs.method, fs.bci).append(nl);
+            for (int i = 0; i < fs.localsSize(); ++i) {
+                ValueNode value = fs.localAt(i);
+                sb.append(String.format("  local[%d] = %-8s : %s%n", i, value == null ? "bogus" : value.kind().javaName, value));
+            }
+            for (int i = 0; i < fs.stackSize(); ++i) {
+                ValueNode value = fs.stackAt(i);
+                sb.append(String.format("  stack[%d] = %-8s : %s%n", i, value == null ? "bogus" : value.kind().javaName, value));
+            }
+            fs = fs.outerFrameState();
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Debugger) {
+            return toString(this);
+        } else if (verbosity == Verbosity.Name) {
+            return super.toString(Verbosity.Name) + "@" + bci;
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+
+    public void insertLoopPhis(LoopBeginNode loopBegin) {
+        for (int i = 0; i < stackSize(); i++) {
+            // always insert phis for the stack
+            ValueNode x = stackAt(i);
+            if (x != null) {
+                setupLoopPhiForStack(loopBegin, i);
+            }
+        }
+        for (int i = 0; i < localsSize(); i++) {
+            ValueNode x = localAt(i);
+            if (x != null) {
+                setupLoopPhiForLocal(loopBegin, i);
+            }
+        }
+    }
+
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> properties = super.getDebugProperties();
+        properties.put("bci", bci);
+        if (method != null) {
+            properties.put("method", CiUtil.format("%H.%n(%p):%r", method));
+        } else {
+            properties.put("method", "None");
+        }
+        StringBuilder str = new StringBuilder();
+        for (int i = 0; i < localsSize(); i++) {
+            str.append(i == 0 ? "" : ", ").append(localAt(i) == null ? "_" : localAt(i).toString(Verbosity.Id));
+        }
+        properties.put("locals", str.toString());
+        str = new StringBuilder();
+        for (int i = 0; i < stackSize(); i++) {
+            str.append(i == 0 ? "" : ", ").append(stackAt(i) == null ? "_" : stackAt(i).toString(Verbosity.Id));
+        }
+        properties.put("stack", str.toString());
+        properties.put("rethrowException", rethrowException);
+        properties.put("duringCall", duringCall);
+        return properties;
+    }
+
+    public CiCodePos toCodePos() {
+        FrameState caller = outerFrameState();
+        CiCodePos callerCodePos = null;
+        if (caller != null) {
+            callerCodePos = caller.toCodePos();
+        }
+        return new CiCodePos(callerCodePos, method, bci);
+    }
+
+    @Override
+    public boolean verify() {
+        for (ValueNode value : values) {
+            assert assertTrue(value == null || value instanceof VirtualObjectNode || (value.kind() != CiKind.Void && value.kind() != CiKind.Illegal), "unexpected value: %s", value);
+        }
+        return super.verify();
+    }
+
+    // TODO this duplicates code in FrameStateBuilder and needs to go away
+    public static boolean isTwoSlot(CiKind kind) {
+        assert kind != CiKind.Void && kind != CiKind.Illegal;
+        return kind == CiKind.Long || kind == CiKind.Double;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/GuardNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,72 @@
+/*
+ * 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.max.graal.nodes;
+
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public final class GuardNode extends FloatingNode implements Canonicalizable, LIRLowerable {
+
+    @Input private BooleanNode condition;
+    @Input(notDataflow = true) private FixedNode anchor;
+
+    public FixedNode anchor() {
+        return anchor;
+    }
+
+    public void setAnchor(FixedNode x) {
+        updateUsages(anchor, x);
+        anchor = x;
+    }
+
+    /**
+     * The instruction that produces the tested boolean value.
+     */
+    public BooleanNode condition() {
+        return condition;
+    }
+
+    public GuardNode(BooleanNode condition, FixedNode anchor) {
+        super(StampFactory.illegal());
+        this.condition = condition;
+        this.anchor = anchor;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.emitGuardCheck(condition());
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (condition() instanceof ConstantNode) {
+            ConstantNode c = (ConstantNode) condition();
+            if (c.asConstant().asBoolean()) {
+                this.replaceAtUsages(null);
+                return null;
+            }
+        }
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/IfNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code IfNode} represents a branch that can go one of two directions depending on the outcome of a
+ * comparison.
+ */
+public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable {
+    public static final int TRUE_EDGE = 0;
+    public static final int FALSE_EDGE = 1;
+
+    private static final BeginNode[] EMPTY_IF_SUCCESSORS = new BeginNode[] {null, null};
+
+    @Input private BooleanNode compare;
+
+    public BooleanNode compare() {
+        return compare;
+    }
+
+    public IfNode(BooleanNode condition, FixedNode trueSuccessor, FixedNode falseSuccessor, double takenProbability) {
+        super(StampFactory.illegal(), new BeginNode[] {BeginNode.begin(trueSuccessor), BeginNode.begin(falseSuccessor)}, new double[] {takenProbability, 1 - takenProbability});
+        this.compare = condition;
+    }
+
+    public IfNode(BooleanNode condition, double probability) {
+        super(StampFactory.illegal(), EMPTY_IF_SUCCESSORS, new double[] {probability, 1 - probability});
+        this.compare = condition;
+    }
+
+    /**
+     * Gets the true successor.
+     *
+     * @return the true successor
+     */
+    public BeginNode trueSuccessor() {
+        return blockSuccessor(0);
+    }
+
+    /**
+     * Gets the false successor.
+     *
+     * @return the false successor
+     */
+    public BeginNode falseSuccessor() {
+        return blockSuccessor(1);
+    }
+
+    public void setTrueSuccessor(BeginNode node) {
+        setBlockSuccessor(0, node);
+    }
+
+    public void setFalseSuccessor(BeginNode node) {
+        setBlockSuccessor(1, node);
+    }
+
+    /**
+     * Gets the node corresponding to the specified outcome of the branch.
+     *
+     * @param istrue {@code true} if the true successor is requested, {@code false} otherwise
+     * @return the corresponding successor
+     */
+    public BeginNode successor(boolean istrue) {
+        return blockSuccessor(istrue ? 0 : 1);
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.emitIf(this);
+    }
+
+    @Override
+    public boolean verify() {
+        assertTrue(compare() != null, "missing compare");
+        assertTrue(trueSuccessor() != null, "missing trueSuccessor");
+        assertTrue(falseSuccessor() != null, "missing falseSuccessor");
+        return super.verify();
+    }
+
+    @Override
+    public void simplify(SimplifierTool tool) {
+        if (compare() instanceof ConstantNode) {
+            ConstantNode c = (ConstantNode) compare();
+            if (c.asConstant().asBoolean()) {
+                tool.deleteBranch(falseSuccessor());
+                tool.addToWorkList(trueSuccessor());
+                ((StructuredGraph) graph()).removeSplit(this, TRUE_EDGE);
+            } else {
+                tool.deleteBranch(trueSuccessor());
+                tool.addToWorkList(falseSuccessor());
+                ((StructuredGraph) graph()).removeSplit(this, FALSE_EDGE);
+            }
+        } else {
+            if (trueSuccessor().next() instanceof EndNode && falseSuccessor().next() instanceof EndNode) {
+                EndNode trueEnd = (EndNode) trueSuccessor().next();
+                EndNode falseEnd = (EndNode) falseSuccessor().next();
+                MergeNode merge = trueEnd.merge();
+                if (merge == falseEnd.merge() && merge.forwardEndCount() == 2) {
+                    Iterator<PhiNode> phis = merge.phis().iterator();
+                    if (!phis.hasNext()) {
+                        // empty if construct with no phis: remove it
+                        removeEmptyIf(tool);
+                    } else {
+                        PhiNode singlePhi = phis.next();
+                        if (!phis.hasNext()) {
+                            // one phi at the merge of an otherwise empty if construct: try to convert into a MaterializeNode
+                            boolean inverted = trueEnd == merge.forwardEndAt(FALSE_EDGE);
+                            ValueNode trueValue = singlePhi.valueAt(inverted ? 1 : 0);
+                            ValueNode falseValue = singlePhi.valueAt(inverted ? 0 : 1);
+                            if (trueValue.kind() != falseValue.kind()) {
+                                return;
+                            }
+                            if (trueValue.kind() != CiKind.Int && trueValue.kind() != CiKind.Long) {
+                                return;
+                            }
+                            if (trueValue.isConstant() && falseValue.isConstant()) {
+                                MaterializeNode materialize = MaterializeNode.create(compare(), graph(), trueValue, falseValue);
+                                ((StructuredGraph) graph()).replaceFloating(singlePhi, materialize);
+                                removeEmptyIf(tool);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void removeEmptyIf(SimplifierTool tool) {
+        BeginNode trueSuccessor = trueSuccessor();
+        BeginNode falseSuccessor = falseSuccessor();
+        assert trueSuccessor.next() instanceof EndNode && falseSuccessor.next() instanceof EndNode;
+
+        EndNode trueEnd = (EndNode) trueSuccessor.next();
+        EndNode falseEnd = (EndNode) falseSuccessor.next();
+        assert trueEnd.merge() == falseEnd.merge();
+
+        MergeNode merge = trueEnd.merge();
+        assert merge.usages().isEmpty();
+
+        FixedNode next = merge.next();
+        merge.setNext(null);
+        setTrueSuccessor(null);
+        setFalseSuccessor(null);
+        ((FixedWithNextNode) predecessor()).setNext(next);
+        safeDelete();
+        trueSuccessor.safeDelete();
+        falseSuccessor.safeDelete();
+        merge.safeDelete();
+        trueEnd.safeDelete();
+        falseEnd.safeDelete();
+        tool.addToWorkList(next);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/Invoke.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * 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.max.graal.nodes;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.java.*;
+
+public interface Invoke extends StateSplit {
+
+    FixedNode next();
+
+    void setNext(FixedNode x);
+
+    MethodCallTargetNode callTarget();
+
+    int bci();
+
+    FixedNode node();
+
+    FrameState stateDuring();
+
+    FrameState stateAfter();
+
+    Node predecessor();
+
+    void intrinsify(Node node);
+
+    Graph graph();
+
+    double probability();
+
+    boolean useForInlining();
+
+    void setUseForInlining(boolean value);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/InvokeNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.java.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.util.*;
+
+/**
+ * The {@code InvokeNode} represents all kinds of method calls.
+ */
+public final class InvokeNode extends AbstractStateSplit implements Node.IterableNodeType, Invoke, LIRLowerable, MemoryCheckpoint  {
+
+    @Input private final MethodCallTargetNode callTarget;
+    private final int bci;
+    private boolean useForInlining;
+
+    /**
+     * Constructs a new Invoke instruction.
+     *
+     * @param bci the bytecode index of the original invoke (used for debug infos)
+     * @param opcode the opcode of the invoke
+     * @param target the target method being called
+     * @param args the list of instructions producing arguments to the invocation, including the receiver object
+     */
+    public InvokeNode(MethodCallTargetNode callTarget, int bci) {
+        super(callTarget.returnStamp());
+        this.callTarget = callTarget;
+        this.bci = bci;
+        this.useForInlining = true;
+    }
+
+    public MethodCallTargetNode callTarget() {
+        return callTarget;
+    }
+
+    public boolean useForInlining() {
+        return useForInlining;
+    }
+
+    @Override
+    public void setUseForInlining(boolean value) {
+        this.useForInlining = value;
+    }
+
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> debugProperties = super.getDebugProperties();
+        if (callTarget != null && callTarget.targetMethod() != null) {
+            debugProperties.put("targetMethod", CiUtil.format("%h.%n(%p)", callTarget.targetMethod()));
+        }
+        return debugProperties;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.emitInvoke(this);
+    }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Long) {
+            return super.toString(Verbosity.Short) + "(bci=" + bci() + ")";
+        } else if (verbosity == Verbosity.Name) {
+            if (callTarget == null || callTarget.targetMethod() == null) {
+                return "Invoke#??Invalid!";
+            }
+            return "Invoke#" + callTarget.targetMethod().name();
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+
+    public int bci() {
+        return bci;
+    }
+
+    @Override
+    public FixedNode node() {
+        return this;
+    }
+
+    @Override
+    public FrameState stateDuring() {
+        FrameState stateAfter = stateAfter();
+        FrameState stateDuring = stateAfter.duplicateModified(bci(), stateAfter.rethrowException(), this.callTarget.targetMethod().signature().returnKind(false));
+        stateDuring.setDuringCall(true);
+        return stateDuring;
+    }
+
+    @Override
+    public void intrinsify(Node node) {
+        MethodCallTargetNode call = callTarget;
+        FrameState stateAfter = stateAfter();
+        if (node instanceof StateSplit) {
+            StateSplit stateSplit = (StateSplit) node;
+            stateSplit.setStateAfter(stateAfter);
+        }
+        if (node == null) {
+            assert kind() == CiKind.Void && usages().isEmpty();
+            ((StructuredGraph) graph()).removeFixed(this);
+        } else {
+            if (node instanceof FixedWithNextNode) {
+                ((StructuredGraph) graph()).replaceFixedWithFixed(this, (FixedWithNextNode) node);
+            } else if (node instanceof DeoptimizeNode) {
+                this.replaceAtPredecessors(node);
+                this.replaceAtUsages(null);
+                GraphUtil.killCFG(this);
+                return;
+            } else {
+                ((StructuredGraph) graph()).replaceFixed(this, node);
+            }
+        }
+        call.safeDelete();
+        if (stateAfter.usages().isEmpty()) {
+            stateAfter.safeDelete();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/InvokeWithExceptionNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,176 @@
+/*
+ * 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.max.graal.nodes;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.java.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.util.*;
+
+public class InvokeWithExceptionNode extends ControlSplitNode implements Node.IterableNodeType, Invoke, MemoryCheckpoint, LIRLowerable {
+    public static final int NORMAL_EDGE = 0;
+    public static final int EXCEPTION_EDGE = 1;
+
+    @Input private final MethodCallTargetNode callTarget;
+    @Input private FrameState stateAfter;
+    private final int bci;
+    private boolean useForInlining;
+
+    /**
+     * @param kind
+     * @param blockSuccessors
+     * @param branchProbability
+     */
+    public InvokeWithExceptionNode(MethodCallTargetNode callTarget, BeginNode exceptionEdge, int bci) {
+        super(callTarget.returnStamp(), new BeginNode[]{null, exceptionEdge}, new double[]{1.0, 0.0});
+        this.bci = bci;
+        this.callTarget = callTarget;
+        this.useForInlining = true;
+    }
+
+    public BeginNode exceptionEdge() {
+        return blockSuccessor(EXCEPTION_EDGE);
+    }
+
+    public void setExceptionEdge(BeginNode x) {
+        setBlockSuccessor(EXCEPTION_EDGE, x);
+    }
+
+    public BeginNode next() {
+        return blockSuccessor(NORMAL_EDGE);
+    }
+
+    public void setNext(BeginNode x) {
+        setBlockSuccessor(NORMAL_EDGE, x);
+    }
+
+    public MethodCallTargetNode callTarget() {
+        return callTarget;
+    }
+
+    @Override
+    public boolean useForInlining() {
+        return useForInlining;
+    }
+
+    @Override
+    public void setUseForInlining(boolean value) {
+        this.useForInlining = value;
+    }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Long) {
+            return super.toString(Verbosity.Short) + "(bci=" + bci() + ")";
+        } else if (verbosity == Verbosity.Name) {
+            return "Invoke!#" + callTarget.targetMethod().name();
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+
+    public int bci() {
+        return bci;
+    }
+
+    @Override
+    public FixedNode node() {
+        return this;
+    }
+
+    @Override
+    public void setNext(FixedNode x) {
+        if (x != null) {
+            this.setNext(BeginNode.begin(x));
+        } else {
+            this.setNext(null);
+        }
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.emitInvoke(this);
+    }
+
+    public FrameState stateAfter() {
+        return stateAfter;
+    }
+
+    public void setStateAfter(FrameState stateAfter) {
+        updateUsages(this.stateAfter, stateAfter);
+        this.stateAfter = stateAfter;
+    }
+
+    public FrameState stateDuring() {
+        FrameState tempStateAfter = stateAfter();
+        FrameState stateDuring = tempStateAfter.duplicateModified(bci(), tempStateAfter.rethrowException(), this.callTarget.targetMethod().signature().returnKind(false));
+        stateDuring.setDuringCall(true);
+        return stateDuring;
+    }
+
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> debugProperties = super.getDebugProperties();
+        debugProperties.put("memoryCheckpoint", "true");
+        if (callTarget != null && callTarget.targetMethod() != null) {
+            debugProperties.put("targetMethod", CiUtil.format("%h.%n(%p)", callTarget.targetMethod()));
+        }
+        return debugProperties;
+    }
+
+    public void killExceptionEdge() {
+        BeginNode exceptionEdge = exceptionEdge();
+        setExceptionEdge(null);
+        GraphUtil.killCFG(exceptionEdge);
+    }
+
+    @Override
+    public boolean needsStateAfter() {
+        return true;
+    }
+
+    @Override
+    public void intrinsify(Node node) {
+        MethodCallTargetNode call = callTarget;
+        FrameState state = stateAfter();
+        killExceptionEdge();
+        if (node instanceof StateSplit) {
+            StateSplit stateSplit = (StateSplit) node;
+            stateSplit.setStateAfter(state);
+        }
+        if (node == null) {
+            assert kind() == CiKind.Void && usages().isEmpty();
+            ((StructuredGraph) graph()).removeSplit(this, NORMAL_EDGE);
+        } else {
+            ((StructuredGraph) graph()).replaceSplit(this, node, NORMAL_EDGE);
+        }
+        call.safeDelete();
+        if (state.usages().isEmpty()) {
+            state.safeDelete();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/LocalNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code Local} instruction is a placeholder for an incoming argument
+ * to a function call.
+ */
+
+public final class LocalNode extends FloatingNode implements Node.IterableNodeType {
+
+    @Data private final int index;
+
+    public LocalNode(CiKind kind, int index) {
+        this(index, StampFactory.forKind(kind));
+    }
+
+    public LocalNode(int index, Stamp stamp) {
+        super(stamp);
+        this.index = index;
+    }
+
+    /**
+     * Gets the index of this local in the array of parameters. This is NOT the JVM local index.
+     * @return the index
+     */
+    public int index() {
+        return index;
+    }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Name) {
+            return super.toString(Verbosity.Name) + "(" + index + ")";
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/LoopBeginNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,148 @@
+/*
+ * 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.max.graal.nodes;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.graph.iterators.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+
+public class LoopBeginNode extends MergeNode implements Node.IterableNodeType, LIRLowerable {
+    private double loopFrequency;
+    private int nextEndIndex;
+
+    public LoopBeginNode() {
+        loopFrequency = 1;
+    }
+
+    public double loopFrequency() {
+        return loopFrequency;
+    }
+
+    public void setLoopFrequency(double loopFrequency) {
+        this.loopFrequency = loopFrequency;
+    }
+
+    public NodeIterable<LoopEndNode> loopEnds() {
+        return usages().filter(LoopEndNode.class);
+    }
+
+    public List<LoopEndNode> orderedLoopEnds() {
+        List<LoopEndNode> snapshot = usages().filter(LoopEndNode.class).snapshot();
+        Collections.sort(snapshot, new Comparator<LoopEndNode>() {
+            @Override
+            public int compare(LoopEndNode o1, LoopEndNode o2) {
+                return o1.endIndex() - o2.endIndex();
+            }
+        });
+        return snapshot;
+    }
+
+    public EndNode forwardEnd() {
+        assert forwardEndCount() == 1;
+        return forwardEndAt(0);
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        // Nothing to emit, since this is node is used for structural purposes only.
+    }
+
+    @Override
+    protected void deleteEnd(EndNode end) {
+        if (end instanceof LoopEndNode) {
+            LoopEndNode loopEnd = (LoopEndNode) end;
+            loopEnd.setLoopBegin(null);
+            int idx = loopEnd.endIndex();
+            for (LoopEndNode le : loopEnds()) {
+                int leIdx = le.endIndex();
+                assert leIdx != idx;
+                if (leIdx > idx) {
+                    le.setEndIndex(leIdx - 1);
+                }
+            }
+            nextEndIndex--;
+        } else {
+            super.deleteEnd(end);
+        }
+    }
+
+    @Override
+    public int phiPredecessorCount() {
+        return forwardEndCount() + loopEnds().count();
+    }
+
+    @Override
+    public int phiPredecessorIndex(EndNode pred) {
+        if (pred instanceof LoopEndNode) {
+            LoopEndNode loopEnd = (LoopEndNode) pred;
+            if (loopEnd.loopBegin() == this) {
+                assert loopEnd.endIndex() < loopEnds().count() : "Invalid endIndex : " + loopEnd;
+                return loopEnd.endIndex() + forwardEndCount();
+            }
+        } else {
+            return super.forwardEndIndex(pred);
+        }
+        throw ValueUtil.shouldNotReachHere("unknown pred : " + pred);
+    }
+
+    @Override
+    public EndNode phiPredecessorAt(int index) {
+        if (index < forwardEndCount()) {
+            return forwardEndAt(index);
+        }
+        for (LoopEndNode end : loopEnds()) {
+            int idx = index - forwardEndCount();
+            assert idx >= 0;
+            if (end.endIndex() == idx) {
+                return end;
+            }
+        }
+        throw ValueUtil.shouldNotReachHere();
+    }
+
+    @Override
+    public boolean verify() {
+        assertTrue(loopEnds().isNotEmpty(), "missing loopEnd");
+        assertTrue(forwardEndCount() == 1, "LoopBegin should only have one forward edge");
+        return super.verify();
+    }
+
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> properties = super.getDebugProperties();
+        properties.put("loopFrequency", String.format("%7.1f", loopFrequency));
+        return properties;
+    }
+
+    public int nextEndIndex() {
+        return nextEndIndex++;
+    }
+
+    @Override
+    public void simplify(SimplifierTool tool) {
+        // nothing yet
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/LoopEndNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,93 @@
+/*
+ * 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.max.graal.nodes;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+
+public final class LoopEndNode extends EndNode {
+
+    @Input(notDataflow = true) private LoopBeginNode loopBegin;
+    @Data private boolean safepointPolling;
+    @Data private int endIndex;
+
+    public LoopEndNode(LoopBeginNode begin) {
+        int idx = begin.nextEndIndex();
+        assert idx >= 0;
+        this.safepointPolling = true;
+        this.endIndex = idx;
+        this.loopBegin = begin;
+    }
+
+    @Override
+    public MergeNode merge() {
+        return loopBegin();
+    }
+
+    public LoopBeginNode loopBegin() {
+        return loopBegin;
+    }
+
+    public void setLoopBegin(LoopBeginNode x) {
+        updateUsages(this.loopBegin, x);
+        this.loopBegin = x;
+    }
+
+
+    public void setSafepointPolling(boolean safePointPolling) {
+        this.safepointPolling = safePointPolling;
+    }
+
+    public boolean hasSafepointPolling() {
+        return safepointPolling;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitLoopEnd(this);
+        super.generate(gen);
+    }
+
+    @Override
+    public boolean verify() {
+        assertTrue(loopBegin != null, "must have a loop begin");
+        assertTrue(usages().count() == 0, "LoopEnds can not be used");
+        return super.verify();
+    }
+
+    public int endIndex() {
+        return endIndex;
+    }
+
+    public void setEndIndex(int idx) {
+        this.endIndex = idx;
+    }
+
+    @Override
+    public Iterable< ? extends Node> cfgSuccessors() {
+        return Collections.emptyList();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/MaterializeNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.calc.*;
+
+public final class MaterializeNode extends ConditionalNode {
+
+    private MaterializeNode(BooleanNode condition, ValueNode trueValue, ValueNode falseValue) {
+        super(condition, trueValue, falseValue);
+    }
+
+    public static MaterializeNode create(BooleanNode condition, Graph graph, ValueNode trueValue, ValueNode falseValue) {
+        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));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/MergeNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes;
+
+import static com.oracle.max.graal.graph.iterators.NodePredicates.*;
+
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.graph.iterators.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+/**
+ * Denotes the merging of multiple control-flow paths.
+ */
+public class MergeNode extends BeginNode implements Node.IterableNodeType, LIRLowerable {
+
+    @Input(notDataflow = true) private final NodeInputList<EndNode> ends = new NodeInputList<>(this);
+
+    @Override
+    public boolean needsStateAfter() {
+        return false;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitMerge(this);
+    }
+
+    public int forwardEndIndex(EndNode end) {
+        return ends.indexOf(end);
+    }
+
+    public void addForwardEnd(EndNode end) {
+        ends.add(end);
+    }
+
+    public int forwardEndCount() {
+        return ends.size();
+    }
+
+    public EndNode forwardEndAt(int index) {
+        return ends.get(index);
+    }
+
+    @Override
+    public NodeIterable<EndNode> cfgPredecessors() {
+        return ends;
+    }
+
+    /**
+     * Determines if a given node is a phi whose {@linkplain PhiNode#merge() merge} is this node.
+     *
+     * @param value the instruction to test
+     * @return {@code true} if {@code value} is a phi and its merge is {@code this}
+     */
+    public boolean isPhiAtMerge(Node value) {
+        return value instanceof PhiNode && ((PhiNode) value).merge() == this;
+    }
+
+    /**
+     * Removes the given end from the merge, along with the entries corresponding to this end in the phis connected to the merge.
+     * @param pred the end to remove
+     */
+    public void removeEnd(EndNode pred) {
+        int predIndex = phiPredecessorIndex(pred);
+        assert predIndex != -1;
+        deleteEnd(pred);
+        for (PhiNode phi : phis()) {
+            phi.removeInput(predIndex);
+        }
+    }
+
+    protected void deleteEnd(EndNode end) {
+        ends.remove(end);
+    }
+
+    public void clearEnds() {
+        ends.clear();
+    }
+
+    public NodeIterable<EndNode> forwardEnds() {
+        return ends;
+    }
+
+    public int phiPredecessorCount() {
+        return forwardEndCount();
+    }
+
+    public int phiPredecessorIndex(EndNode pred) {
+        return forwardEndIndex(pred);
+    }
+
+    public EndNode phiPredecessorAt(int index) {
+        return forwardEndAt(index);
+    }
+
+    public NodeIterable<PhiNode> phis() {
+        return this.usages().filter(PhiNode.class);
+    }
+
+    @Override
+    public void simplify(SimplifierTool tool) {
+        FixedNode next = next();
+        if (next instanceof LoopEndNode) {
+            LoopEndNode origLoopEnd = (LoopEndNode) next;
+            LoopBeginNode begin = origLoopEnd.loopBegin();
+            for (PhiNode phi : phis()) {
+                for (Node usage : phi.usages().filter(isNotA(FrameState.class))) {
+                    if (!begin.isPhiAtMerge(usage)) {
+                        return;
+                    }
+                }
+            }
+            Debug.log("Split %s into loop ends for %s", this, begin);
+            int numEnds = this.forwardEndCount();
+            StructuredGraph graph = (StructuredGraph) graph();
+            for (int i = 0; i < numEnds - 1; i++) {
+                EndNode end = forwardEndAt(numEnds - 1 - i);
+                LoopEndNode loopEnd = graph.add(new LoopEndNode(begin));
+                for (PhiNode phi : begin.phis()) {
+                    ValueNode v = phi.valueAt(origLoopEnd);
+                    ValueNode newInput;
+                    if (isPhiAtMerge(v)) {
+                        PhiNode endPhi = (PhiNode) v;
+                        newInput = endPhi.valueAt(end);
+                    } else {
+                        newInput = v;
+                    }
+                    phi.addInput(newInput);
+                }
+                this.removeEnd(end);
+                end.replaceAtPredecessors(loopEnd);
+                end.safeDelete();
+                tool.addToWorkList(loopEnd.predecessor());
+            }
+            graph.reduceTrivialMerge(this);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/PhiNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code PhiNode} represents the merging of dataflow in the graph. It refers to a merge
+ * and a variable.
+ */
+public final class PhiNode extends FloatingNode implements Canonicalizable, Node.IterableNodeType {
+
+    @Input(notDataflow = true) private MergeNode merge;
+
+    @Input private final NodeInputList<ValueNode> values = new NodeInputList<>(this);
+
+    public MergeNode merge() {
+        return merge;
+    }
+
+    public static enum PhiType {
+        Value, // normal value phis
+        Memory, // memory phis
+        Virtual // phis used for VirtualObjectField merges
+    }
+
+    private final PhiType type;
+
+    public PhiNode(CiKind kind, MergeNode merge, PhiType type) {
+        super(StampFactory.forKind(kind));
+        this.type = type;
+        this.merge = merge;
+    }
+
+    public PhiType type() {
+        return type;
+    }
+
+    public NodeInputList<ValueNode> values() {
+        return values;
+    }
+
+    public boolean inferStamp() {
+        Stamp newStamp = StampFactory.or(values());
+        if (stamp().equals(newStamp)) {
+            return false;
+        } else {
+            setStamp(newStamp);
+            return true;
+        }
+    }
+
+    @Override
+    public boolean verify() {
+        assertTrue(merge() != null, "missing merge");
+        assertTrue(merge().phiPredecessorCount() == valueCount(), "mismatch between merge predecessor count and phi value count: %d != %d", merge().phiPredecessorCount(), valueCount());
+        if (type == PhiType.Value) {
+            for (ValueNode v : values()) {
+                assertTrue(v.kind() == kind(), "all phi values must have same kind");
+            }
+        }
+        return super.verify();
+    }
+
+    /**
+     * Get the instruction that produces the value associated with the i'th predecessor of the merge.
+     *
+     * @param i the index of the predecessor
+     * @return the instruction that produced the value in the i'th predecessor
+     */
+    public ValueNode valueAt(int i) {
+        return values.get(i);
+    }
+
+    public void setValueAt(int i, ValueNode x) {
+        values.set(i, x);
+    }
+
+    public ValueNode valueAt(EndNode pred) {
+        return valueAt(merge().phiPredecessorIndex(pred));
+    }
+
+    /**
+     * Get the number of inputs to this phi (i.e. the number of predecessors to the merge).
+     *
+     * @return the number of inputs in this phi
+     */
+    public int valueCount() {
+        return values.size();
+    }
+
+    public void clearValues() {
+        values.clear();
+    }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Name) {
+            StringBuilder str = new StringBuilder();
+            for (int i = 0; i < valueCount(); ++i) {
+                if (i != 0) {
+                    str.append(' ');
+                }
+                str.append(valueAt(i) == null ? "-" : valueAt(i).toString(Verbosity.Id));
+            }
+            if (type == PhiType.Value) {
+                return super.toString(Verbosity.Name) + "(" + str + ")";
+            } else {
+                return type + super.toString(Verbosity.Name) + "(" + str + ")";
+            }
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+
+    public void addInput(ValueNode x) {
+        values.add(x);
+    }
+
+    public void removeInput(int index) {
+        values.remove(index);
+    }
+
+    public ValueNode singleValue() {
+        ValueNode differentValue = null;
+        for (ValueNode n : values()) {
+            if (n != this) {
+                if (differentValue == null) {
+                    differentValue = n;
+                } else if (differentValue != n) {
+                    return null;
+                }
+            }
+        }
+        return differentValue;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        ValueNode singleValue = singleValue();
+
+        if (singleValue != null) {
+            return singleValue;
+        }
+
+        return this;
+    }
+
+    public ValueNode firstValue() {
+        return valueAt(0);
+    }
+
+    public boolean isLoopPhi() {
+        return merge() instanceof LoopBeginNode;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/PiNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012, 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.max.graal.nodes;
+
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+
+public class PiNode extends FloatingNode implements LIRLowerable {
+
+    @Input private ValueNode value;
+    @Input private BeginNode anchor;
+
+    public ValueNode value() {
+        return value;
+    }
+
+    public BeginNode anchor() {
+        return anchor;
+    }
+
+    public PiNode(ValueNode value, BeginNode anchor, Stamp stamp) {
+        super(stamp);
+        this.value = value;
+        this.anchor = anchor;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool generator) {
+        generator.setResult(this, generator.operand(value));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/PlaceholderNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ * 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.max.graal.nodes;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+
+public class PlaceholderNode extends AbstractStateSplit implements Node.IterableNodeType, LIRLowerable {
+
+    public PlaceholderNode() {
+        super(StampFactory.illegal());
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        // nothing to do
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/ReturnNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public final class ReturnNode extends FixedNode implements LIRLowerable, Node.IterableNodeType {
+
+    @Input private ValueNode result;
+
+    public ValueNode result() {
+        return result;
+    }
+
+    /**
+     * Constructs a new Return instruction.
+     * @param result the instruction producing the result for this return; {@code null} if this is a void return
+     */
+    public ReturnNode(ValueNode result) {
+        super(StampFactory.forKind(result == null ? CiKind.Void : result.kind()));
+        this.result = result;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitReturn(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/ScheduledNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 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.max.graal.nodes;
+
+import com.oracle.max.graal.graph.*;
+
+public class ScheduledNode extends Node {
+
+    @Successor private ScheduledNode scheduledNext; // the immediate successor of the current node
+
+    public ScheduledNode scheduledNext() {
+        return scheduledNext;
+    }
+
+    public void setScheduledNext(ScheduledNode x) {
+        updatePredecessors(scheduledNext, x);
+        scheduledNext = x;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/StateSplit.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * 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.max.graal.nodes;
+
+public interface StateSplit {
+
+    /**
+     * Gets the state of the JVM frame after execution of this node.
+     */
+    FrameState stateAfter();
+
+    /**
+     * Sets the state of the JVM frame after execution of this node.
+     */
+    void setStateAfter(FrameState x);
+
+    /**
+     * Determines if the caller should create an {@link #stateAfter() after}
+     * frame state for this node if it doesn't already have one.
+     */
+    boolean needsStateAfter();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/StructuredGraph.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,333 @@
+/*
+ * 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.max.graal.nodes;
+
+import java.util.*;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.java.*;
+import com.oracle.max.graal.nodes.util.*;
+
+
+/**
+ * A graph that contains at least one distinguished node : the {@link #start() start} node.
+ * This node is the start of the control flow of the graph.
+ */
+public class StructuredGraph extends Graph {
+    private final BeginNode start;
+    private final RiResolvedMethod method;
+
+    /**
+     * Creates a new Graph containing a single {@link BeginNode} as the {@link #start() start} node.
+     */
+    public StructuredGraph(String name) {
+        this(name, null);
+    }
+
+    public StructuredGraph(String name, RiResolvedMethod method) {
+        super(name);
+        this.start = add(new BeginNode());
+        this.method = method;
+    }
+
+    /**
+     * Creates a new Graph containing a single {@link BeginNode} as the {@link #start() start} node.
+     */
+    public StructuredGraph() {
+        this((String) null);
+    }
+
+    public StructuredGraph(RiResolvedMethod method) {
+        this(null, method);
+    }
+
+    public BeginNode start() {
+        return start;
+    }
+
+    public RiResolvedMethod method() {
+        return method;
+    }
+
+    @Override
+    public StructuredGraph copy() {
+        return copy(name);
+    }
+
+    @Override
+    public StructuredGraph copy(String newName) {
+        StructuredGraph copy = new StructuredGraph(newName);
+        HashMap<Node, Node> replacements = new HashMap<>();
+        replacements.put(start, copy.start);
+        copy.addDuplicates(getNodes(), replacements);
+        return copy;
+    }
+
+    public LocalNode getLocal(int index) {
+        for (LocalNode local : getNodes(LocalNode.class)) {
+            if (local.index() == index) {
+                return local;
+            }
+        }
+        return null;
+    }
+
+    public Iterable<Invoke> getInvokes() {
+        final Iterator<MethodCallTargetNode> callTargets = getNodes(MethodCallTargetNode.class).iterator();
+        return new Iterable<Invoke>() {
+            private Invoke next;
+
+            @Override
+            public Iterator<Invoke> iterator() {
+                return new Iterator<Invoke>() {
+
+                    @Override
+                    public boolean hasNext() {
+                        if (next == null) {
+                            while (callTargets.hasNext()) {
+                                Invoke i = callTargets.next().invoke();
+                                if (i != null) {
+                                    next = i;
+                                    return true;
+                                }
+                            }
+                            return false;
+                        } else {
+                            return true;
+                        }
+                    }
+
+                    @Override
+                    public Invoke next() {
+                        try {
+                            return next;
+                        } finally {
+                            next = null;
+                        }
+                    }
+
+                    @Override
+                    public void remove() {
+                        throw new UnsupportedOperationException();
+                    }
+                };
+            }
+        };
+    }
+
+    public boolean hasLoops() {
+        return getNodes(LoopBeginNode.class).iterator().hasNext();
+    }
+
+    public void removeFloating(FloatingNode node) {
+        assert node != null && node.isAlive() : "cannot remove " + node;
+        node.safeDelete();
+    }
+
+    public void replaceFloating(FloatingNode node, ValueNode replacement) {
+        assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement;
+        node.replaceAtUsages(replacement);
+        node.safeDelete();
+    }
+
+    public void removeFixed(FixedWithNextNode node) {
+        assert node != null;
+        assert node.usages().isEmpty() : node + " " + node.usages();
+        FixedNode next = node.next();
+        node.setNext(null);
+        node.replaceAtPredecessors(next);
+        node.safeDelete();
+    }
+
+    public void replaceFixed(FixedWithNextNode node, Node replacement) {
+        if (replacement instanceof FixedWithNextNode) {
+            replaceFixedWithFixed(node, (FixedWithNextNode) replacement);
+        } else {
+            assert replacement != null : "cannot replace " + node + " with null";
+            assert replacement instanceof FloatingNode : "cannot replace " + node + " with " + replacement;
+            replaceFixedWithFloating(node, (FloatingNode) replacement);
+        }
+    }
+
+    public void replaceFixedWithFixed(FixedWithNextNode node, FixedWithNextNode replacement) {
+        assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement;
+        replacement.setProbability(node.probability());
+        FixedNode next = node.next();
+        node.setNext(null);
+        replacement.setNext(next);
+        node.replaceAndDelete(replacement);
+    }
+
+    public void replaceFixedWithFloating(FixedWithNextNode node, FloatingNode replacement) {
+        assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement;
+        FixedNode next = node.next();
+        node.setNext(null);
+        node.replaceAtPredecessors(next);
+        node.replaceAtUsages(replacement);
+        node.safeDelete();
+    }
+
+    public void removeSplit(ControlSplitNode node, int survivingSuccessor) {
+        assert node != null;
+        assert node.usages().isEmpty();
+        assert survivingSuccessor >= 0 && survivingSuccessor < node.blockSuccessorCount() : "invalid surviving successor " + survivingSuccessor + " for " + node;
+        BeginNode begin = node.blockSuccessor(survivingSuccessor);
+        begin.evacuateGuards();
+        FixedNode next = begin.next();
+        begin.setNext(null);
+        for (int i = 0; i < node.blockSuccessorCount(); i++) {
+            node.setBlockSuccessor(i, null);
+        }
+        node.replaceAtPredecessors(next);
+        node.safeDelete();
+        begin.safeDelete();
+    }
+
+    public void removeSplitPropagate(ControlSplitNode node, int survivingSuccessor) {
+        assert node != null;
+        assert node.usages().isEmpty();
+        assert survivingSuccessor >= 0 && survivingSuccessor < node.blockSuccessorCount() : "invalid surviving successor " + survivingSuccessor + " for " + node;
+        BeginNode begin = node.blockSuccessor(survivingSuccessor);
+        begin.evacuateGuards();
+        FixedNode next = begin.next();
+        begin.setNext(null);
+        for (int i = 0; i < node.blockSuccessorCount(); i++) {
+            BeginNode successor = node.blockSuccessor(i);
+            node.setBlockSuccessor(i, null);
+            if (successor != begin && successor.isAlive()) {
+                GraphUtil.killCFG(successor);
+            }
+        }
+        if (next.isAlive()) {
+            node.replaceAtPredecessors(next);
+            node.safeDelete();
+            begin.safeDelete();
+        } else {
+            assert node.isDeleted();
+        }
+    }
+
+    public void replaceSplit(ControlSplitNode node, Node replacement, int survivingSuccessor) {
+        if (replacement instanceof FixedWithNextNode) {
+            replaceSplitWithFixed(node, (FixedWithNextNode) replacement, survivingSuccessor);
+        } else {
+            assert replacement != null : "cannot replace " + node + " with null";
+            assert replacement instanceof FloatingNode : "cannot replace " + node + " with " + replacement;
+            replaceSplitWithFloating(node, (FloatingNode) replacement, survivingSuccessor);
+        }
+    }
+
+    public void replaceSplitWithFixed(ControlSplitNode node, FixedWithNextNode replacement, int survivingSuccessor) {
+        assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement;
+        assert survivingSuccessor >= 0 && survivingSuccessor < node.blockSuccessorCount() : "invalid surviving successor " + survivingSuccessor + " for " + node;
+        BeginNode begin = node.blockSuccessor(survivingSuccessor);
+        begin.evacuateGuards();
+        FixedNode next = begin.next();
+        begin.setNext(null);
+        for (int i = 0; i < node.blockSuccessorCount(); i++) {
+            node.setBlockSuccessor(i, null);
+        }
+        replacement.setNext(next);
+        node.replaceAndDelete(replacement);
+        begin.safeDelete();
+    }
+
+    public void replaceSplitWithFloating(ControlSplitNode node, FloatingNode replacement, int survivingSuccessor) {
+        assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement;
+        assert survivingSuccessor >= 0 && survivingSuccessor < node.blockSuccessorCount() : "invalid surviving successor " + survivingSuccessor + " for " + node;
+        BeginNode begin = node.blockSuccessor(survivingSuccessor);
+        begin.evacuateGuards();
+        FixedNode next = begin.next();
+        begin.setNext(null);
+        for (int i = 0; i < node.blockSuccessorCount(); i++) {
+            node.setBlockSuccessor(i, null);
+        }
+        node.replaceAtPredecessors(next);
+        node.replaceAtUsages(replacement);
+        node.safeDelete();
+        begin.safeDelete();
+    }
+
+    public void addAfterFixed(FixedWithNextNode node, FixedWithNextNode newNode) {
+        assert node != null && newNode != null && node.isAlive() && newNode.isAlive() : "cannot add " + newNode + " after " + node;
+        assert newNode.next() == null;
+        newNode.setProbability(node.probability());
+        FixedNode next = node.next();
+        node.setNext(newNode);
+        newNode.setNext(next);
+    }
+
+    public void addBeforeFixed(FixedNode node, FixedWithNextNode newNode) {
+        assert node != null && newNode != null && node.isAlive() && newNode.isAlive() : "cannot add " + newNode + " before " + node;
+        assert node.predecessor() != null && node.predecessor() instanceof FixedWithNextNode : "cannot add " + newNode + " before " + node;
+        assert newNode.next() == null;
+        newNode.setProbability(node.probability());
+        FixedWithNextNode pred = (FixedWithNextNode) node.predecessor();
+        pred.setNext(newNode);
+        newNode.setNext(node);
+    }
+
+    public void reduceDegenerateLoopBegin(LoopBeginNode begin) {
+        assert begin.loopEnds().isEmpty() : "Loop begin still has backedges";
+        if (begin.forwardEndCount() == 1) { // bypass merge and remove
+            reduceTrivialMerge(begin);
+        } else { // convert to merge
+            MergeNode merge = this.add(new MergeNode());
+            this.replaceFixedWithFixed(begin, merge);
+        }
+    }
+
+    public void reduceTrivialMerge(MergeNode merge) {
+        assert merge.forwardEndCount() == 1;
+        assert !(merge instanceof LoopBeginNode) || ((LoopBeginNode) merge).loopEnds().isEmpty();
+        for (PhiNode phi : merge.phis().snapshot()) {
+            assert phi.valueCount() == 1;
+            ValueNode singleValue = phi.valueAt(0);
+            phi.replaceAtUsages(singleValue);
+            phi.safeDelete();
+        }
+        EndNode singleEnd = merge.forwardEndAt(0);
+        FixedNode sux = merge.next();
+        FrameState stateAfter = merge.stateAfter();
+        // evacuateGuards
+        Node prevBegin = singleEnd.predecessor();
+        assert prevBegin != null;
+        while (!(prevBegin instanceof BeginNode)) {
+            prevBegin = prevBegin.predecessor();
+        }
+        merge.replaceAtUsages(prevBegin);
+
+        merge.safeDelete();
+        if (stateAfter != null && stateAfter.usages().isEmpty()) {
+            stateAfter.safeDelete();
+        }
+        if (sux == null) {
+            singleEnd.replaceAtPredecessors(null);
+            singleEnd.safeDelete();
+        } else {
+            singleEnd.replaceAndDelete(sux);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/UnwindNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * 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.max.graal.nodes;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * Unwind takes an exception object, destroys the current stack frame and passes the exception object to the system's exception dispatch code.
+ */
+public final class UnwindNode extends FixedNode implements LIRLowerable, Node.IterableNodeType {
+
+    @Input private ValueNode exception;
+
+    public ValueNode exception() {
+        return exception;
+    }
+
+    public UnwindNode(ValueNode exception) {
+        super(StampFactory.forKind(CiKind.Object));
+        assert exception == null || exception.kind() == CiKind.Object;
+        this.exception = exception;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.emitCallToRuntime(CiRuntimeCall.UnwindException, false, gen.operand(exception()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/ValueNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * This class represents a value within the graph, including local variables, phis, and
+ * all other instructions.
+ */
+public abstract class ValueNode extends ScheduledNode implements StampProvider {
+
+    /**
+     * The kind of this value. This is {@link CiKind#Void} for instructions that produce no value.
+     * This kind is guaranteed to be a {@linkplain CiKind#stackKind() stack kind}.
+     */
+    @Data private Stamp stamp;
+
+    /**
+     * Creates a new value with the specified kind.
+     * @param kind the type of this value
+     * @param inputCount
+     * @param successorCount
+     * @param graph
+     */
+    public ValueNode(Stamp stamp) {
+        this.stamp = stamp;
+        assert kind() != null && kind() == kind().stackKind() : kind() + " != " + kind().stackKind();
+    }
+
+    public Stamp stamp() {
+        return stamp;
+    }
+
+    public void setStamp(Stamp stamp) {
+        this.stamp = stamp;
+    }
+
+    public CiKind kind() {
+        return stamp.kind();
+    }
+
+    /**
+     * Checks whether this value is a constant (i.e. it is of type {@link ConstantNode}.
+     * @return {@code true} if this value is a constant
+     */
+    public final boolean isConstant() {
+        return this instanceof ConstantNode;
+    }
+
+    /**
+     * Checks whether this value represents the null constant.
+     * @return {@code true} if this value represents the null constant
+     */
+    public final boolean isNullConstant() {
+        return this instanceof ConstantNode && ((ConstantNode) this).value.isNull();
+    }
+
+    /**
+     * Convert this value to a constant if it is a constant, otherwise return null.
+     * @return the {@link CiConstant} represented by this value if it is a constant; {@code null}
+     * otherwise
+     */
+    public final CiConstant asConstant() {
+        if (this instanceof ConstantNode) {
+            return ((ConstantNode) this).value;
+        }
+        return null;
+    }
+
+    /**
+     * Computes the exact type of the result of this node, if possible.
+     * @return the exact type of the result of this node, if it is known; {@code null} otherwise
+     */
+    public final RiResolvedType exactType() {
+        return stamp.exactType();
+    }
+
+    /**
+     * Computes the declared type of the result of this node, if possible.
+     * @return the declared type of the result of this node, if it is known; {@code null} otherwise
+     */
+    public final RiResolvedType declaredType() {
+        return stamp.declaredType();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/ValueUtil.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,108 @@
+/*
+ * 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.max.graal.nodes;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.graph.Node.Verbosity;
+
+
+public class ValueUtil {
+
+    public static ValueNode assertKind(CiKind kind, ValueNode x) {
+        assert x != null && ((x.kind() == kind) || (x.kind() == CiKind.Jsr && kind == CiKind.Object)) : "kind=" + kind + ", value=" + x + ((x == null) ? "" : ", value.kind=" + x.kind());
+        return x;
+    }
+
+    public static RuntimeException shouldNotReachHere(String msg) {
+        throw new InternalError("should not reach here: " + msg);
+    }
+
+    public static RuntimeException shouldNotReachHere() {
+        throw new InternalError("should not reach here");
+    }
+
+    public static ValueNode assertLong(ValueNode x) {
+        assert x != null && (x.kind() == CiKind.Long);
+        return x;
+    }
+
+    public static ValueNode assertJsr(ValueNode x) {
+        assert x != null && (x.kind() == CiKind.Jsr);
+        return x;
+    }
+
+    public static ValueNode assertInt(ValueNode x) {
+        assert x != null && (x.kind() == CiKind.Int);
+        return x;
+    }
+
+    public static ValueNode assertFloat(ValueNode x) {
+        assert x != null && (x.kind() == CiKind.Float);
+        return x;
+    }
+
+    public static ValueNode assertObject(ValueNode x) {
+        assert x != null && (x.kind() == CiKind.Object);
+        return x;
+    }
+
+    public static ValueNode assertDouble(ValueNode x) {
+        assert x != null && (x.kind() == CiKind.Double);
+        return x;
+    }
+
+    public static void assertHigh(ValueNode x) {
+        assert x == null;
+    }
+
+    public static boolean typeMismatch(ValueNode x, ValueNode y) {
+        return y == null || x == null || x.kind() != y.kind();
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public static <T extends Node> Collection<T> filter(Iterable<Node> nodes, Class<T> clazz) {
+        ArrayList<T> phis = new ArrayList<>();
+        for (Node node : nodes) {
+            if (clazz.isInstance(node)) {
+                phis.add((T) node);
+            }
+        }
+        return phis;
+    }
+
+    /**
+     * Converts a given instruction to a value string. The representation of an node as
+     * a value is formed by concatenating the {@linkplain com.oracle.max.cri.ci.CiKind#typeChar character} denoting its
+     * {@linkplain ValueNode#kind kind} and its {@linkplain Node#id()}. For example, {@code "i13"}.
+     *
+     * @param value the instruction to convert to a value string. If {@code value == null}, then "-" is returned.
+     * @return the instruction representation as a string
+     */
+    public static String valueString(ValueNode value) {
+        return (value == null) ? "-" : ("" + value.kind().typeChar + value.toString(Verbosity.Id));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/AndNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "&")
+public final class AndNode extends LogicNode implements Canonicalizable, LIRLowerable {
+
+    public AndNode(CiKind kind, ValueNode x, ValueNode y) {
+        super(kind, x, y);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x() == y()) {
+            return x();
+        }
+        if (x().isConstant() && !y().isConstant()) {
+            return graph().unique(new AndNode(kind(), y(), x()));
+        }
+        if (x().isConstant()) {
+            if (kind() == CiKind.Int) {
+                return ConstantNode.forInt(x().asConstant().asInt() & y().asConstant().asInt(), graph());
+            } else {
+                assert kind() == CiKind.Long;
+                return ConstantNode.forLong(x().asConstant().asLong() & y().asConstant().asLong(), graph());
+            }
+        } else if (y().isConstant()) {
+            if (kind() == CiKind.Int) {
+                int c = y().asConstant().asInt();
+                if (c == -1) {
+                    return x();
+                }
+                if (c == 0) {
+                    return ConstantNode.forInt(0, graph());
+                }
+            } else {
+                assert kind() == CiKind.Long;
+                long c = y().asConstant().asLong();
+                if (c == -1) {
+                    return x();
+                }
+                if (c == 0) {
+                    return ConstantNode.forLong(0, graph());
+                }
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.setResult(this, gen.emitAnd(gen.operand(x()), gen.operand(y())));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/ArithmeticNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+
+/**
+ * The {@code ArithmeticOp} class represents arithmetic operations such as addition, subtraction, etc.
+ */
+public abstract class ArithmeticNode extends BinaryNode {
+
+    private final boolean isStrictFP;
+
+    /**
+     * Creates a new arithmetic operation.
+     * @param kind the result kind of the operation
+     * @param x the first input instruction
+     * @param y the second input instruction
+     * @param isStrictFP indicates this operation has strict rounding semantics
+     */
+    public ArithmeticNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
+        super(kind, x, y);
+        this.isStrictFP = isStrictFP;
+    }
+
+    /**
+     * Checks whether this instruction has strict fp semantics.
+     * @return {@code true} if this instruction has strict fp semantics
+     */
+    public boolean isStrictFP() {
+        return isStrictFP;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/BinaryNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code BinaryNode} class is the base of arithmetic and logic operations with two inputs.
+ */
+public abstract class BinaryNode extends FloatingNode {
+
+    @Input private ValueNode x;
+    @Input private ValueNode y;
+
+    public ValueNode x() {
+        return x;
+    }
+
+    public ValueNode y() {
+        return y;
+    }
+
+    /**
+     * Creates a new BinaryNode instance.
+     * @param kind the result type of this instruction
+     * @param x the first input instruction
+     * @param y the second input instruction
+     */
+    public BinaryNode(CiKind kind, ValueNode x, ValueNode y) {
+        super(StampFactory.forKind(kind));
+        this.x = x;
+        this.y = y;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/CompareNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/* TODO(tw/gd) For high-level optimization purpose the compare node should be a boolean *value* (it is currently only a helper node)
+ * But in the back-end the comparison should not always be materialized (for example in x86 the comparison result will not be in a register but in a flag)
+ *
+ * Compare should probably be made a value (so that it can be canonicalized for example) and in later stages some Compare usage should be transformed
+ * into variants that do not materialize the value (CompareIf, CompareGuard...)
+ */
+public final class CompareNode extends BooleanNode implements Canonicalizable, LIRLowerable {
+
+    @Input private ValueNode x;
+    @Input private ValueNode y;
+
+    @Data private final Condition condition;
+    @Data private final boolean unorderedIsTrue;
+
+    public ValueNode x() {
+        return x;
+    }
+
+    public ValueNode y() {
+        return y;
+    }
+
+    /**
+     * Constructs a new Compare instruction.
+     *
+     * @param x the instruction producing the first input to the instruction
+     * @param condition the condition (comparison operation)
+     * @param y the instruction that produces the second input to this instruction
+     * @param graph
+     */
+    public CompareNode(ValueNode x, Condition condition, ValueNode y) {
+        this(x, condition, false, y);
+    }
+
+    /**
+     * Constructs a new Compare instruction.
+     *
+     * @param x the instruction producing the first input to the instruction
+     * @param condition the condition (comparison operation)
+     * @param y the instruction that produces the second input to this instruction
+     * @param graph
+     */
+    public CompareNode(ValueNode x, Condition condition, boolean unorderedIsTrue, ValueNode y) {
+        super(StampFactory.illegal());
+        assert (x == null && y == null) || x.kind() == y.kind();
+        this.condition = condition;
+        this.unorderedIsTrue = unorderedIsTrue;
+        this.x = x;
+        this.y = y;
+    }
+
+    /**
+     * Gets the condition (comparison operation) for this instruction.
+     *
+     * @return the condition
+     */
+    public Condition condition() {
+        return condition;
+    }
+
+    /**
+     * Checks whether unordered inputs mean true or false.
+     *
+     * @return {@code true} if unordered inputs produce true
+     */
+    public boolean unorderedIsTrue() {
+        return unorderedIsTrue;
+    }
+
+    @Override
+    public BooleanNode negate() {
+        return graph().unique(new CompareNode(x(), condition.negate(), !unorderedIsTrue, y()));
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+    }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Name) {
+            return super.toString(Verbosity.Name) + " " + condition.operator;
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+
+    private ValueNode optimizeMaterialize(CiConstant constant, MaterializeNode materializeNode, RiRuntime runtime) {
+        CiConstant trueConstant = materializeNode.trueValue().asConstant();
+        CiConstant falseConstant = materializeNode.falseValue().asConstant();
+
+        if (falseConstant != null && trueConstant != null) {
+            Boolean trueResult = condition().foldCondition(trueConstant, constant, runtime, unorderedIsTrue());
+            Boolean falseResult = condition().foldCondition(falseConstant, constant, runtime, unorderedIsTrue());
+
+            if (trueResult != null && falseResult != null) {
+                boolean trueUnboxedResult = trueResult;
+                boolean falseUnboxedResult = falseResult;
+                if (trueUnboxedResult == falseUnboxedResult) {
+                    return ConstantNode.forBoolean(trueUnboxedResult, graph());
+                } else {
+                    if (trueUnboxedResult) {
+                        assert falseUnboxedResult == false;
+                        return materializeNode.condition();
+                    } else {
+                        assert falseUnboxedResult == true;
+                        return materializeNode.condition().negate();
+
+                    }
+                }
+            }
+        }
+        return this;
+    }
+
+    private ValueNode optimizeNormalizeCmp(CiConstant constant, NormalizeCompareNode normalizeNode) {
+        if (constant.kind == CiKind.Int && constant.asInt() == 0) {
+            Condition cond = condition();
+            boolean isLess = cond == Condition.LE || cond == Condition.LT || cond == Condition.BE || cond == Condition.BT;
+            boolean canonUnorderedIsTrue = cond != Condition.EQ && (cond == Condition.NE || !(isLess ^ normalizeNode.isUnorderedLess));
+            CompareNode result = graph().unique(new CompareNode(normalizeNode.x(), cond, canonUnorderedIsTrue, normalizeNode.y()));
+            return result;
+        }
+        return this;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x().isConstant() && !y().isConstant()) { // move constants to the left (y)
+            return graph().unique(new CompareNode(y(), condition.mirror(), unorderedIsTrue(), x()));
+        } else if (x().isConstant() && y().isConstant()) {
+            CiConstant constX = x().asConstant();
+            CiConstant constY = y().asConstant();
+            Boolean result = condition().foldCondition(constX, constY, tool.runtime(), unorderedIsTrue());
+            if (result != null) {
+                return ConstantNode.forBoolean(result, graph());
+            }
+        }
+
+        if (y().isConstant()) {
+            if (x() instanceof MaterializeNode) {
+                return optimizeMaterialize(y().asConstant(), (MaterializeNode) x(), tool.runtime());
+            } else if (x() instanceof NormalizeCompareNode) {
+                return optimizeNormalizeCmp(y().asConstant(), (NormalizeCompareNode) x());
+            }
+        }
+
+        if (x() == y() && x().kind() != CiKind.Float && x().kind() != CiKind.Double) {
+            return ConstantNode.forBoolean(condition().check(1, 1), graph());
+        }
+        if ((condition == Condition.NE || condition == Condition.EQ) && x().kind() == CiKind.Object) {
+            ValueNode object = null;
+            if (x().isNullConstant()) {
+                object = y();
+            } else if (y().isNullConstant()) {
+                object = x();
+            }
+            if (object != null) {
+                return graph().unique(new NullCheckNode(object, condition == Condition.EQ));
+            } else {
+                Stamp xStamp = x.stamp();
+                Stamp yStamp = y.stamp();
+                if (xStamp.alwaysDistinct(yStamp)) {
+                    return ConstantNode.forBoolean(condition == Condition.NE, graph());
+                }
+            }
+        }
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/Condition.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.cri.util.*;
+
+/**
+ * Condition codes used in conditionals.
+ */
+public enum Condition {
+    /**
+     * Equal.
+     */
+    EQ("=="),
+
+    /**
+     * Not equal.
+     */
+    NE("!="),
+
+    /**
+     * Signed less than.
+     */
+    LT("<"),
+
+    /**
+     * Signed less than or equal.
+     */
+    LE("<="),
+
+    /**
+     * Signed greater than.
+     */
+    GT(">"),
+
+    /**
+     * Signed greater than or equal.
+     */
+    GE(">="),
+
+    /**
+     * Unsigned greater than or equal ("above than or equal").
+     */
+    AE("|>=|"),
+
+    /**
+     * Unsigned less than or equal ("below than or equal").
+     */
+    BE("|<=|"),
+
+    /**
+     * Unsigned greater than ("above than").
+     */
+    AT("|>|"),
+
+    /**
+     * Unsigned less than ("below than").
+     */
+    BT("|<|"),
+
+    /**
+     * Operation produced an overflow.
+     */
+    OF("overflow"),
+
+    /**
+     * Operation did not produce an overflow.
+     */
+    NOF("noOverflow");
+
+    public final String operator;
+
+    private Condition(String operator) {
+        this.operator = operator;
+    }
+
+    public boolean check(int left, int right) {
+        switch (this) {
+            case EQ: return left == right;
+            case NE: return left != right;
+            case LT: return left < right;
+            case LE: return left <= right;
+            case GT: return left > right;
+            case GE: return left >= right;
+            case AE: return UnsignedMath.aboveOrEqual(left, right);
+            case BE: return UnsignedMath.belowOrEqual(left, right);
+            case AT: return UnsignedMath.aboveThan(left, right);
+            case BT: return UnsignedMath.belowThan(left, right);
+        }
+        throw new IllegalArgumentException();
+    }
+
+    /**
+     * Negate this conditional.
+     * @return the condition that represents the negation
+     */
+    public final Condition negate() {
+        switch (this) {
+            case EQ: return NE;
+            case NE: return EQ;
+            case LT: return GE;
+            case LE: return GT;
+            case GT: return LE;
+            case GE: return LT;
+            case BT: return AE;
+            case BE: return AT;
+            case AT: return BE;
+            case AE: return BT;
+            case OF: return NOF;
+            case NOF: return OF;
+        }
+        throw new IllegalArgumentException(this.toString());
+    }
+
+    public boolean implies(Condition other) {
+        if (other == this) {
+            return true;
+        }
+        switch (this) {
+            case EQ: return other == LE || other == GE || other == BE || other == AE;
+            case NE: return false;
+            case LT: return other == LE;
+            case LE: return false;
+            case GT: return other == GE;
+            case GE: return false;
+            case BT: return other == BE;
+            case BE: return false;
+            case AT: return other == AE;
+            case AE: return false;
+            case OF: return false;
+            case NOF: return false;
+        }
+        throw new IllegalArgumentException(this.toString());
+    }
+
+    /**
+     * Mirror this conditional (i.e. commute "a op b" to "b op' a")
+     * @return the condition representing the equivalent commuted operation
+     */
+    public final Condition mirror() {
+        switch (this) {
+            case EQ: return EQ;
+            case NE: return NE;
+            case LT: return GT;
+            case LE: return GE;
+            case GT: return LT;
+            case GE: return LE;
+            case BT: return AT;
+            case BE: return AE;
+            case AT: return BT;
+            case AE: return BE;
+        }
+        throw new IllegalArgumentException();
+    }
+
+    /**
+     * Checks if this conditional operation is commutative.
+     * @return {@code true} if this operation is commutative
+     */
+    public final boolean isCommutative() {
+        return this == EQ || this == NE;
+    }
+
+    /**
+     * Attempts to fold a comparison between two constants and return the result.
+     * @param lt the constant on the left side of the comparison
+     * @param rt the constant on the right side of the comparison
+     * @param runtime the RiRuntime (might be needed to compare runtime-specific types)
+     * @return {@link Boolean#TRUE} if the comparison is known to be true,
+     * {@link Boolean#FALSE} if the comparison is known to be false, {@code null} otherwise.
+     */
+    public Boolean foldCondition(CiConstant lt, CiConstant rt, RiRuntime runtime, boolean unorderedIsTrue) {
+        switch (lt.kind) {
+            case Boolean:
+            case Byte:
+            case Char:
+            case Short:
+            case Jsr:
+            case Int: {
+                int x = lt.asInt();
+                int y = rt.asInt();
+                switch (this) {
+                    case EQ: return x == y;
+                    case NE: return x != y;
+                    case LT: return x < y;
+                    case LE: return x <= y;
+                    case GT: return x > y;
+                    case GE: return x >= y;
+                    case AE: return UnsignedMath.aboveOrEqual(x, y);
+                    case BE: return UnsignedMath.belowOrEqual(x, y);
+                    case AT: return UnsignedMath.aboveThan(x, y);
+                    case BT: return UnsignedMath.belowThan(x, y);
+                }
+                break;
+            }
+            case Long: {
+                long x = lt.asLong();
+                long y = rt.asLong();
+                switch (this) {
+                    case EQ: return x == y;
+                    case NE: return x != y;
+                    case LT: return x < y;
+                    case LE: return x <= y;
+                    case GT: return x > y;
+                    case GE: return x >= y;
+                    case AE: return UnsignedMath.aboveOrEqual(x, y);
+                    case BE: return UnsignedMath.belowOrEqual(x, y);
+                    case AT: return UnsignedMath.aboveThan(x, y);
+                    case BT: return UnsignedMath.belowThan(x, y);
+                }
+                break;
+            }
+            case Object: {
+                switch (this) {
+                    case EQ: return runtime.areConstantObjectsEqual(lt, rt);
+                    case NE: return !runtime.areConstantObjectsEqual(lt, rt);
+                }
+                break;
+            }
+            case Float: {
+                float x = lt.asFloat();
+                float y = rt.asFloat();
+                if (Float.isNaN(x) || Float.isNaN(y)) {
+                    return unorderedIsTrue;
+                }
+                switch (this) {
+                    case EQ: return x == y;
+                    case NE: return x != y;
+                    case LT: return x < y;
+                    case LE: return x <= y;
+                    case GT: return x > y;
+                    case GE: return x >= y;
+                }
+            }
+            case Double: {
+                double x = lt.asDouble();
+                double y = rt.asDouble();
+                if (Double.isNaN(x) || Double.isNaN(y)) {
+                    return unorderedIsTrue;
+                }
+                switch (this) {
+                    case EQ: return x == y;
+                    case NE: return x != y;
+                    case LT: return x < y;
+                    case LE: return x <= y;
+                    case GT: return x > y;
+                    case GE: return x >= y;
+                }
+            }
+        }
+        assert false : "missed folding of constant operands: " + lt + " " + this + " " + rt;
+        return null;
+    }
+
+    public Condition join(Condition other) {
+        if (other == this) {
+            return this;
+        }
+        if (this == OF || this == NOF || other == OF || other == NOF) {
+            return null;
+        }
+        switch (this) {
+            case EQ:
+                if (other == LE || other == GE || other == BE || other == AE) {
+                    return EQ;
+                } else {
+                    return null;
+                }
+            case NE:
+                if (other == LT || other == GT || other == BT || other == AT) {
+                    return other;
+                } else if (other == LE) {
+                    return LT;
+                } else if (other == GE) {
+                    return GT;
+                } else if (other == BE) {
+                    return BT;
+                } else if (other == AE) {
+                    return AT;
+                } else {
+                    return null;
+                }
+            case LE:
+                if (other == GE || other == EQ) {
+                    return EQ;
+                } else if (other == NE || other == LT) {
+                    return LT;
+                } else {
+                    return null;
+                }
+            case LT:
+                if (other == NE || other == LE) {
+                    return LT;
+                } else {
+                    return null;
+                }
+            case GE:
+                if (other == LE || other == EQ) {
+                    return EQ;
+                } else if (other == NE || other == GT) {
+                    return GT;
+                } else {
+                    return null;
+                }
+            case GT:
+                if (other == NE || other == GE) {
+                    return GT;
+                } else {
+                    return null;
+                }
+            case BE:
+                if (other == AE || other == EQ) {
+                    return EQ;
+                } else if (other == NE || other == BT) {
+                    return BT;
+                } else {
+                    return null;
+                }
+            case BT:
+                if (other == NE || other == BE) {
+                    return BT;
+                } else {
+                    return null;
+                }
+            case AE:
+                if (other == BE || other == EQ) {
+                    return EQ;
+                } else if (other == NE || other == AT) {
+                    return AT;
+                } else {
+                    return null;
+                }
+            case AT:
+                if (other == NE || other == AE) {
+                    return AT;
+                } else {
+                    return null;
+                }
+        }
+        throw new IllegalArgumentException(this.toString());
+    }
+
+    public Condition meet(Condition other) {
+        if (other == this) {
+            return this;
+        }
+        if (this == OF || this == NOF || other == OF || other == NOF) {
+            return null;
+        }
+        switch (this) {
+            case EQ:
+                if (other == LE || other == GE || other == BE || other == AE) {
+                    return other;
+                } else if (other == LT) {
+                    return LE;
+                } else if (other == GT) {
+                    return GE;
+                } else if (other == BT) {
+                    return BE;
+                } else if (other == AT) {
+                    return AE;
+                } else {
+                    return null;
+                }
+            case NE:
+                if (other == LT || other == GT || other == BT || other == AT) {
+                    return NE;
+                } else {
+                    return null;
+                }
+            case LE:
+                if (other == EQ || other == LT) {
+                    return LE;
+                } else {
+                    return null;
+                }
+            case LT:
+                if (other == EQ || other == LE) {
+                    return LE;
+                } else if (other == NE || other == GT) {
+                    return NE;
+                } else {
+                    return null;
+                }
+            case GE:
+                if (other == EQ || other == GT) {
+                    return GE;
+                } else {
+                    return null;
+                }
+            case GT:
+                if (other == EQ || other == GE) {
+                    return GE;
+                } else if (other == NE || other == LT) {
+                    return NE;
+                } else {
+                    return null;
+                }
+            case BE:
+                if (other == EQ || other == BT) {
+                    return BE;
+                } else {
+                    return null;
+                }
+            case BT:
+                if (other == EQ || other == BE) {
+                    return BE;
+                } else if (other == NE || other == AT) {
+                    return NE;
+                } else {
+                    return null;
+                }
+            case AE:
+                if (other == EQ || other == AT) {
+                    return AE;
+                } else {
+                    return null;
+                }
+            case AT:
+                if (other == EQ || other == AE) {
+                    return AE;
+                } else if (other == NE || other == BT) {
+                    return NE;
+                } else {
+                    return null;
+                }
+        }
+        throw new IllegalArgumentException(this.toString());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/ConditionalNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.PhiNode.PhiType;
+import com.oracle.max.graal.nodes.spi.*;
+
+/**
+ * The {@code ConditionalNode} class represents a comparison that yields one of two values. Note that these nodes are not
+ * built directly from the bytecode but are introduced by canonicalization.
+ */
+public class ConditionalNode extends BinaryNode implements Canonicalizable, LIRLowerable {
+
+    @Input private BooleanNode condition;
+
+    public BooleanNode condition() {
+        return condition;
+    }
+
+    public ConditionalNode(BooleanNode condition, ValueNode trueValue, ValueNode falseValue) {
+        super(trueValue.kind(), trueValue, falseValue);
+        assert trueValue.kind() == falseValue.kind();
+        this.condition = condition;
+    }
+
+    public ValueNode trueValue() {
+        return x();
+    }
+
+    public ValueNode falseValue() {
+        return y();
+    }
+
+    public static class ConditionalStructure {
+
+        public final IfNode ifNode;
+        public final PhiNode phi;
+        public final MergeNode merge;
+
+        public ConditionalStructure(IfNode ifNode, PhiNode phi, MergeNode merge) {
+            this.ifNode = ifNode;
+            this.phi = phi;
+            this.merge = merge;
+        }
+    }
+
+    public static ConditionalStructure createConditionalStructure(BooleanNode condition, ValueNode trueValue, ValueNode falseValue) {
+        return createConditionalStructure(condition, trueValue, falseValue, 0.5);
+    }
+
+    public static ConditionalStructure createConditionalStructure(BooleanNode condition, ValueNode trueValue, ValueNode falseValue, double trueProbability) {
+        Graph graph = condition.graph();
+        assert trueValue.kind() == falseValue.kind();
+        CiKind kind = trueValue.kind();
+        IfNode ifNode = graph.add(new IfNode(condition, trueProbability));
+        EndNode trueEnd = graph.add(new EndNode());
+        EndNode falseEnd = graph.add(new EndNode());
+        ifNode.setTrueSuccessor(BeginNode.begin(trueEnd));
+        ifNode.setFalseSuccessor(BeginNode.begin(falseEnd));
+        MergeNode merge = graph.add(new MergeNode());
+        merge.addForwardEnd(trueEnd);
+        merge.addForwardEnd(falseEnd);
+        PhiNode phi = graph.unique(new PhiNode(kind, merge, PhiType.Value));
+        phi.addInput(trueValue);
+        phi.addInput(falseValue);
+        return new ConditionalStructure(ifNode, phi, merge);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (condition instanceof ConstantNode) {
+            ConstantNode c = (ConstantNode) condition;
+            if (c.asConstant().asBoolean()) {
+                return trueValue();
+            } else {
+                return falseValue();
+            }
+        }
+        if (trueValue() == falseValue()) {
+            return trueValue();
+        }
+
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool generator) {
+        generator.emitConditional(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/ConvertNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.calc;
+
+import static com.oracle.max.cri.ci.CiKind.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code ConvertNode} class represents a conversion between primitive types.
+ */
+public final class ConvertNode extends FloatingNode implements Canonicalizable, LIRLowerable {
+
+    public enum Op {
+        I2L(Int, Long),
+        L2I(Long, Int),
+        I2B(Int, Byte),
+        I2C(Int, Char),
+        I2S(Int, Short),
+        F2D(Float, Double),
+        D2F(Double, Float),
+        I2F(Int, Float),
+        I2D(Int, Double),
+        F2I(Float, Int),
+        D2I(Double, Int),
+        L2F(Long, Float),
+        L2D(Long, Double),
+        F2L(Float, Long),
+        D2L(Double, Long),
+        MOV_I2F(Int, Float),
+        MOV_L2D(Long, Double),
+        MOV_F2I(Float, Int),
+        MOV_D2L(Double, Long);
+
+        public final CiKind from;
+        public final CiKind to;
+
+        private Op(CiKind from, CiKind to) {
+            this.from = from;
+            this.to = to;
+        }
+    }
+
+    @Input private ValueNode value;
+
+    @Data public final Op opcode;
+
+    public ValueNode value() {
+        return value;
+    }
+
+    /**
+     * Constructs a new Convert instance.
+     * @param kind the result type of this instruction
+     * @param opcode the operation
+     * @param value the instruction producing the input value
+     * @param graph
+     */
+    public ConvertNode(Op opcode, ValueNode value) {
+        super(StampFactory.forKind(opcode.to.stackKind()));
+        assert value.kind() == opcode.from : opcode + " : " + value.kind() + " != " + opcode.from;
+        this.opcode = opcode;
+        this.value = value;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (value instanceof ConstantNode) {
+            CiConstant c = ((ConstantNode) value).asConstant();
+            switch (opcode) {
+                case I2L: return ConstantNode.forLong(c.asInt(), graph());
+                case L2I: return ConstantNode.forInt((int) c.asLong(), graph());
+                case I2B: return ConstantNode.forByte((byte) c.asInt(), graph());
+                case I2C: return ConstantNode.forChar((char) c.asInt(), graph());
+                case I2S: return ConstantNode.forShort((short) c.asInt(), graph());
+                case F2D: return ConstantNode.forDouble(c.asFloat(), graph());
+                case D2F: return ConstantNode.forFloat((float) c.asDouble(), graph());
+                case I2F: return ConstantNode.forFloat(c.asInt(), graph());
+                case I2D: return ConstantNode.forDouble(c.asInt(), graph());
+                case F2I: return ConstantNode.forInt((int) c.asFloat(), graph());
+                case D2I: return ConstantNode.forInt((int) c.asDouble(), graph());
+                case L2F: return ConstantNode.forFloat(c.asLong(), graph());
+                case L2D: return ConstantNode.forDouble(c.asLong(), graph());
+                case F2L: return ConstantNode.forLong((long) c.asFloat(), graph());
+                case D2L: return ConstantNode.forLong((long) c.asDouble(), graph());
+                case MOV_I2F: return ConstantNode.forFloat(java.lang.Float.intBitsToFloat(c.asInt()), graph());
+                case MOV_L2D: return ConstantNode.forDouble(java.lang.Double.longBitsToDouble(c.asLong()), graph());
+                case MOV_F2I: return ConstantNode.forInt(java.lang.Float.floatToRawIntBits(c.asFloat()), graph());
+                case MOV_D2L: return ConstantNode.forLong(java.lang.Double.doubleToRawLongBits(c.asDouble()), graph());
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.setResult(this, gen.emitConvert(opcode, gen.operand(value())));
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static <S, T> S convert(@ConstantNodeParameter Op op, T value) {
+        throw new UnsupportedOperationException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatAddNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "+")
+public final class FloatAddNode extends FloatArithmeticNode implements Canonicalizable, LIRLowerable {
+
+    public FloatAddNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
+        super(kind, x, y, isStrictFP);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x().isConstant() && !y().isConstant()) {
+            return graph().unique(new FloatAddNode(kind(), y(), x(), isStrictFP()));
+        }
+        if (x().isConstant()) {
+            if (kind() == CiKind.Float) {
+                return ConstantNode.forFloat(x().asConstant().asFloat() + y().asConstant().asFloat(), graph());
+            } else {
+                assert kind() == CiKind.Double;
+                return ConstantNode.forDouble(x().asConstant().asDouble() + y().asConstant().asDouble(), graph());
+            }
+        } else if (y().isConstant()) {
+            if (kind() == CiKind.Float) {
+                float c = y().asConstant().asFloat();
+                if (c == 0.0f) {
+                    return x();
+                }
+            } else {
+                assert kind() == CiKind.Double;
+                double c = y().asConstant().asDouble();
+                if (c == 0.0) {
+                    return x();
+                }
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        CiValue op1 = gen.operand(x());
+        CiValue op2 = gen.operand(y());
+        if (!y().isConstant() && !livesLonger(this, y(), gen)) {
+            CiValue op = op1;
+            op1 = op2;
+            op2 = op;
+        }
+        gen.setResult(this, gen.emitAdd(op1, op2));
+    }
+
+    public static boolean livesLonger(ValueNode after, ValueNode value, LIRGeneratorTool gen) {
+        for (Node usage : value.usages()) {
+            if (usage != after && usage instanceof ValueNode && gen.operand(((ValueNode) usage)) != null) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatArithmeticNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,34 @@
+/*
+ * 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+
+public abstract class FloatArithmeticNode extends ArithmeticNode {
+
+    public FloatArithmeticNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
+        super(kind, x, y, isStrictFP);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatDivNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "/")
+public final class FloatDivNode extends FloatArithmeticNode implements Canonicalizable, LIRLowerable {
+
+    public FloatDivNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
+        super(kind, x, y, isStrictFP);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x().isConstant() && y().isConstant()) {
+            if (kind() == CiKind.Float) {
+                if (y().asConstant().asFloat() != 0) {
+                    return ConstantNode.forFloat(x().asConstant().asFloat() / y().asConstant().asFloat(), graph());
+                }
+            } else {
+                assert kind() == CiKind.Double;
+                if (y().asConstant().asDouble() != 0) {
+                    return ConstantNode.forDouble(x().asConstant().asDouble() / y().asConstant().asDouble(), graph());
+                }
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.setResult(this, gen.emitDiv(gen.operand(x()), gen.operand(y())));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatMulNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,64 @@
+/*
+ * 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "*")
+public final class FloatMulNode extends FloatArithmeticNode implements Canonicalizable, LIRLowerable {
+
+    public FloatMulNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
+        super(kind, x, y, isStrictFP);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x().isConstant() && !y().isConstant()) {
+            return graph().unique(new FloatMulNode(kind(), y(), x(), isStrictFP()));
+        }
+        if (x().isConstant()) {
+            if (kind() == CiKind.Float) {
+                return ConstantNode.forFloat(x().asConstant().asFloat() * y().asConstant().asFloat(), graph());
+            } else {
+                assert kind() == CiKind.Double;
+                return ConstantNode.forDouble(x().asConstant().asDouble() * y().asConstant().asDouble(), graph());
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        CiValue op1 = gen.operand(x());
+        CiValue op2 = gen.operand(y());
+        if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), gen)) {
+            CiValue op = op1;
+            op1 = op2;
+            op2 = op;
+        }
+        gen.setResult(this, gen.emitMul(op1, op2));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatRemNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "%")
+public final class FloatRemNode extends FloatArithmeticNode implements Canonicalizable, LIRLowerable {
+
+    public FloatRemNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
+        super(kind, x, y, isStrictFP);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x().isConstant() && y().isConstant()) {
+            if (kind() == CiKind.Float) {
+                return ConstantNode.forFloat(x().asConstant().asFloat() % y().asConstant().asFloat(), graph());
+            } else {
+                assert kind() == CiKind.Double;
+                return ConstantNode.forDouble(x().asConstant().asDouble() % y().asConstant().asDouble(), graph());
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.setResult(this, gen.emitRem(gen.operand(x()), gen.operand(y())));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatSubNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,72 @@
+/*
+ * 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "-")
+public final class FloatSubNode extends FloatArithmeticNode implements Canonicalizable, LIRLowerable {
+
+    public FloatSubNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
+        super(kind, x, y, isStrictFP);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x() == y()) {
+            return ConstantNode.forFloatingKind(kind(), 0.0f, graph());
+        }
+        if (x().isConstant() && y().isConstant()) {
+            if (kind() == CiKind.Float) {
+                return ConstantNode.forFloat(x().asConstant().asFloat() - y().asConstant().asFloat(), graph());
+            } else {
+                assert kind() == CiKind.Double;
+                return ConstantNode.forDouble(x().asConstant().asDouble() - y().asConstant().asDouble(), graph());
+            }
+        } else if (y().isConstant()) {
+            if (kind() == CiKind.Float) {
+                float c = y().asConstant().asFloat();
+                if (c == 0.0f) {
+                    return x();
+                }
+                return graph().unique(new FloatAddNode(kind(), x(), ConstantNode.forFloat(-c, graph()), isStrictFP()));
+            } else {
+                assert kind() == CiKind.Double;
+                double c = y().asConstant().asDouble();
+                if (c == 0.0) {
+                    return x();
+                }
+                return graph().unique(new FloatAddNode(kind(), x(), ConstantNode.forDouble(-c, graph()), isStrictFP()));
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.setResult(this, gen.emitSub(gen.operand(x()), gen.operand(y())));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatingNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.max.graal.nodes.calc;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public abstract class FloatingNode extends ValueNode implements Node.ValueNumberable {
+    public FloatingNode(Stamp stamp) {
+        super(stamp);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerAddNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "+")
+public class IntegerAddNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable {
+
+    public IntegerAddNode(CiKind kind, ValueNode x, ValueNode y) {
+        super(kind, x, y);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x().isConstant() && !y().isConstant()) {
+            return graph().unique(new IntegerAddNode(kind(), y(), x()));
+        }
+        if (x().isConstant()) {
+            if (kind() == CiKind.Int) {
+                return ConstantNode.forInt(x().asConstant().asInt() + y().asConstant().asInt(), graph());
+            } else {
+                assert kind() == CiKind.Long;
+                return ConstantNode.forLong(x().asConstant().asLong() + y().asConstant().asLong(), graph());
+            }
+        } else if (y().isConstant()) {
+            if (kind() == CiKind.Int) {
+                int c = y().asConstant().asInt();
+                if (c == 0) {
+                    return x();
+                }
+            } else {
+                assert kind() == CiKind.Long;
+                long c = y().asConstant().asLong();
+                if (c == 0) {
+                    return x();
+                }
+            }
+        }
+        return this;
+    }
+
+    public static boolean isIntegerAddition(ValueNode result, ValueNode a, ValueNode b) {
+        CiKind kind = result.kind();
+        if (kind != a.kind() || kind != b.kind() || !(kind.isInt() || kind.isLong())) {
+            return false;
+        }
+        if (result.isConstant() && a.isConstant() && b.isConstant()) {
+            if (kind.isInt()) {
+                return result.asConstant().asInt() == a.asConstant().asInt() + b.asConstant().asInt();
+            } else if (kind.isLong()) {
+                return result.asConstant().asLong() == a.asConstant().asLong() + b.asConstant().asLong();
+            }
+        } else if (result instanceof IntegerAddNode) {
+            IntegerAddNode add = (IntegerAddNode) result;
+            return (add.x() == a && add.y() == b) || (add.y() == a && add.x() == b);
+        }
+        return false;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        CiValue op1 = gen.operand(x());
+        assert op1 != null : x() + ", this=" + this;
+        CiValue op2 = gen.operand(y());
+        if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), gen)) {
+            CiValue op = op1;
+            op1 = op2;
+            op2 = op;
+        }
+        gen.setResult(this, gen.emitAdd(op1, op2));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerArithmeticNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+
+
+public abstract class IntegerArithmeticNode extends ArithmeticNode {
+
+    public IntegerArithmeticNode(CiKind kind, ValueNode x, ValueNode y) {
+        super(kind, x, y, false);
+        assert kind == CiKind.Int || kind == CiKind.Long;
+    }
+
+    public static IntegerAddNode add(ValueNode v1, ValueNode v2) {
+        assert v1.kind() == v2.kind() && v1.graph() == v2.graph();
+        Graph graph = v1.graph();
+        //TODO (gd) handle conversions here instead of strong assert ?
+        switch(v1.kind()) {
+            case Int:
+                return graph.unique(new IntegerAddNode(CiKind.Int, v1, v2));
+            case Long:
+                return graph.unique(new IntegerAddNode(CiKind.Long, v1, v2));
+            default:
+                throw ValueUtil.shouldNotReachHere();
+        }
+    }
+
+    public static IntegerMulNode mul(ValueNode v1, ValueNode v2) {
+        assert v1.kind() == v2.kind() && v1.graph() == v2.graph();
+        Graph graph = v1.graph();
+        //TODO (gd) handle conversions here instead of strong assert ?
+        switch(v1.kind()) {
+            case Int:
+                return graph.unique(new IntegerMulNode(CiKind.Int, v1, v2));
+            case Long:
+                return graph.unique(new IntegerMulNode(CiKind.Long, v1, v2));
+            default:
+                throw ValueUtil.shouldNotReachHere();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerDivNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "/")
+public final class IntegerDivNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable {
+
+    public IntegerDivNode(CiKind kind, ValueNode x, ValueNode y) {
+        super(kind, x, y);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x().isConstant() && y().isConstant()) {
+            long yConst = y().asConstant().asLong();
+            if (yConst == 0) {
+                return this; // this will trap, can not canonicalize
+            }
+            if (kind() == CiKind.Int) {
+                return ConstantNode.forInt(x().asConstant().asInt() / (int) yConst, graph());
+            } else {
+                assert kind() == CiKind.Long;
+                return ConstantNode.forLong(x().asConstant().asLong() / yConst, graph());
+            }
+        } else if (y().isConstant()) {
+            long c = y().asConstant().asLong();
+            if (c == 1) {
+                return x();
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.setResult(this, gen.emitDiv(gen.operand(x()), gen.operand(y())));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerMulNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,75 @@
+/*
+ * 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "*")
+public final class IntegerMulNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable {
+
+    public IntegerMulNode(CiKind kind, ValueNode x, ValueNode y) {
+        super(kind, x, y);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x().isConstant() && !y().isConstant()) {
+            return graph().unique(new IntegerMulNode(kind(), y(), x()));
+        }
+        if (x().isConstant()) {
+            if (kind() == CiKind.Int) {
+                return ConstantNode.forInt(x().asConstant().asInt() * y().asConstant().asInt(), graph());
+            } else {
+                assert kind() == CiKind.Long;
+                return ConstantNode.forLong(x().asConstant().asLong() * y().asConstant().asLong(), graph());
+            }
+        } else if (y().isConstant()) {
+            long c = y().asConstant().asLong();
+            if (c == 1) {
+                return x();
+            }
+            if (c == 0) {
+                return ConstantNode.forInt(0, graph());
+            }
+            if (c > 0 && CiUtil.isPowerOf2(c)) {
+                return graph().unique(new LeftShiftNode(kind(), x(), ConstantNode.forInt(CiUtil.log2(c), graph())));
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        CiValue op1 = gen.operand(x());
+        CiValue op2 = gen.operand(y());
+        if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), gen)) {
+            CiValue op = op1;
+            op1 = op2;
+            op2 = op;
+        }
+        gen.setResult(this, gen.emitMul(op1, op2));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerRemNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "%")
+public final class IntegerRemNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable {
+
+    public IntegerRemNode(CiKind kind, ValueNode x, ValueNode y) {
+        super(kind, x, y);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x().isConstant() && y().isConstant()) {
+            long yConst = y().asConstant().asLong();
+            if (yConst == 0) {
+                return this; // this will trap, can not canonicalize
+            }
+            if (kind() == CiKind.Int) {
+                return ConstantNode.forInt(x().asConstant().asInt() % (int) yConst, graph());
+            } else {
+                assert kind() == CiKind.Long;
+                return ConstantNode.forLong(x().asConstant().asLong() % yConst, graph());
+            }
+        } else if (y().isConstant()) {
+            long c = y().asConstant().asLong();
+            if (c == 1 || c == -1) {
+                return ConstantNode.forIntegerKind(kind(), 0, graph());
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.setResult(this, gen.emitRem(gen.operand(x()), gen.operand(y())));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/IntegerSubNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "-")
+public final class IntegerSubNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable {
+
+    public IntegerSubNode(CiKind kind, ValueNode x, ValueNode y) {
+        super(kind, x, y);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x() == y()) {
+            return ConstantNode.forIntegerKind(kind(), 0, graph());
+        }
+        if (x().isConstant() && y().isConstant()) {
+            if (kind() == CiKind.Int) {
+                return ConstantNode.forInt(x().asConstant().asInt() - y().asConstant().asInt(), graph());
+            } else {
+                assert kind() == CiKind.Long;
+                return ConstantNode.forLong(x().asConstant().asLong() - y().asConstant().asLong(), graph());
+            }
+        } else if (y().isConstant()) {
+            long c = y().asConstant().asLong();
+            if (c == 0) {
+                return x();
+            }
+            if (kind() == CiKind.Int) {
+                return graph().unique(new IntegerAddNode(kind(), x(), ConstantNode.forInt((int) -c, graph())));
+            } else {
+                assert kind() == CiKind.Long;
+                return graph().unique(new IntegerAddNode(kind(), x(), ConstantNode.forLong(-c, graph())));
+            }
+        } else if (x().isConstant()) {
+            long c = x().asConstant().asLong();
+            if (c == 0) {
+                return graph().unique(new NegateNode(y()));
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.setResult(this, gen.emitSub(gen.operand(x()), gen.operand(y())));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/LeftShiftNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,92 @@
+/*
+ * 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "<<")
+public final class LeftShiftNode extends ShiftNode implements Canonicalizable, LIRLowerable {
+
+    public LeftShiftNode(CiKind kind, ValueNode x, ValueNode y) {
+        super(kind, x, y);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (y().isConstant()) {
+            int amount = y().asConstant().asInt();
+            int originalAmout = amount;
+            int mask;
+            if (kind() == CiKind.Int) {
+                mask = 0x1f;
+            } else {
+                assert kind() == CiKind.Long;
+                mask = 0x3f;
+            }
+            amount &= mask;
+            if (x().isConstant()) {
+                if (kind() == CiKind.Int) {
+                    return ConstantNode.forInt(x().asConstant().asInt() << amount, graph());
+                } else {
+                    assert kind() == CiKind.Long;
+                    return ConstantNode.forLong(x().asConstant().asLong() << amount, graph());
+                }
+            }
+            if (amount == 0) {
+                return x();
+            }
+            if (x() instanceof ShiftNode) {
+                ShiftNode other = (ShiftNode) x();
+                if (other.y().isConstant()) {
+                    int otherAmount = other.y().asConstant().asInt() & mask;
+                    if (other instanceof LeftShiftNode) {
+                        int total = amount + otherAmount;
+                        if (total != (total & mask)) {
+                            return ConstantNode.forInt(0, graph());
+                        }
+                        return graph().unique(new LeftShiftNode(kind(), other.x(), ConstantNode.forInt(total, graph())));
+                    } else if ((other instanceof RightShiftNode || other instanceof UnsignedRightShiftNode) && otherAmount == amount) {
+                        if (kind() == CiKind.Long) {
+                            return graph().unique(new AndNode(kind(), other.x(), ConstantNode.forLong(-1L << amount, graph())));
+                        } else {
+                            assert kind() == CiKind.Int;
+                            return graph().unique(new AndNode(kind(), other.x(), ConstantNode.forInt(-1 << amount, graph())));
+                        }
+                    }
+                }
+            }
+            if (originalAmout != amount) {
+                return graph().unique(new LeftShiftNode(kind(), x(), ConstantNode.forInt(amount, graph())));
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.setResult(this, gen.emitShl(gen.operand(x()), gen.operand(y())));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/LogicNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+
+/**
+ * The {@code LogicNode} class definition.
+ */
+public abstract class LogicNode extends BinaryNode {
+
+    /**
+     * Constructs a new logic operation node.
+     * @param x the first input into this node
+     * @param y the second input into this node
+     */
+    public LogicNode(CiKind kind, ValueNode x, ValueNode y) {
+        super(kind, x, y);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/NegateNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.calc;
+
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code NegateNode} node negates its operand.
+ */
+public final class NegateNode extends FloatingNode implements Canonicalizable, LIRLowerable {
+
+    @Input
+    private ValueNode x;
+
+    public ValueNode x() {
+        return x;
+    }
+
+    /**
+     * Creates new NegateOp instance.
+     *
+     * @param x the instruction producing the value that is input to this instruction
+     */
+    public NegateNode(ValueNode x) {
+        super(StampFactory.forKind(x.kind()));
+        this.x = x;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x().isConstant()) {
+            switch (x().kind()) {
+                case Int:
+                    return ConstantNode.forInt(-x().asConstant().asInt(), graph());
+                case Long:
+                    return ConstantNode.forLong(-x().asConstant().asLong(), graph());
+                case Float:
+                    return ConstantNode.forFloat(-x().asConstant().asFloat(), graph());
+                case Double:
+                    return ConstantNode.forDouble(-x().asConstant().asDouble(), graph());
+            }
+        }
+        if (x() instanceof NegateNode) {
+            return ((NegateNode) x()).x();
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.setResult(this, gen.emitNegate(gen.operand(x())));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/NormalizeCompareNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+/**
+ * Returns -1, 0, or 1 if either x < y, x == y, or x > y.
+ */
+public final class NormalizeCompareNode extends BinaryNode implements Lowerable {
+    @Data public final boolean isUnorderedLess;
+
+    /**
+     * Creates a new compare operation.
+     * @param x the first input
+     * @param y the second input
+     * @param isUnorderedLess true when an unordered floating point comparison is interpreted as less, false when greater.
+     */
+    public NormalizeCompareNode(ValueNode x, ValueNode y, boolean isUnorderedLess) {
+        super(CiKind.Int, x, y);
+        this.isUnorderedLess = isUnorderedLess;
+    }
+
+    @Override
+    public void lower(CiLoweringTool tool) {
+        StructuredGraph graph = (StructuredGraph) graph();
+
+        CompareNode equalComp = graph.unique(new CompareNode(x(), Condition.EQ, false, y()));
+        MaterializeNode equalValue = MaterializeNode.create(equalComp, graph, ConstantNode.forInt(0, graph), ConstantNode.forInt(1, graph));
+
+        CompareNode lessComp = graph.unique(new CompareNode(x(), Condition.LT, isUnorderedLess, y()));
+        MaterializeNode value =  MaterializeNode.create(lessComp, graph, ConstantNode.forInt(-1, graph), equalValue);
+
+        graph.replaceFloating(this, value);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/NullCheckNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public final class NullCheckNode extends BooleanNode implements Canonicalizable, LIRLowerable {
+
+    @Input private ValueNode object;
+    @Data public final boolean expectedNull;
+
+    public ValueNode object() {
+        return object;
+    }
+
+    /**
+     * Constructs a new NullCheck instruction.
+     *
+     * @param object the instruction producing the object to check against null
+     * @param expectedNull True when this node checks that the value is null, false when this node checks for non-null
+     */
+    public NullCheckNode(ValueNode object, boolean expectedNull) {
+        super(StampFactory.illegal());
+        assert object.kind() == CiKind.Object : object.kind();
+        this.object = object;
+        this.expectedNull = expectedNull;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        // Nothing to do.
+    }
+
+    @Override
+    public boolean verify() {
+        assertTrue(object().kind().isObject(), "null check input must be an object");
+        return super.verify();
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        CiConstant constant = object().asConstant();
+        if (constant != null) {
+            assert constant.kind == CiKind.Object;
+            return ConstantNode.forBoolean(constant.isNull() == expectedNull, graph());
+        }
+        if (object.stamp().nonNull()) {
+            return ConstantNode.forBoolean(!expectedNull, graph());
+        }
+        return this;
+    }
+
+    @Override
+    public BooleanNode negate() {
+        return graph().unique(new NullCheckNode(object(), !expectedNull));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/OrNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "|")
+public final class OrNode extends LogicNode implements Canonicalizable, LIRLowerable {
+
+    public OrNode(CiKind kind, ValueNode x, ValueNode y) {
+        super(kind, x, y);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x() == y()) {
+            return x();
+        }
+        if (x().isConstant() && !y().isConstant()) {
+            return graph().unique(new OrNode(kind(), y(), x()));
+        }
+        if (x().isConstant()) {
+            if (kind() == CiKind.Int) {
+                return ConstantNode.forInt(x().asConstant().asInt() | y().asConstant().asInt(), graph());
+            } else {
+                assert kind() == CiKind.Long;
+                return ConstantNode.forLong(x().asConstant().asLong() | y().asConstant().asLong(), graph());
+            }
+        } else if (y().isConstant()) {
+            if (kind() == CiKind.Int) {
+                int c = y().asConstant().asInt();
+                if (c == -1) {
+                    return ConstantNode.forInt(-1, graph());
+                }
+                if (c == 0) {
+                    return x();
+                }
+            } else {
+                assert kind() == CiKind.Long;
+                long c = y().asConstant().asLong();
+                if (c == -1) {
+                    return ConstantNode.forLong(-1, graph());
+                }
+                if (c == 0) {
+                    return x();
+                }
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.setResult(this, gen.emitOr(gen.operand(x()), gen.operand(y())));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/RightShiftNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,85 @@
+/*
+ * 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+@NodeInfo(shortName = ">>")
+public final class RightShiftNode extends ShiftNode implements Canonicalizable, LIRLowerable {
+
+    public RightShiftNode(CiKind kind, ValueNode x, ValueNode y) {
+        super(kind, x, y);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (y().isConstant()) {
+            int amount = y().asConstant().asInt();
+            int originalAmout = amount;
+            int mask;
+            if (kind() == CiKind.Int) {
+                mask = 0x1f;
+            } else {
+                assert kind() == CiKind.Long;
+                mask = 0x3f;
+            }
+            amount &= mask;
+            if (x().isConstant()) {
+                if (kind() == CiKind.Int) {
+                    return ConstantNode.forInt(x().asConstant().asInt() >> amount, graph());
+                } else {
+                    assert kind() == CiKind.Long;
+                    return ConstantNode.forLong(x().asConstant().asLong() >> amount, graph());
+                }
+            }
+            if (amount == 0) {
+                return x();
+            }
+            if (x() instanceof ShiftNode) {
+                ShiftNode other = (ShiftNode) x();
+                if (other.y().isConstant()) {
+                    int otherAmount = other.y().asConstant().asInt() & mask;
+                    if (other instanceof RightShiftNode) {
+                        int total = amount + otherAmount;
+                        if (total != (total & mask)) {
+                            return ConstantNode.forInt(0, graph());
+                        }
+                        return graph().unique(new RightShiftNode(kind(), other.x(), ConstantNode.forInt(total, graph())));
+                    }
+                }
+            }
+            if (originalAmout != amount) {
+                return graph().unique(new RightShiftNode(kind(), x(), ConstantNode.forInt(amount, graph())));
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.setResult(this, gen.emitShr(gen.operand(x()), gen.operand(y())));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/ShiftNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+
+/**
+ * The {@code ShiftOp} class represents shift operations.
+ */
+public abstract class ShiftNode extends BinaryNode {
+
+    /**
+     * Creates a new shift operation.
+     * @param x the first input value
+     * @param s the second input value
+     */
+    public ShiftNode(CiKind kind, ValueNode x, ValueNode s) {
+        super(kind, x, s);
+        // TODO(cwi) Why check for null here - what is a shift with no left operand?
+        assert x == null || x.kind() == kind;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/UnsignedRightShiftNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,92 @@
+/*
+ * 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+@NodeInfo(shortName = ">>>")
+public final class UnsignedRightShiftNode extends ShiftNode implements Canonicalizable, LIRLowerable {
+
+    public UnsignedRightShiftNode(CiKind kind, ValueNode x, ValueNode y) {
+        super(kind, x, y);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (y().isConstant()) {
+            int amount = y().asConstant().asInt();
+            int originalAmout = amount;
+            int mask;
+            if (kind() == CiKind.Int) {
+                mask = 0x1f;
+            } else {
+                assert kind() == CiKind.Long;
+                mask = 0x3f;
+            }
+            amount &= mask;
+            if (x().isConstant()) {
+                if (kind() == CiKind.Int) {
+                    return ConstantNode.forInt(x().asConstant().asInt() >>> amount, graph());
+                } else {
+                    assert kind() == CiKind.Long;
+                    return ConstantNode.forLong(x().asConstant().asLong() >>> amount, graph());
+                }
+            }
+            if (amount == 0) {
+                return x();
+            }
+            if (x() instanceof ShiftNode) {
+                ShiftNode other = (ShiftNode) x();
+                if (other.y().isConstant()) {
+                    int otherAmount = other.y().asConstant().asInt() & mask;
+                    if (other instanceof UnsignedRightShiftNode) {
+                        int total = amount + otherAmount;
+                        if (total != (total & mask)) {
+                            return ConstantNode.forInt(0, graph());
+                        }
+                        return graph().unique(new UnsignedRightShiftNode(kind(), other.x(), ConstantNode.forInt(total, graph())));
+                    } else if (other instanceof LeftShiftNode && otherAmount == amount) {
+                        if (kind() == CiKind.Long) {
+                            return graph().unique(new AndNode(kind(), other.x(), ConstantNode.forLong(-1L >>> amount, graph())));
+                        } else {
+                            assert kind() == CiKind.Int;
+                            return graph().unique(new AndNode(kind(), other.x(), ConstantNode.forInt(-1 >>> amount, graph())));
+                        }
+                    }
+                }
+            }
+            if (originalAmout != amount) {
+                return graph().unique(new UnsignedRightShiftNode(kind(), x(), ConstantNode.forInt(amount, graph())));
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.setResult(this, gen.emitUShr(gen.operand(x()), gen.operand(y())));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/XorNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * 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.max.graal.nodes.calc;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "^")
+public final class XorNode extends LogicNode implements Canonicalizable, LIRLowerable {
+
+    public XorNode(CiKind kind, ValueNode x, ValueNode y) {
+        super(kind, x, y);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x() == y()) {
+            return ConstantNode.forIntegerKind(kind(), 0, graph());
+        }
+        if (x().isConstant() && !y().isConstant()) {
+            return graph().unique(new XorNode(kind(), y(), x()));
+        }
+        if (x().isConstant()) {
+            if (kind() == CiKind.Int) {
+                return ConstantNode.forInt(x().asConstant().asInt() ^ y().asConstant().asInt(), graph());
+            } else {
+                assert kind() == CiKind.Long;
+                return ConstantNode.forLong(x().asConstant().asLong() ^ y().asConstant().asLong(), graph());
+            }
+        } else if (y().isConstant()) {
+            if (kind() == CiKind.Int) {
+                int c = y().asConstant().asInt();
+                if (c == 0) {
+                    return x();
+                }
+            } else {
+                assert kind() == CiKind.Long;
+                long c = y().asConstant().asLong();
+                if (c == 0) {
+                    return x();
+                }
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.setResult(this, gen.emitXor(gen.operand(x()), gen.operand(y())));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/AbstractCallNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * 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.max.graal.nodes.extended;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public abstract class AbstractCallNode extends AbstractStateSplit implements MemoryCheckpoint {
+
+    @Input
+    protected final NodeInputList<ValueNode> arguments;
+
+    public AbstractCallNode(Stamp stamp, ValueNode[] arguments) {
+        super(stamp);
+        this.arguments = new NodeInputList<>(this, arguments);
+    }
+
+    public NodeInputList<ValueNode> arguments() {
+        return arguments;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/Access.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,34 @@
+/*
+ * 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.max.graal.nodes.extended;
+
+import com.oracle.max.graal.nodes.*;
+
+public interface Access {
+
+    ValueNode object();
+
+    LocationNode location();
+
+    void setNullCheck(boolean check);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/AccessNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,66 @@
+/*
+ * 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.max.graal.nodes.extended;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public abstract class AccessNode extends AbstractStateSplit implements Access {
+
+    @Input private ValueNode object;
+    @Input private GuardNode guard;
+    @Input private LocationNode location;
+    @Data private boolean nullCheck;
+
+    public ValueNode object() {
+        return object;
+    }
+
+    public GuardNode guard() {
+        return guard;
+    }
+
+    public void setGuard(GuardNode x) {
+        updateUsages(guard, x);
+        guard = x;
+    }
+
+    public LocationNode location() {
+        return location;
+    }
+
+    public boolean getNullCheck() {
+        return nullCheck;
+    }
+
+    public void setNullCheck(boolean check) {
+        this.nullCheck = check;
+    }
+
+    public AccessNode(CiKind kind, ValueNode object, LocationNode location) {
+        super(StampFactory.forKind(kind));
+        this.object = object;
+        this.location = location;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/BoxNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.nodes.extended;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.java.*;
+import com.oracle.max.graal.nodes.java.MethodCallTargetNode.*;
+import com.oracle.max.graal.nodes.type.*;
+
+
+public final class BoxNode extends AbstractStateSplit implements Node.IterableNodeType {
+
+    @Input private ValueNode source;
+    @Data private int bci;
+    @Data private CiKind sourceKind;
+
+    public BoxNode(ValueNode value, RiResolvedType type, CiKind sourceKind, int bci) {
+        super(StampFactory.exactNonNull(type));
+        this.source = value;
+        this.bci = bci;
+        this.sourceKind = sourceKind;
+        assert value.kind() != CiKind.Object : "can only box from primitive type";
+    }
+
+    public ValueNode source() {
+        return source;
+    }
+
+
+    public CiKind getSourceKind() {
+        return sourceKind;
+    }
+
+    public void expand(BoxingMethodPool pool) {
+        RiResolvedMethod boxingMethod = pool.getBoxingMethod(sourceKind);
+        MethodCallTargetNode callTarget = graph().add(new MethodCallTargetNode(InvokeKind.Static, boxingMethod, new ValueNode[]{source}, boxingMethod.signature().returnType(boxingMethod.holder())));
+        InvokeNode invokeNode = graph().add(new InvokeNode(callTarget, bci));
+        invokeNode.setProbability(this.probability());
+        invokeNode.setStateAfter(stateAfter());
+        ((StructuredGraph) graph()).replaceFixedWithFixed(this, invokeNode);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/BoxingMethodPool.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,102 @@
+/*
+ * 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.max.graal.nodes.extended;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+
+public class BoxingMethodPool {
+
+    private final Set<RiMethod> specialMethods = new HashSet<>();
+    private final RiRuntime runtime;
+    private final RiResolvedMethod[] boxingMethods = new RiResolvedMethod[CiKind.values().length];
+    private final RiResolvedMethod[] unboxingMethods = new RiResolvedMethod[CiKind.values().length];
+    private final RiResolvedField[] boxFields = new RiResolvedField[CiKind.values().length];
+
+    public BoxingMethodPool(RiRuntime runtime) {
+        this.runtime = runtime;
+        initialize();
+    }
+
+    private void initialize() {
+        try {
+            initialize(CiKind.Boolean, Boolean.class, "booleanValue");
+            initialize(CiKind.Byte, Byte.class, "byteValue");
+            initialize(CiKind.Char, Character.class, "charValue");
+            initialize(CiKind.Short, Short.class, "shortValue");
+            initialize(CiKind.Int, Integer.class, "intValue");
+            initialize(CiKind.Long, Long.class, "longValue");
+            initialize(CiKind.Float, Float.class, "floatValue");
+            initialize(CiKind.Double, Double.class, "doubleValue");
+        } catch (SecurityException e) {
+            throw new RuntimeException(e);
+        } catch (NoSuchMethodException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void initialize(CiKind kind, Class<?> type, String unboxMethod) throws SecurityException, NoSuchMethodException {
+
+        // Get boxing method from runtime.
+        RiResolvedMethod boxingMethod = runtime.getRiMethod(type.getDeclaredMethod("valueOf", kind.toJavaClass()));
+        specialMethods.add(boxingMethod);
+        boxingMethods[kind.ordinal()] = boxingMethod;
+
+        // Get unboxing method from runtime.
+        RiResolvedMethod unboxingMethod = runtime.getRiMethod(type.getDeclaredMethod(unboxMethod));
+        unboxingMethods[kind.ordinal()] = unboxingMethod;
+        specialMethods.add(unboxingMethod);
+
+        // Get the field that contains the boxed value.
+        RiResolvedField[] fields = runtime.getType(type).declaredFields();
+        RiResolvedField boxField = fields[0];
+        assert fields.length == 1 && boxField.kind(false) == kind;
+        boxFields[kind.ordinal()] = boxField;
+    }
+
+    public boolean isSpecialMethod(RiResolvedMethod method) {
+        return specialMethods.contains(method);
+    }
+
+    public boolean isBoxingMethod(RiResolvedMethod method) {
+        return isSpecialMethod(method) && method.signature().returnKind(false) == CiKind.Object;
+    }
+
+    public boolean isUnboxingMethod(RiResolvedMethod method) {
+        return isSpecialMethod(method) && method.signature().returnKind(false) != CiKind.Object;
+    }
+
+    public RiResolvedMethod getBoxingMethod(CiKind kind) {
+        return boxingMethods[kind.ordinal()];
+    }
+
+    public RiResolvedMethod getUnboxingMethod(CiKind kind) {
+        return unboxingMethods[kind.ordinal()];
+    }
+
+    public RiResolvedField getBoxField(CiKind kind) {
+        return boxFields[kind.ordinal()];
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/FloatingAccessNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.nodes.extended;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public abstract class FloatingAccessNode extends FloatingNode implements Access {
+
+    @Input private ValueNode object;
+    @Input private GuardNode guard;
+    @Input private LocationNode location;
+    @Data private boolean nullCheck;
+
+    public ValueNode object() {
+        return object;
+    }
+
+    public GuardNode guard() {
+        return guard;
+    }
+
+    public void setGuard(GuardNode x) {
+        updateUsages(guard, x);
+        guard = x;
+    }
+
+    public LocationNode location() {
+        return location;
+    }
+
+    public boolean getNullCheck() {
+        return nullCheck;
+    }
+
+    public void setNullCheck(boolean check) {
+        this.nullCheck = check;
+    }
+
+    public FloatingAccessNode(CiKind kind, ValueNode object, GuardNode guard, LocationNode location) {
+        super(StampFactory.forKind(kind));
+        this.object = object;
+        this.guard = guard;
+        this.location = location;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/FloatingReadNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.nodes.extended;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+
+public final class FloatingReadNode extends FloatingAccessNode implements Node.IterableNodeType, LIRLowerable, Canonicalizable {
+
+    @Input private final NodeInputList<Node> dependencies;
+
+    public NodeInputList<Node> dependencies() {
+        return dependencies;
+    }
+
+    public FloatingReadNode(CiKind kind, ValueNode object, GuardNode guard, LocationNode location, Node... dependencies) {
+        super(kind, object, guard, location);
+        this.dependencies = new NodeInputList<>(this, dependencies);
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.setResult(this, gen.emitLoad(gen.makeAddress(location(), object()), getNullCheck()));
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (object() != null && object().isConstant() && object().kind() == CiKind.Object) {
+            if (this.location() == LocationNode.FINAL_LOCATION && location().getClass() == LocationNode.class) {
+                Object value = object().asConstant().asObject();
+                long displacement = location().displacement();
+                CiKind kind = location().kind();
+                RiRuntime runtime = tool.runtime();
+                CiConstant constant = kind.readUnsafeConstant(value, displacement);
+                if (constant != null) {
+                    return ConstantNode.forCiConstant(constant, runtime, graph());
+                }
+            }
+        }
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/IndexedLocationNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.nodes.extended;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+public final class IndexedLocationNode extends LocationNode implements LIRLowerable, Canonicalizable {
+    @Input private ValueNode index;
+    @Data private boolean indexScalingEnabled;
+
+    public ValueNode index() {
+        return index;
+    }
+
+    public static Object getArrayLocation(CiKind elementKind) {
+        return elementKind;
+    }
+
+    /**
+     * @return whether scaling of the index by the value kind's size is enabled (the default) or disabled.
+     */
+    public boolean indexScalingEnabled() {
+        return indexScalingEnabled;
+    }
+
+    /**
+     * Enables or disables scaling of the index by the value kind's size. Has no effect if the index input is not used.
+     */
+    public void setIndexScalingEnabled(boolean enable) {
+        this.indexScalingEnabled = enable;
+    }
+
+    public static IndexedLocationNode create(Object identity, CiKind kind, int displacement, ValueNode index, Graph graph) {
+        return create(identity, kind, displacement, index, graph, true);
+    }
+
+    public static IndexedLocationNode create(Object identity, CiKind kind, int displacement, ValueNode index, Graph graph, boolean indexScalingEnabled) {
+        return graph.unique(new IndexedLocationNode(identity, kind, index, displacement, indexScalingEnabled));
+    }
+
+    private IndexedLocationNode(Object identity, CiKind kind, ValueNode index, int displacement, boolean indexScalingEnabled) {
+        super(identity, kind, displacement);
+        this.index = index;
+        this.indexScalingEnabled = indexScalingEnabled;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        CiConstant constantIndex = index.asConstant();
+        if (constantIndex != null && constantIndex.kind.stackKind().isInt()) {
+            long constantIndexLong = constantIndex.asInt();
+            if (indexScalingEnabled && tool.target() != null) {
+                constantIndexLong *= tool.target().sizeInBytes(getValueKind());
+            }
+            constantIndexLong += displacement();
+            int constantIndexInt = (int) constantIndexLong;
+            if (constantIndexLong == constantIndexInt) {
+                return LocationNode.create(locationIdentity(), getValueKind(), constantIndexInt, graph());
+            }
+        }
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/LocationNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.nodes.extended;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.graph.Node.ValueNumberable;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public class LocationNode extends FloatingNode implements LIRLowerable, ValueNumberable {
+
+    @Data private int displacement;
+    @Data private CiKind valueKind;
+    @Data private Object locationIdentity;
+
+    public static final Object ANY_LOCATION = new Object() {
+        @Override
+        public String toString() {
+            return "ANY_LOCATION";
+        }
+    };
+    public static final Object FINAL_LOCATION = new Object();
+
+    public static Object getArrayLocation(CiKind elementKind) {
+        return elementKind;
+    }
+
+    public int displacement() {
+        return displacement;
+    }
+
+    public static LocationNode create(Object identity, CiKind kind, int displacement, Graph graph) {
+        return graph.unique(new LocationNode(identity, kind, displacement));
+    }
+
+    protected LocationNode(Object identity, CiKind kind, int displacement) {
+        super(StampFactory.illegal());
+        assert kind != CiKind.Illegal && kind != CiKind.Void;
+        this.displacement = displacement;
+        this.valueKind = kind;
+        this.locationIdentity = identity;
+    }
+
+    public CiKind getValueKind() {
+        return valueKind;
+    }
+
+    public Object locationIdentity() {
+        return locationIdentity;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool generator) {
+        // nothing to do...
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/LookupSwitchNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.extended;
+
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+/**
+ * The {@code LookupSwitchNode} represents a lookup switch bytecode, which has a sorted
+ * array of key values.
+ */
+public final class LookupSwitchNode extends SwitchNode implements LIRLowerable, Simplifiable {
+
+    @Data private final int[] keys;
+
+    /**
+     * Constructs a new LookupSwitch instruction.
+     * @param value the instruction producing the value being switched on
+     * @param successors the list of successors
+     * @param keys the list of keys, sorted
+     */
+    public LookupSwitchNode(ValueNode value, BeginNode[] successors, int[] keys, double[] probability) {
+        super(value, successors, probability);
+        assert successors.length == keys.length + 1;
+        this.keys = keys;
+    }
+
+    public LookupSwitchNode(ValueNode value, int[] keys, double[] switchProbability) {
+        this(value, new BeginNode[switchProbability.length], keys, switchProbability);
+    }
+
+    /**
+     * Gets the key at the specified index.
+     * @param i the index
+     * @return the key at that index
+     */
+    public int keyAt(int i) {
+        return keys[i];
+    }
+
+    public int keysLength() {
+        return keys.length;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.emitLookupSwitch(this);
+    }
+
+    @Override
+    public void simplify(SimplifierTool tool) {
+        if (value() instanceof ConstantNode) {
+            ConstantNode constant = (ConstantNode) value();
+            int value = constant.value.asInt();
+
+            BeginNode remainingSux = (BeginNode) defaultSuccessor();
+            int remainingSuxIndex = blockSuccessorCount() - 1;
+            for (int i = 0; i < keys.length; i++) {
+                if (value == keys[i]) {
+                    remainingSux = blockSuccessor(i);
+                    remainingSuxIndex = i;
+                    break;
+                }
+            }
+
+            for (int i = 0; i < blockSuccessorCount(); i++) {
+                BeginNode sux = blockSuccessor(i);
+                if (sux != remainingSux) {
+                    tool.deleteBranch(sux);
+                }
+            }
+
+            tool.addToWorkList(remainingSux);
+            ((StructuredGraph) graph()).removeSplit(this, remainingSuxIndex);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/MembarNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * 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.max.graal.nodes.extended;
+
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * Cretes a memory barrier.
+ */
+public class MembarNode extends AbstractStateSplit implements LIRLowerable, MemoryCheckpoint {
+
+    private final int barriers;
+
+    public MembarNode(int barriers) {
+        super(StampFactory.illegal());
+        this.barriers = barriers;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool generator) {
+        generator.emitMembar(barriers);
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static void get(@ConstantNodeParameter int barriers) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/MemoryCheckpoint.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,28 @@
+/*
+ * 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.max.graal.nodes.extended;
+
+
+public interface MemoryCheckpoint {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/ReadHubNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,48 @@
+/*
+ * 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.max.graal.nodes.extended;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+// TODO (ch) this should be a FloatingNode but Lowering crashes in that case
+public final class ReadHubNode extends FixedWithNextNode implements Lowerable {
+    @Input private ValueNode object;
+
+    public ValueNode object() {
+        return object;
+    }
+
+    public ReadHubNode(ValueNode object) {
+        super(StampFactory.forKind(CiKind.Object));
+        this.object = object;
+    }
+
+    @Override
+    public void lower(CiLoweringTool tool) {
+        tool.getRuntime().lower(this, tool);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/ReadNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.nodes.extended;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+
+public final class ReadNode extends AccessNode implements Node.IterableNodeType, LIRLowerable, Canonicalizable {
+
+    public ReadNode(CiKind kind, ValueNode object, LocationNode location) {
+        super(kind, object, location);
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.setResult(this, gen.emitLoad(gen.makeAddress(location(), object()), getNullCheck()));
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (object() != null && object().isConstant() && object().kind() == CiKind.Object) {
+            if (location() == LocationNode.FINAL_LOCATION && location().getClass() == LocationNode.class) {
+                Object value = object().asConstant().asObject();
+                long displacement = location().displacement();
+                CiKind kind = location().kind();
+                RiRuntime runtime = tool.runtime();
+                CiConstant constant = kind.readUnsafeConstant(value, displacement);
+                if (constant != null) {
+                    return ConstantNode.forCiConstant(constant, runtime, graph());
+                }
+            }
+        }
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/RuntimeCallNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,68 @@
+/*
+ * 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.max.graal.nodes.extended;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public final class RuntimeCallNode extends AbstractCallNode implements LIRLowerable {
+
+    @Data private final CiRuntimeCall call;
+
+    public CiRuntimeCall call() {
+        return call;
+    }
+
+    public RuntimeCallNode(CiRuntimeCall call) {
+        this(call, new ValueNode[0]);
+    }
+
+    public RuntimeCallNode(CiRuntimeCall call, ValueNode arg1) {
+        this(call, new ValueNode[] {arg1});
+    }
+
+    public RuntimeCallNode(CiRuntimeCall call, ValueNode[] arguments) {
+        super(StampFactory.forKind(call.resultKind), arguments);
+        this.call = call;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.emitRuntimeCall(this);
+    }
+
+    // specialized on return type (instead of public static <T> T performCall) until boxing/unboxing is sorted out in intrinsification
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static <S> double performCall(@ConstantNodeParameter CiRuntimeCall call, S arg1) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static long performCall(@ConstantNodeParameter CiRuntimeCall call) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/SafeAccessNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,48 @@
+/*
+ * 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.max.graal.nodes.extended;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.type.*;
+
+
+public abstract class SafeAccessNode extends AbstractStateSplit {
+
+    @Input private ValueNode object;
+    @Input private LocationNode location;
+
+    public SafeAccessNode(CiKind kind, ValueNode object, LocationNode location) {
+        super(StampFactory.forKind(kind));
+        this.object = object;
+        this.location = location;
+    }
+
+    public ValueNode object() {
+        return object;
+    }
+
+    public LocationNode location() {
+        return location;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/SafeReadNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,48 @@
+/*
+ * 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.max.graal.nodes.extended;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+
+public class SafeReadNode extends SafeAccessNode implements Lowerable {
+
+    public SafeReadNode(CiKind kind, ValueNode object, LocationNode location) {
+        super(kind, object, location);
+        assert object != null && location != null;
+    }
+
+    @Override
+    public void lower(CiLoweringTool tool) {
+        StructuredGraph graph = (StructuredGraph) graph();
+        GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(object(), false)));
+        ReadNode read = graph.add(new ReadNode(kind(), object(), location()));
+        read.setGuard(guard);
+
+        graph.replaceFixedWithFixed(this, read);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/SafeWriteNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * 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.max.graal.nodes.extended;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+
+public class SafeWriteNode extends SafeAccessNode implements Lowerable{
+
+    @Input private ValueNode value;
+
+    public SafeWriteNode(ValueNode object, ValueNode value, LocationNode location) {
+        super(CiKind.Void, object, location);
+        this.value = value;
+    }
+
+    public ValueNode value() {
+        return value;
+    }
+
+    @Override
+    public void lower(CiLoweringTool tool) {
+        StructuredGraph graph = (StructuredGraph) graph();
+        GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(object(), false)));
+        WriteNode write = graph.add(new WriteNode(object(), value(), location()));
+        write.setGuard(guard);
+        graph.replaceFixedWithFixed(this, write);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/SwitchNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.extended;
+
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code SwitchNode} class is the base of both lookup and table switches.
+ */
+public abstract class SwitchNode extends ControlSplitNode {
+
+    @Input private ValueNode value;
+
+    public ValueNode value() {
+        return value;
+    }
+
+    /**
+     * Constructs a new Switch.
+     * @param value the instruction that provides the value to be switched over
+     * @param successors the list of successors of this switch
+     * @param stateAfter the state after the switch
+     */
+    public SwitchNode(ValueNode value, BeginNode[] successors, double[] probability) {
+        super(StampFactory.illegal(), successors, probability);
+        this.value = value;
+    }
+
+    /**
+     * Gets the number of cases that this switch covers (excluding the default case).
+     * @return the number of cases
+     */
+    public int numberOfCases() {
+        return blockSuccessorCount() - 1;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/TableSwitchNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.extended;
+
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+/**
+ * The {@code TableSwitchNode} represents a table switch.
+ */
+public final class TableSwitchNode extends SwitchNode implements LIRLowerable, Simplifiable {
+
+    @Data private final int lowKey;
+
+    /**
+     * Constructs a new TableSwitch instruction.
+     * @param value the instruction producing the value being switched on
+     * @param successors the list of successors
+     * @param lowKey the lowest integer key in the table
+     */
+    public TableSwitchNode(ValueNode value, BeginNode[] successors, int lowKey, double[] probability) {
+        super(value, successors, probability);
+        this.lowKey = lowKey;
+    }
+
+    public TableSwitchNode(ValueNode value, int lowKey, double[] switchProbability) {
+        this(value, new BeginNode[switchProbability.length], lowKey, switchProbability);
+    }
+
+    /**
+     * Gets the lowest key in the table switch (inclusive).
+     * @return the low key
+     */
+    public int lowKey() {
+        return lowKey;
+    }
+
+    /**
+     * Gets the highest key in the table switch (exclusive).
+     * @return the high key
+     */
+    public int highKey() {
+        return lowKey + numberOfCases();
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.emitTableSwitch(this);
+    }
+
+    @Override
+    public void simplify(SimplifierTool tool) {
+        if (value() instanceof ConstantNode) {
+            ConstantNode constant = (ConstantNode) value();
+            int value = constant.value.asInt();
+
+            int remainingSuxIndex;
+            if (value >= lowKey() && value <= highKey()) {
+                remainingSuxIndex = value - lowKey();
+            } else {
+                remainingSuxIndex = blockSuccessorCount() - 1;
+            }
+
+            BeginNode remainingSux = blockSuccessor(remainingSuxIndex);
+            for (int i = 0; i < blockSuccessorCount(); i++) {
+                BeginNode sux = blockSuccessor(i);
+                if (sux != remainingSux) {
+                    tool.deleteBranch(sux);
+                }
+            }
+
+            tool.addToWorkList(remainingSux);
+            ((StructuredGraph) graph()).removeSplit(this, remainingSuxIndex);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/UnboxNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,92 @@
+/*
+ * 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.max.graal.nodes.extended;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.java.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+
+public final class UnboxNode extends FixedWithNextNode implements Node.IterableNodeType, Canonicalizable {
+
+    @Input private ValueNode source;
+    @Data private CiKind destinationKind;
+
+    public UnboxNode(CiKind kind, ValueNode source) {
+        super(StampFactory.forKind(kind));
+        this.source = source;
+        this.destinationKind = kind;
+        assert kind != CiKind.Object : "can only unbox to primitive";
+        assert source.kind() == CiKind.Object : "can only unbox objects";
+    }
+
+    public ValueNode source() {
+        return source;
+    }
+
+    public CiKind destinationKind() {
+        return destinationKind;
+    }
+
+    public void expand(BoxingMethodPool pool) {
+        RiResolvedField field = pool.getBoxField(kind());
+        LoadFieldNode loadField = graph().add(new LoadFieldNode(source, field));
+        loadField.setProbability(probability());
+        ((StructuredGraph) graph()).replaceFixedWithFixed(this, loadField);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (source.isConstant()) {
+            CiConstant constant = source.asConstant();
+            Object o = constant.asObject();
+            if (o != null) {
+                switch (destinationKind) {
+                    case Boolean:
+                        return ConstantNode.forBoolean((Boolean) o, graph());
+                    case Byte:
+                        return ConstantNode.forByte((Byte) o, graph());
+                    case Char:
+                        return ConstantNode.forChar((Character) o, graph());
+                    case Short:
+                        return ConstantNode.forShort((Short) o, graph());
+                    case Int:
+                        return ConstantNode.forInt((Integer) o, graph());
+                    case Long:
+                        return ConstantNode.forLong((Long) o, graph());
+                    case Float:
+                        return ConstantNode.forFloat((Long) o, graph());
+                    case Double:
+                        return ConstantNode.forDouble((Long) o, graph());
+                    default:
+                        ValueUtil.shouldNotReachHere();
+                }
+            }
+        }
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/UnsafeCastNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.extended;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code UnsafeCastNode} produces the same value as its input, but with a different type.
+ */
+public final class UnsafeCastNode extends FloatingNode implements Canonicalizable, Lowerable {
+
+    @Input private ValueNode x;
+    @Data private RiResolvedType toType;
+
+    public ValueNode x() {
+        return x;
+    }
+
+    public UnsafeCastNode(ValueNode x, RiResolvedType toType) {
+        super(StampFactory.declared(toType));
+        this.x = x;
+        this.toType = toType;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x != null && x.declaredType() != null && x.declaredType().isSubtypeOf(toType)) {
+            return x;
+        }
+        return this;
+    }
+
+    @Override
+    public void lower(CiLoweringTool tool) {
+        ((StructuredGraph) graph()).replaceFloating(this, x);
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static <T> T cast(Object object, @ConstantNodeParameter Class<?> toType) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/UnsafeLoadNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * 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.max.graal.nodes.extended;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * Load of a value from a location specified as an offset relative to an object.
+ */
+public class UnsafeLoadNode extends AbstractStateSplit implements Lowerable {
+
+    @Input private ValueNode object;
+    @Input private ValueNode offset;
+    @Data private final int displacement;
+    @Data private final CiKind loadKind;
+
+    public ValueNode object() {
+        return object;
+    }
+
+    public int displacement() {
+        return displacement;
+    }
+
+    public ValueNode offset() {
+        return offset;
+    }
+
+    public UnsafeLoadNode(ValueNode object, ValueNode offset, CiKind kind) {
+        this(object, 0, offset, kind);
+    }
+
+    public UnsafeLoadNode(ValueNode object, int displacement, ValueNode offset, CiKind kind) {
+        super(StampFactory.forKind(kind.stackKind()));
+        this.object = object;
+        this.displacement = displacement;
+        this.offset = offset;
+        this.loadKind = kind;
+    }
+
+    public CiKind loadKind() {
+        return loadKind;
+    }
+
+    @Override
+    public void lower(CiLoweringTool tool) {
+        tool.getRuntime().lower(this, tool);
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static <T> T load(Object object, long offset, @ConstantNodeParameter CiKind kind) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/UnsafeStoreNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,135 @@
+/*
+ * 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.max.graal.nodes.extended;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * Store of a value at a location specified as an offset relative to an object.
+ */
+public class UnsafeStoreNode extends AbstractStateSplit implements Lowerable {
+
+    @Input private ValueNode object;
+    @Input private ValueNode offset;
+    @Input private ValueNode value;
+    @Data private final int displacement;
+    @Data private final CiKind storeKind;
+
+    public UnsafeStoreNode(ValueNode object, ValueNode offset, ValueNode value, CiKind kind) {
+        this(object, 0, offset, value, kind);
+    }
+
+    public UnsafeStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value, CiKind kind) {
+        super(StampFactory.illegal());
+        assert kind != CiKind.Void && kind != CiKind.Illegal;
+        this.object = object;
+        this.displacement = displacement;
+        this.offset = offset;
+        this.value = value;
+        this.storeKind = kind;
+    }
+
+    public ValueNode object() {
+        return object;
+    }
+
+    public int displacement() {
+        return displacement;
+    }
+
+    public ValueNode offset() {
+        return offset;
+    }
+
+    public ValueNode value() {
+        return value;
+    }
+
+    public CiKind storeKind() {
+        return storeKind;
+    }
+
+    @Override
+    public void lower(CiLoweringTool tool) {
+        tool.getRuntime().lower(this, tool);
+    }
+
+    // specialized on value type until boxing/unboxing is sorted out in intrinsification
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static void store(Object object, long offset, Object value, @ConstantNodeParameter CiKind kind) {
+        throw new UnsupportedOperationException();
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static void store(Object object, long offset, boolean value, @ConstantNodeParameter CiKind kind) {
+        throw new UnsupportedOperationException();
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static void store(Object object, long offset, byte value, @ConstantNodeParameter CiKind kind) {
+        throw new UnsupportedOperationException();
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static void store(Object object, long offset, char value, @ConstantNodeParameter CiKind kind) {
+        throw new UnsupportedOperationException();
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static void store(Object object, long offset, double value, @ConstantNodeParameter CiKind kind) {
+        throw new UnsupportedOperationException();
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static void store(Object object, long offset, float value, @ConstantNodeParameter CiKind kind) {
+        throw new UnsupportedOperationException();
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static void store(Object object, long offset, int value, @ConstantNodeParameter CiKind kind) {
+        throw new UnsupportedOperationException();
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static void store(Object object, long offset, long value, @ConstantNodeParameter CiKind kind) {
+        throw new UnsupportedOperationException();
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static void store(Object object, long offset, short value, @ConstantNodeParameter CiKind kind) {
+        throw new UnsupportedOperationException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/ValueAnchorNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * 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.max.graal.nodes.extended;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The ValueAnchor instruction keeps non-CFG (floating) nodes above a certain point in the graph.
+ */
+
+public final class ValueAnchorNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType {
+
+    @Input private ValueNode object;
+
+    public ValueNode object() {
+        return object;
+    }
+
+    public ValueAnchorNode(ValueNode object) {
+        super(StampFactory.illegal());
+        this.object = object;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        // Nothing to emit, since this is node is used for structural purposes only.
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (object == null) {
+            return null;
+        }
+        if (object instanceof ConstantNode) {
+            return null;
+        }
+        if (object instanceof IntegerDivNode || object instanceof IntegerRemNode) {
+            if (((ArithmeticNode) object).y().isConstant()) {
+                CiConstant  constant = ((ArithmeticNode) object).y().asConstant();
+                assert constant.kind == object.kind() : constant.kind + " != " + object.kind();
+                if (constant.asLong() != 0) {
+                    return null;
+                }
+            }
+        }
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/WriteMemoryCheckpointNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,44 @@
+/*
+ * 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.max.graal.nodes.extended;
+
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+
+public final class WriteMemoryCheckpointNode extends AbstractStateSplit implements LIRLowerable, MemoryCheckpoint {
+
+    public WriteMemoryCheckpointNode() {
+        this(StampFactory.illegal());
+    }
+
+    public WriteMemoryCheckpointNode(Stamp stamp) {
+        super(stamp);
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool generator) {
+        // nothing to do...
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/WriteNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.nodes.extended;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+
+public final class WriteNode extends AccessNode implements LIRLowerable {
+    @Input private ValueNode value;
+
+    public ValueNode value() {
+        return value;
+    }
+
+    public WriteNode(ValueNode object, ValueNode value, LocationNode location) {
+        super(CiKind.Void, object, location);
+        this.value = value;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.emitStore(gen.makeAddress(location(), object()), gen.operand(value()), getNullCheck());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/AccessArrayNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.java;
+
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * This the base class of all array operations.
+ */
+public abstract class AccessArrayNode extends AbstractStateSplit {
+
+    @Input private ValueNode array;
+
+    public ValueNode array() {
+        return array;
+    }
+
+    /**
+     * Creates a new AccessArrayNode.
+     * @param kind the type of the result of this instruction
+     * @param array the instruction that produces the array object value
+     */
+    public AccessArrayNode(Stamp stamp, ValueNode array) {
+        super(stamp);
+        this.array = array;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/AccessFieldNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.java;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The base class of all instructions that access fields.
+ */
+public abstract class AccessFieldNode extends AbstractStateSplit implements Lowerable {
+
+    @Input private ValueNode object;
+
+    @Data protected final RiResolvedField field;
+
+    public ValueNode object() {
+        return object;
+    }
+
+    /**
+     * Constructs a new access field object.
+     * @param kind the result kind of the access
+     * @param object the instruction producing the receiver object
+     * @param field the compiler interface representation of the field
+     * @param graph
+     */
+    public AccessFieldNode(Stamp stamp, ValueNode object, RiResolvedField field) {
+        super(stamp);
+        this.object = object;
+        this.field = field;
+        assert field.holder().isInitialized();
+    }
+
+    /**
+     * Gets the compiler interface field for this field access.
+     * @return the compiler interface field for this field access
+     */
+    public RiResolvedField field() {
+        return field;
+    }
+
+    /**
+     * Checks whether this field access is an access to a static field.
+     * @return {@code true} if this field access is to a static field
+     */
+    public boolean isStatic() {
+        return Modifier.isStatic(field.accessFlags());
+    }
+
+    /**
+     * Checks whether this field is declared volatile.
+     * @return {@code true} if the field is resolved and declared volatile
+     */
+    public boolean isVolatile() {
+        return Modifier.isVolatile(field.accessFlags());
+    }
+
+    @Override
+    public void lower(CiLoweringTool tool) {
+        tool.getRuntime().lower(this, tool);
+    }
+
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> debugProperties = super.getDebugProperties();
+        debugProperties.put("field", CiUtil.format("%h.%n", field));
+        return debugProperties;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/AccessIndexedNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.java;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code AccessIndexedNode} class is the base class of instructions that read or write
+ * elements of an array.
+ */
+public abstract class AccessIndexedNode extends AccessArrayNode {
+
+    @Input private ValueNode index;
+    @Input private ValueNode length;
+
+    public ValueNode index() {
+        return index;
+    }
+
+    public ValueNode length() {
+        return length;
+    }
+
+    private final CiKind elementType;
+
+    /**
+     * Create an new AccessIndexedNode.
+     * @param kind the result kind of the access
+     * @param array the instruction producing the array
+     * @param index the instruction producing the index
+     * @param length the instruction producing the length
+     * @param elementKind the type of the elements of the array
+     */
+    protected AccessIndexedNode(Stamp stamp, ValueNode array, ValueNode index, ValueNode length, CiKind elementKind) {
+        super(stamp, array);
+        this.index = index;
+        this.length = length;
+        this.elementType = elementKind;
+    }
+
+    /**
+     * Gets the element type of the array.
+     * @return the element type
+     */
+    public CiKind elementKind() {
+        return elementType;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/AccessMonitorNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.nodes.java;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code AccessMonitorNode} is the base class of both monitor acquisition and release.
+ * <br>
+ * The VM needs information about monitors in the debug information. This information is built from
+ * the nesting level of {@link MonitorEnterNode} when the LIR is constructed. Therefore, monitor
+ * nodes must not be removed from the graph unless it is guaranteed that the nesting level does not change.
+ * For example, you must not remove a {@link MonitorEnterNode} for a thread-local object or for a recursive locking.
+ * Instead, mark the node as {@link #eliminated}. This makes sure that the meta data still contains the complete
+ * locking hierarchy.
+ * <br>
+ * The Java bytecode specification allows non-balanced locking. Graal does not handle such cases and throws a
+ * {@link CiBailout} instead. Detecting non-balanced monitors during bytecode parsing is difficult, since the
+ * node flowing into the {@link MonitorExitNode} can be a phi function hiding the node that was flowing into the
+ * {@link MonitorEnterNode}. Optimization phases are free to throw {@link CiBailout} if they detect such cases.
+ * Otherwise, they are detected during LIR construction.
+ */
+public abstract class AccessMonitorNode extends AbstractStateSplit implements MemoryCheckpoint {
+
+    @Input private ValueNode object;
+    @Data private boolean eliminated;
+
+    public ValueNode object() {
+        return object;
+    }
+
+    public boolean eliminated() {
+        return eliminated;
+    }
+
+    public void eliminate() {
+        eliminated = true;
+    }
+
+    /**
+     * Creates a new AccessMonitor instruction.
+     *
+     * @param object the instruction producing the object
+     */
+    public AccessMonitorNode(ValueNode object) {
+        super(StampFactory.illegal());
+        this.object = object;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/ArrayLengthNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.java;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code ArrayLength} instruction gets the length of an array.
+ */
+public final class ArrayLengthNode extends FixedWithNextNode implements Canonicalizable, Lowerable, LIRLowerable {
+
+    @Input private ValueNode array;
+
+    public ValueNode array() {
+        return array;
+    }
+
+    public ArrayLengthNode(ValueNode array) {
+        super(StampFactory.intValue());
+        this.array = array;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitArrayLength(this);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (array() instanceof NewArrayNode) {
+            ValueNode length = ((NewArrayNode) array()).dimension(0);
+            assert length != null;
+            return length;
+        }
+        CiConstant constantValue = null;
+        if (array().isConstant() && !array().isNullConstant()) {
+            constantValue = array().asConstant();
+            if (constantValue != null && constantValue.isNonNull()) {
+                RiRuntime runtime = tool.runtime();
+                return ConstantNode.forInt(runtime.getArrayLength(constantValue), graph());
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void lower(CiLoweringTool tool) {
+        tool.getRuntime().lower(this, tool);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/CheckCastNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.java;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code CheckCastNode} represents a {@link Bytecodes#CHECKCAST}.
+ *
+ * The {@link #targetClass()} of a CheckCastNode can be null for array store checks!
+ */
+public final class CheckCastNode extends TypeCheckNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType {
+
+    @Input protected final FixedNode anchor;
+    @Data  protected final boolean emitCode;
+
+    public FixedNode anchor() {
+        return anchor;
+    }
+
+    public boolean emitCode() {
+        return emitCode;
+    }
+
+    /**
+     * Creates a new CheckCast instruction.
+     *
+     * @param targetClassInstruction the instruction which produces the class which is being cast to
+     * @param targetClass the class being cast to
+     * @param object the instruction producing the object
+     */
+    public CheckCastNode(FixedNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object) {
+        this(anchor, targetClassInstruction, targetClass, object, EMPTY_HINTS, false);
+    }
+
+    public CheckCastNode(FixedNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, boolean emitCode) {
+        this(anchor, targetClassInstruction, targetClass, object, EMPTY_HINTS, false, emitCode);
+    }
+
+    public CheckCastNode(FixedNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, RiResolvedType[] hints, boolean hintsExact) {
+        this(anchor, targetClassInstruction, targetClass, object, hints, hintsExact, true);
+    }
+
+    private CheckCastNode(FixedNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, RiResolvedType[] hints, boolean hintsExact, boolean emitCode) {
+        super(targetClassInstruction, targetClass, object, hints, hintsExact, targetClass == null ? StampFactory.forKind(CiKind.Object) : StampFactory.declared(targetClass));
+        this.anchor = anchor;
+        this.emitCode = emitCode;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitCheckCast(this);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        RiResolvedType objectDeclaredType = object().declaredType();
+        RiResolvedType targetClass = targetClass();
+        if (objectDeclaredType != null && targetClass != null && objectDeclaredType.isSubtypeOf(targetClass)) {
+            freeAnchor();
+            return object();
+        }
+        CiConstant constant = object().asConstant();
+        if (constant != null) {
+            assert constant.kind == CiKind.Object;
+            if (constant.isNull()) {
+                freeAnchor();
+                return object();
+            }
+        }
+
+        if (tool.assumptions() != null && hints() != null && targetClass() != null) {
+            if (!hintsExact() && hints().length == 1 && hints()[0] == targetClass().uniqueConcreteSubtype()) {
+                tool.assumptions().recordConcreteSubtype(targetClass(), hints()[0]);
+                return graph().unique(new CheckCastNode(anchor, targetClassInstruction(), targetClass(), object(), hints(), true));
+            }
+        }
+        return this;
+    }
+
+    // TODO(tw): Find a better way to handle anchors.
+    private void freeAnchor() {
+        ValueAnchorNode anchorUsage = usages().filter(ValueAnchorNode.class).first();
+        if (anchorUsage != null) {
+            anchorUsage.replaceFirstInput(this, null);
+        }
+    }
+
+    @Override
+    public BooleanNode negate() {
+        throw new Error("A CheckCast does not produce a boolean value, so it should actually not be a subclass of BooleanNode");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/CompareAndSwapNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,100 @@
+/*
+ * 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.max.graal.nodes.java;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * Represents an atomic compare-and-swap operation. If {@link #directResult} is true then the value read from the memory location is produced.
+ * Otherwise the result is a boolean that contains whether the value matched the expected value.
+ */
+public class CompareAndSwapNode extends AbstractStateSplit implements LIRLowerable, MemoryCheckpoint {
+
+    @Input private ValueNode object;
+    @Input private ValueNode offset;
+    @Input private ValueNode expected;
+    @Input private ValueNode newValue;
+    @Data private final boolean directResult;
+
+    public ValueNode object() {
+        return object;
+    }
+
+    public ValueNode offset() {
+        return offset;
+    }
+
+    public ValueNode expected() {
+        return expected;
+    }
+
+    public ValueNode newValue() {
+        return newValue;
+    }
+
+    public boolean directResult() {
+        return directResult;
+    }
+
+    public CompareAndSwapNode(ValueNode object, ValueNode offset, ValueNode expected, ValueNode newValue) {
+        this(object, offset, expected, newValue, false);
+    }
+
+    public CompareAndSwapNode(ValueNode object, ValueNode offset, ValueNode expected, ValueNode newValue, boolean directResult) {
+        super(StampFactory.forKind(directResult ? expected.kind().stackKind() : CiKind.Boolean.stackKind()));
+        assert expected.kind() == newValue.kind();
+        this.object = object;
+        this.offset = offset;
+        this.expected = expected;
+        this.newValue = newValue;
+        this.directResult = directResult;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitCompareAndSwap(this);
+    }
+
+    // specialized on value type until boxing/unboxing is sorted out in intrinsification
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static boolean compareAndSwap(Object object, long offset, Object expected, Object newValue) {
+        throw new UnsupportedOperationException();
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static boolean compareAndSwap(Object object, long offset, long expected, long newValue) {
+        throw new UnsupportedOperationException();
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static boolean compareAndSwap(Object object, long offset, int expected, int newValue) {
+        throw new UnsupportedOperationException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/ExceptionObjectNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.java;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code ExceptionObject} instruction represents the incoming exception object to an exception handler.
+ */
+public final class ExceptionObjectNode extends AbstractStateSplit implements LIRLowerable, MemoryCheckpoint {
+
+    /**
+     * Constructs a new ExceptionObject instruction.
+     */
+    public ExceptionObjectNode() {
+        super(StampFactory.forKind(CiKind.Object));
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitExceptionObject(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/InstanceOfNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.java;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code InstanceOfNode} represents an instanceof test.
+ */
+public final class InstanceOfNode extends TypeCheckNode implements Canonicalizable, LIRLowerable {
+
+    @Data private final boolean negated;
+
+    public boolean negated() {
+        return negated;
+    }
+
+    /**
+     * Constructs a new InstanceOfNode.
+     *
+     * @param targetClassInstruction the instruction which produces the target class of the instanceof check
+     * @param targetClass the class which is the target of the instanceof check
+     * @param object the instruction producing the object input to this instruction
+     */
+    public InstanceOfNode(ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, boolean negated) {
+        this(targetClassInstruction, targetClass, object, EMPTY_HINTS, false, negated);
+    }
+
+    public InstanceOfNode(ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, RiResolvedType[] hints, boolean hintsExact, boolean negated) {
+        super(targetClassInstruction, targetClass, object, hints, hintsExact, StampFactory.illegal());
+        this.negated = negated;
+        assert targetClass != null;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        assert object() != null : this;
+        RiResolvedType exact = object().exactType();
+        if (exact != null) {
+            boolean result = exact.isSubtypeOf(targetClass());
+            if (result != negated) {
+                // The instanceof check reduces to a null check.
+                return graph().unique(new NullCheckNode(object(), false));
+            } else {
+                // The instanceof check can never succeed.
+                return ConstantNode.forBoolean(false, graph());
+            }
+        }
+        CiConstant constant = object().asConstant();
+        if (constant != null) {
+            assert constant.kind == CiKind.Object;
+            if (constant.isNull()) {
+                return ConstantNode.forBoolean(negated, graph());
+            } else {
+                assert false : "non-null constants are always expected to provide an exactType";
+            }
+        }
+        if (tool.assumptions() != null && hints() != null && targetClass() != null) {
+            if (!hintsExact() && hints().length == 1 && hints()[0] == targetClass().uniqueConcreteSubtype()) {
+                tool.assumptions().recordConcreteSubtype(targetClass(), hints()[0]);
+                return graph().unique(new InstanceOfNode(targetClassInstruction(), targetClass(), object(), hints(), true, negated));
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public BooleanNode negate() {
+        return graph().unique(new InstanceOfNode(targetClassInstruction(), targetClass(), object(), hints(), hintsExact(), !negated));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/IsTypeNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.java;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public final class IsTypeNode extends BooleanNode implements Canonicalizable, LIRLowerable {
+
+    @Input private ValueNode objectClass;
+    @Data private final RiResolvedType type;
+
+    public ValueNode objectClass() {
+        return objectClass;
+    }
+
+    /**
+     * Constructs a new IsTypeNode.
+     *
+     * @param object the instruction producing the object to check against the given type
+     * @param type the type for this check
+     */
+    public IsTypeNode(ValueNode objectClass, RiResolvedType type) {
+        super(StampFactory.illegal());
+        assert objectClass == null || objectClass.kind() == CiKind.Object;
+        this.type = type;
+        this.objectClass = objectClass;
+    }
+
+    public RiResolvedType type() {
+        return type;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        // nothing to do
+    }
+
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> properties = super.getDebugProperties();
+        properties.put("type", type);
+        return properties;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        RiResolvedType exactType = objectClass() instanceof ReadHubNode ? ((ReadHubNode) objectClass()).object().exactType() : null;
+        if (exactType != null) {
+            return ConstantNode.forBoolean(exactType == type(), graph());
+        }
+        // constants return the correct exactType, so they are handled by the code above
+        return this;
+    }
+
+    @Override
+    public BooleanNode negate() {
+        throw new Error("unimplemented");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/LoadFieldNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.java;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code LoadFieldNode} represents a read of a static or instance field.
+ */
+public final class LoadFieldNode extends AccessFieldNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType {
+
+    /**
+     * Creates a new LoadFieldNode instance.
+     *
+     * @param object the receiver object
+     * @param field the compiler interface field
+     */
+    public LoadFieldNode(ValueNode object, RiResolvedField field) {
+        super(createStamp(field), object, field);
+    }
+
+    private static Stamp createStamp(RiResolvedField field) {
+        CiKind kind = field.kind(false);
+        if (kind == CiKind.Object && field.type() instanceof RiResolvedType) {
+            RiResolvedType resolvedType = (RiResolvedType) field.type();
+            return StampFactory.declared(resolvedType);
+        } else {
+            return StampFactory.forKind(kind);
+        }
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitLoadField(this);
+    }
+
+    @Override
+    public boolean needsStateAfter() {
+        return false;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        CiConstant constant = null;
+        if (isStatic()) {
+            constant = field().constantValue(null);
+        } else if (object().isConstant() && !object().isNullConstant()) {
+            constant = field().constantValue(object().asConstant());
+        }
+        if (constant != null) {
+            return ConstantNode.forCiConstant(constant, tool.runtime(), graph());
+        }
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/LoadIndexedNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.java;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code LoadIndexedNode} represents a read from an element of an array.
+ */
+public final class LoadIndexedNode extends AccessIndexedNode implements Lowerable, LIRLowerable, Node.IterableNodeType {
+
+    /**
+     * Creates a new LoadIndexedNode.
+     * @param array the instruction producing the array
+     * @param index the instruction producing the index
+     * @param length the instruction producing the length
+     * @param elementKind the element type
+     */
+    public LoadIndexedNode(ValueNode array, ValueNode index, ValueNode length, CiKind elementKind) {
+        super(createStamp(array, elementKind), array, index, length, elementKind);
+    }
+
+    private static Stamp createStamp(ValueNode array, CiKind kind) {
+        if (kind == CiKind.Object && array.declaredType() != null) {
+            return StampFactory.declared(array.declaredType().componentType());
+        } else {
+            return StampFactory.forKind(kind);
+        }
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitLoadIndexed(this);
+    }
+
+    @Override
+    public boolean needsStateAfter() {
+        return false;
+    }
+
+    @Override
+    public void lower(CiLoweringTool tool) {
+        tool.getRuntime().lower(this, tool);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/MethodCallTargetNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,151 @@
+/*
+ * 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.max.graal.nodes.java;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public class MethodCallTargetNode extends CallTargetNode implements Node.IterableNodeType, Canonicalizable {
+    public enum InvokeKind {
+        Interface,
+        Special,
+        Static,
+        Virtual
+    }
+
+    @Data private final RiType returnType;
+    @Data private RiResolvedMethod targetMethod;
+    @Data private InvokeKind invokeKind;
+    private final Stamp returnStamp;
+
+    /**
+     * @param arguments
+     */
+    public MethodCallTargetNode(InvokeKind invokeKind, RiResolvedMethod targetMethod, ValueNode[] arguments, RiType returnType) {
+        super(arguments);
+        this.invokeKind = invokeKind;
+        this.returnType = returnType;
+        this.targetMethod = targetMethod;
+        CiKind returnKind = targetMethod.signature().returnKind(false);
+        if (returnKind == CiKind.Object && returnType instanceof RiResolvedType) {
+            returnStamp = StampFactory.declared((RiResolvedType) returnType);
+        } else {
+            returnStamp = StampFactory.forKind(returnKind);
+        }
+    }
+
+    @Override
+    public RiType returnType() {
+        return returnType;
+    }
+
+    /**
+     * Gets the target method for this invocation instruction.
+     * @return the target method
+     */
+    public RiResolvedMethod targetMethod() {
+        return targetMethod;
+    }
+
+    public InvokeKind invokeKind() {
+        return invokeKind;
+    }
+
+    public void setInvokeKind(InvokeKind kind) {
+        this.invokeKind = kind;
+    }
+
+    public void setTargetMethod(RiResolvedMethod method) {
+        targetMethod = method;
+    }
+
+    /**
+     * Gets the instruction that produces the receiver object for this invocation, if any.
+     * @return the instruction that produces the receiver object for this invocation if any, {@code null} if this
+     *         invocation does not take a receiver object
+     */
+    public ValueNode receiver() {
+        return isStatic() ? null : arguments().get(0);
+    }
+
+    /**
+     * Checks whether this is an invocation of a static method.
+     * @return {@code true} if the invocation is a static invocation
+     */
+    public boolean isStatic() {
+        return invokeKind() == InvokeKind.Static;
+    }
+
+    @Override
+    public CiKind returnKind() {
+        return targetMethod().signature().returnKind(false);
+    }
+
+    public Invoke invoke() {
+        return (Invoke) this.usages().first();
+    }
+
+
+    @Override
+    public boolean verify() {
+        assert usages().size() <= 1 : "call target may only be used by a single invoke";
+        for (Node n : usages()) {
+            assertTrue(n instanceof Invoke, "call target can only be used from an invoke (%s)", n);
+        }
+        return super.verify();
+    }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Long) {
+            return super.toString(Verbosity.Short) + "(" + targetMethod() + ")";
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (!isStatic()) {
+            ValueNode receiver = receiver();
+            if (receiver != null && receiver.exactType() != null) {
+                if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) {
+                    RiResolvedMethod method = receiver.exactType().resolveMethodImpl(targetMethod);
+                    if (method != null) {
+                        invokeKind = InvokeKind.Special;
+                        targetMethod = method;
+                    }
+                }
+            }
+        }
+        return this;
+    }
+
+    public Stamp returnStamp() {
+        return returnStamp;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/MonitorEnterNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.nodes.java;
+
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+/**
+ * The {@code MonitorEnterNode} represents the acquisition of a monitor.
+ */
+public final class MonitorEnterNode extends AccessMonitorNode implements LIRLowerable {
+
+    /**
+     * Creates a new MonitorEnterNode.
+     *
+     * @param object the instruction producing the object
+     */
+    public MonitorEnterNode(ValueNode object) {
+        super(object);
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitMonitorEnter(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/MonitorExitNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.nodes.java;
+
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.graph.*;
+
+/**
+ * The {@code MonitorEnterNode} represents a monitor release.
+ */
+public final class MonitorExitNode extends AccessMonitorNode implements LIRLowerable, Node.IterableNodeType {
+
+    /**
+     * Creates a new MonitorExitNode.
+     *
+     * @param object the instruction produces the object value
+     */
+    public MonitorExitNode(ValueNode object) {
+        super(object);
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitMonitorExit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/NewArrayNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.java;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code NewArrayNode} class is the base of all instructions that allocate arrays.
+ */
+public abstract class NewArrayNode extends FixedWithNextNode implements EscapeAnalyzable{
+
+    @Input private ValueNode length;
+
+    public static final int MaximumEscapeAnalysisArrayLength = 32;
+
+    public ValueNode length() {
+        return length;
+    }
+
+    /**
+     * Constructs a new NewArrayNode.
+     * @param length the node that produces the length for this allocation
+     */
+    protected NewArrayNode(Stamp stamp, ValueNode length) {
+        super(stamp);
+        this.length = length;
+    }
+
+    /**
+     * The list of node which produce input for this instruction.
+     */
+    public ValueNode dimension(int index) {
+        assert index == 0;
+        return length();
+    }
+
+    /**
+     * The rank of the array allocated by this node, i.e. how many array dimensions.
+     */
+    public int dimensionCount() {
+        return 1;
+    }
+
+    /**
+     * Gets the element type of the array.
+     * @return the element type of the array
+     */
+    public abstract RiResolvedType elementType();
+
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> properties = super.getDebugProperties();
+        properties.put("exactType", exactType());
+        return properties;
+    }
+
+    public EscapeOp getEscapeOp() {
+        return ESCAPE;
+    }
+
+    private static final EscapeOp ESCAPE = new EscapeOp() {
+
+        @Override
+        public boolean canAnalyze(Node node) {
+            NewArrayNode x = (NewArrayNode) node;
+            CiConstant length = x.dimension(0).asConstant();
+            return length != null && length.asInt() >= 0 && length.asInt() < MaximumEscapeAnalysisArrayLength;
+        }
+
+        @Override
+        public EscapeField[] fields(Node node) {
+            NewArrayNode x = (NewArrayNode) node;
+            int length = x.dimension(0).asConstant().asInt();
+            EscapeField[] fields = new EscapeField[length];
+            for (int i = 0; i < length; i++) {
+                Integer representation = i;
+                fields[i] = new EscapeField("[" + i + "]", representation, ((NewArrayNode) node).elementType());
+            }
+            return fields;
+        }
+
+        @Override
+        public void beforeUpdate(Node node, Node usage) {
+            if (usage instanceof ArrayLengthNode) {
+                ArrayLengthNode x = (ArrayLengthNode) usage;
+                StructuredGraph graph = (StructuredGraph) node.graph();
+                x.replaceAtUsages(((NewArrayNode) node).dimension(0));
+                graph.removeFixed(x);
+            } else {
+                super.beforeUpdate(node, usage);
+            }
+        }
+
+        @Override
+        public int updateState(Node node, Node current, Map<Object, Integer> fieldIndex, ValueNode[] fieldState) {
+            if (current instanceof AccessIndexedNode) {
+                AccessIndexedNode x = (AccessIndexedNode) current;
+                if (x.array() == node) {
+                    int index = ((AccessIndexedNode) current).index().asConstant().asInt();
+                    if (current instanceof LoadIndexedNode) {
+                        x.replaceAtUsages(fieldState[index]);
+                        ((StructuredGraph) x.graph()).removeFixed(x);
+                    } else if (current instanceof StoreIndexedNode) {
+                        fieldState[index] = ((StoreIndexedNode) x).value();
+                        ((StructuredGraph) x.graph()).removeFixed(x);
+                        return index;
+                    }
+                }
+            }
+            return -1;
+        }
+    };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/NewInstanceNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.java;
+
+import java.util.*;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code NewInstanceNode} represents the allocation of an instance class object.
+ */
+public final class NewInstanceNode extends FixedWithNextNode implements EscapeAnalyzable, LIRLowerable, Node.IterableNodeType {
+
+    private final RiResolvedType instanceClass;
+
+    /**
+     * Constructs a NewInstanceNode.
+     * @param type the class being allocated
+     */
+    public NewInstanceNode(RiResolvedType type) {
+        super(StampFactory.exactNonNull(type));
+        this.instanceClass = type;
+    }
+
+    /**
+     * Gets the instance class being allocated by this node.
+     * @return the instance class allocated
+     */
+    public RiResolvedType instanceClass() {
+        return instanceClass;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitNewInstance(this);
+    }
+
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> properties = super.getDebugProperties();
+        properties.put("instanceClass", instanceClass);
+        return properties;
+    }
+
+    public EscapeOp getEscapeOp() {
+        return ESCAPE;
+    }
+
+    private static final EscapeOp ESCAPE = new EscapeOp() {
+
+        @Override
+        public boolean canAnalyze(Node node) {
+            return true;
+        }
+
+        private void fillEscapeFields(RiResolvedType type, List<EscapeField> escapeFields) {
+            if (type != null) {
+                fillEscapeFields(type.superType(), escapeFields);
+                RiField[] declaredFields = type.declaredFields();
+                assert declaredFields != null : "the runtime must specify the declared fields of that type";
+                for (RiField field : declaredFields) {
+                    escapeFields.add(new EscapeField(field.name(), field, field.type()));
+                }
+            }
+        }
+
+        @Override
+        public EscapeField[] fields(Node node) {
+            NewInstanceNode x = (NewInstanceNode) node;
+            List<EscapeField> escapeFields = new ArrayList<>();
+            fillEscapeFields(x.instanceClass(), escapeFields);
+            return escapeFields.toArray(new EscapeField[escapeFields.size()]);
+        }
+
+        @Override
+        public void beforeUpdate(Node node, Node usage) {
+            if (usage instanceof RegisterFinalizerNode) {
+                RegisterFinalizerNode x = (RegisterFinalizerNode) usage;
+                ((StructuredGraph) x.graph()).removeFixed(x);
+            } else {
+                super.beforeUpdate(node, usage);
+            }
+        }
+
+        @Override
+        public int updateState(Node node, Node current, Map<Object, Integer> fieldIndex, ValueNode[] fieldState) {
+            if (current instanceof AccessFieldNode) {
+                AccessFieldNode x = (AccessFieldNode) current;
+                if (x.object() == node) {
+                    int field = fieldIndex.get(((AccessFieldNode) current).field());
+                    if (current instanceof LoadFieldNode) {
+                        assert fieldState[field] != null : field + ", " + ((AccessFieldNode) current).field();
+                        x.replaceAtUsages(fieldState[field]);
+                        ((StructuredGraph) x.graph()).removeFixed(x);
+                    } else if (current instanceof StoreFieldNode) {
+                        fieldState[field] = ((StoreFieldNode) x).value();
+                        ((StructuredGraph) x.graph()).removeFixed(x);
+                        return field;
+                    }
+                }
+            }
+            return -1;
+        }
+    };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/NewMultiArrayNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.java;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code NewMultiArrayNode} represents an allocation of a multi-dimensional object
+ * array.
+ */
+public final class NewMultiArrayNode extends FixedWithNextNode implements LIRLowerable {
+
+    @Input private final NodeInputList<ValueNode> dimensions;
+    @Data private final RiResolvedType type;
+
+    public ValueNode dimension(int index) {
+        return dimensions.get(index);
+    }
+
+    public int dimensionCount() {
+        return dimensions.size();
+    }
+
+    /**
+     * Constructs a new NewMultiArrayNode.
+     * @param elementType the element type of the array
+     * @param dimensions the node which produce the dimensions for this array
+     * @param cpi the constant pool index for resolution
+     * @param riConstantPool the constant pool for resolution
+     */
+    public NewMultiArrayNode(RiResolvedType type, ValueNode[] dimensions) {
+        super(StampFactory.exactNonNull(type));
+        this.type = type;
+        this.dimensions = new NodeInputList<>(this, dimensions);
+        assert dimensions.length > 0 && type.isArrayClass();
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitNewMultiArray(this);
+    }
+
+    public RiResolvedType type() {
+        return type;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/NewObjectArrayNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.java;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code NewObjectArrayNode} represents an allocation of an object array.
+ */
+public final class NewObjectArrayNode extends NewArrayNode implements LIRLowerable, Node.IterableNodeType {
+
+    private final RiResolvedType elementClass;
+
+    /**
+     * Constructs a new NewObjectArrayNode.
+     * @param elementClass the class of elements in this array
+     * @param length the node producing the length of the array
+     * @param graph
+     */
+    public NewObjectArrayNode(RiResolvedType elementClass, ValueNode length) {
+        super(StampFactory.exactNonNull(elementClass.arrayOf()), length);
+        this.elementClass = elementClass;
+    }
+
+    @Override
+    public RiResolvedType elementType() {
+        return elementClass;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitNewObjectArray(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/NewTypeArrayNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.java;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code NewTypeArrayNode} class definition.
+ */
+public final class NewTypeArrayNode extends NewArrayNode implements LIRLowerable {
+
+    private final RiResolvedType elementType;
+
+    public NewTypeArrayNode(ValueNode length, RiResolvedType elementType) {
+        super(StampFactory.exactNonNull(elementType.arrayOf()), length);
+        this.elementType = elementType;
+    }
+
+    @Override
+    public RiResolvedType elementType() {
+        return elementType;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitNewTypeArray(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/RegisterFinalizerNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.nodes.java;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * This node is used to perform the finalizer registration at the end of the java.lang.Object constructor.
+ */
+public final class RegisterFinalizerNode extends AbstractStateSplit implements Canonicalizable, LIRLowerable {
+
+    @Input private ValueNode object;
+
+    public ValueNode object() {
+        return object;
+    }
+
+    public RegisterFinalizerNode(ValueNode object) {
+        super(StampFactory.illegal());
+        this.object = object;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.emitCallToRuntime(CiRuntimeCall.RegisterFinalizer, true, gen.operand(object()));
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        RiResolvedType declaredType = object.declaredType();
+        RiResolvedType exactType = object.exactType();
+        if (exactType == null && declaredType != null) {
+            exactType = declaredType.exactType();
+        }
+
+        boolean needsCheck = true;
+        if (exactType != null) {
+            // we have an exact type
+            needsCheck = exactType.hasFinalizer();
+        } else {
+            // if either the declared type of receiver or the holder can be assumed to have no finalizers
+            if (declaredType != null && !declaredType.hasFinalizableSubclass()) {
+                if (tool.assumptions() != null && tool.assumptions().recordNoFinalizableSubclassAssumption(declaredType)) {
+                    needsCheck = false;
+                }
+            }
+        }
+
+        if (!needsCheck) {
+            return null;
+        }
+
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/StoreFieldNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.java;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code StoreFieldNode} represents a write to a static or instance field.
+ */
+public final class StoreFieldNode extends AccessFieldNode implements LIRLowerable {
+
+    @Input private ValueNode value;
+
+    public ValueNode value() {
+        return value;
+    }
+
+    /**
+     * Creates a new StoreFieldNode.
+     * @param object the receiver object
+     * @param field the compiler interface field
+     * @param value the node representing the value to store to the field
+     */
+    public StoreFieldNode(ValueNode object, RiResolvedField field, ValueNode value) {
+        super(StampFactory.illegal(), object, field);
+        this.value = value;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitStoreField(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/StoreIndexedNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.java;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code StoreIndexedNode} represents a write to an array element.
+ */
+public final class StoreIndexedNode extends AccessIndexedNode implements Lowerable, LIRLowerable {
+
+    @Input private ValueNode value;
+
+    public ValueNode value() {
+        return value;
+    }
+
+    /**
+     * Creates a new StoreIndexedNode.
+     * @param array the node producing the array
+     * @param index the node producing the index
+     * @param length the node producing the length
+     * @param elementKind the element type
+     * @param value the value to store into the array
+     */
+    public StoreIndexedNode(ValueNode array, ValueNode index, ValueNode length, CiKind elementKind, ValueNode value) {
+        super(StampFactory.illegal(), array, index, length, elementKind);
+        this.value = value;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.visitStoreIndexed(this);
+    }
+
+    @Override
+    public void lower(CiLoweringTool tool) {
+        tool.getRuntime().lower(this, tool);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/TypeCheckNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2009, 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.max.graal.nodes.java;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.type.*;
+
+/**
+ * The {@code TypeCheckNode} is the base class of casts and instanceof tests.
+ */
+public abstract class TypeCheckNode extends BooleanNode {
+
+    protected static final RiResolvedType[] EMPTY_HINTS = new RiResolvedType[0];
+    @Input private ValueNode object;
+    @Input private ValueNode targetClassInstruction;
+    @Data private final RiResolvedType targetClass;
+    @Data private final RiResolvedType[] hints;
+    @Data private final boolean hintsExact;
+
+    /**
+     * Creates a new TypeCheckNode.
+     * @param targetClassInstruction the instruction which produces the class which is being cast to or checked against
+     * @param targetClass the class that is being casted to or checked against
+     * @param object the node which produces the object
+     * @param kind the result type of this node
+     */
+    public TypeCheckNode(ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, RiResolvedType[] hints, boolean hintsExact, Stamp stamp) {
+        super(stamp);
+        this.targetClassInstruction = targetClassInstruction;
+        this.targetClass = targetClass;
+        this.object = object;
+        this.hints = hints;
+        this.hintsExact = hintsExact;
+    }
+
+    public ValueNode object() {
+        return object;
+    }
+
+    public ValueNode targetClassInstruction() {
+        return targetClassInstruction;
+    }
+
+    /**
+     * Gets the target class, i.e. the class being cast to, or the class being tested against.
+     * @return the target class
+     */
+    public RiResolvedType targetClass() {
+        return targetClass;
+    }
+
+    public RiResolvedType[] hints() {
+        return hints;
+    }
+
+    public boolean hintsExact() {
+        return hintsExact;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/Canonicalizable.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,30 @@
+/*
+ * 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.max.graal.nodes.spi;
+
+import com.oracle.max.graal.nodes.*;
+
+public interface Canonicalizable {
+
+    ValueNode canonical(CanonicalizerTool tool);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/CanonicalizerTool.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.max.graal.nodes.spi;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+
+
+public interface CanonicalizerTool {
+    CiTarget target();
+    CiAssumptions assumptions();
+    RiRuntime runtime();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/EscapeAnalyzable.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,28 @@
+/*
+ * 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.max.graal.nodes.spi;
+
+public interface EscapeAnalyzable {
+
+    EscapeOp getEscapeOp();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/EscapeField.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * 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.max.graal.nodes.spi;
+
+import com.oracle.max.cri.ri.*;
+
+public class EscapeField {
+
+    private String name;
+    private Object representation;
+    private RiType type;
+
+    public EscapeField(String name, Object representation, RiType type) {
+        this.name = name;
+        this.representation = representation;
+        this.type = type;
+    }
+
+    public String name() {
+        return name;
+    }
+
+    public Object representation() {
+        return representation;
+    }
+
+    public RiType type() {
+        return type;
+    }
+
+    @Override
+    public String toString() {
+        return name();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/EscapeOp.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,117 @@
+/*
+ * 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.max.graal.nodes.spi;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.java.*;
+import com.oracle.max.graal.nodes.virtual.*;
+
+
+public abstract class EscapeOp {
+
+    public abstract boolean canAnalyze(Node node);
+
+    public boolean escape(Node node, Node usage) {
+        if (usage instanceof NullCheckNode) {
+            assert ((NullCheckNode) usage).object() == node;
+            return false;
+        } else if (usage instanceof IsTypeNode) {
+            assert ((IsTypeNode) usage).objectClass() == node;
+            return false;
+        } else if (usage instanceof FrameState) {
+            assert usage.inputs().contains(node);
+            return true;
+        } else if (usage instanceof AccessMonitorNode) {
+            assert ((AccessMonitorNode) usage).object() == node;
+            return false;
+        } else if (usage instanceof LoadFieldNode) {
+            assert ((LoadFieldNode) usage).object() == node;
+            return false;
+        } else if (usage instanceof StoreFieldNode) {
+            StoreFieldNode x = (StoreFieldNode) usage;
+            // self-references do escape
+            return x.value() == node; // TODO(tw) Check if we can add this condition? && x.object() != node;
+        } else if (usage instanceof LoadIndexedNode) {
+            LoadIndexedNode x = (LoadIndexedNode) usage;
+            if (x.index() == node) {
+                return true;
+            } else {
+                assert x.array() == node;
+                return !isValidConstantIndex(x);
+            }
+        } else if (usage instanceof StoreIndexedNode) {
+            StoreIndexedNode x = (StoreIndexedNode) usage;
+            if (x.index() == node) {
+                return true;
+            } else {
+                assert x.array() == node || x.value() == node;
+                // in order to not escape the access needs to have a valid constant index and either a store into node or self-referencing
+                return !isValidConstantIndex(x) || x.value() == node && x.array() != node;
+            }
+        } else if (usage instanceof VirtualObjectFieldNode) {
+            return false;
+        } else if (usage instanceof RegisterFinalizerNode) {
+            assert ((RegisterFinalizerNode) usage).object() == node;
+            return false;
+        } else if (usage instanceof ArrayLengthNode) {
+            assert ((ArrayLengthNode) usage).array() == node;
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    public static boolean isValidConstantIndex(AccessIndexedNode x) {
+        CiConstant index = x.index().asConstant();
+        if (x.array() instanceof NewArrayNode) {
+            CiConstant length = ((NewArrayNode) x.array()).dimension(0).asConstant();
+            return index != null && length != null && index.asInt() >= 0 && index.asInt() < length.asInt();
+        } else {
+            return false;
+        }
+    }
+
+    public abstract EscapeField[] fields(Node node);
+
+    public void beforeUpdate(Node node, Node usage) {
+        // IsNonNullNode and IsTypeNode should have been eliminated by the CanonicalizerPhase, but we can't rely on this
+        if (usage instanceof NullCheckNode) {
+            NullCheckNode x = (NullCheckNode) usage;
+            ((StructuredGraph) x.graph()).replaceFloating(x, ConstantNode.forBoolean(!x.expectedNull, node.graph()));
+        } else if (usage instanceof IsTypeNode) {
+            IsTypeNode x = (IsTypeNode) usage;
+            assert x.type() == ((ValueNode) node).exactType();
+            ((StructuredGraph) x.graph()).replaceFloating(x, ConstantNode.forBoolean(true, node.graph()));
+        } else if (usage instanceof AccessMonitorNode) {
+            ((AccessMonitorNode) usage).eliminate();
+        }
+    }
+
+    public abstract int updateState(Node node, Node current, Map<Object, Integer> fieldIndex, ValueNode[] fieldState);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/FrameStateAccess.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * 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.max.graal.nodes.spi;
+
+import com.oracle.max.graal.nodes.*;
+
+public interface FrameStateAccess {
+
+    FrameState duplicate(int newBci);
+
+    int localsSize();
+
+    int stackSize();
+
+    boolean rethrowException();
+
+    ValueNode valueAt(int i);
+
+    ValueNode localAt(int i);
+
+    ValueNode stackAt(int i);
+
+    FrameState outerFrameState();
+
+    FrameState duplicateWithException(int bci, ValueNode exceptionObject);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/LIRGeneratorTool.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.nodes.spi;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.java.*;
+
+public abstract class LIRGeneratorTool {
+    public abstract CiTarget target();
+
+    /**
+     * Checks whether the supplied constant can be used without loading it into a register
+     * for most operations, i.e., for commonly used arithmetic, logical, and comparison operations.
+     * @param c The constant to check.
+     * @return True if the constant can be used directly, false if the constant needs to be in a register.
+     */
+    public abstract boolean canInlineConstant(CiConstant c);
+
+    /**
+     * Checks whether the supplied constant can be used without loading it into a register
+     * for store operations, i.e., on the right hand side of a memory access.
+     * @param c The constant to check.
+     * @return True if the constant can be used directly, false if the constant needs to be in a register.
+     */
+    public abstract boolean canStoreConstant(CiConstant c);
+
+    public abstract CiValue operand(ValueNode object);
+    public abstract CiValue newVariable(CiKind kind);
+    public abstract CiValue setResult(ValueNode x, CiValue operand);
+
+    public abstract CiAddress makeAddress(LocationNode location, ValueNode object);
+
+    public abstract CiValue emitMove(CiValue input);
+    public abstract void emitMove(CiValue src, CiValue dst);
+    public abstract CiValue emitLoad(CiValue loadAddress, boolean canTrap);
+    public abstract void emitStore(CiValue storeAddress, CiValue input, boolean canTrap);
+    public abstract CiValue emitLea(CiValue address);
+
+    public abstract CiValue emitNegate(CiValue input);
+    public abstract CiValue emitAdd(CiValue a, CiValue b);
+    public abstract CiValue emitSub(CiValue a, CiValue b);
+    public abstract CiValue emitMul(CiValue a, CiValue b);
+    public abstract CiValue emitDiv(CiValue a, CiValue b);
+    public abstract CiValue emitRem(CiValue a, CiValue b);
+    public abstract CiValue emitUDiv(CiValue a, CiValue b);
+    public abstract CiValue emitURem(CiValue a, CiValue b);
+
+    public abstract CiValue emitAnd(CiValue a, CiValue b);
+    public abstract CiValue emitOr(CiValue a, CiValue b);
+    public abstract CiValue emitXor(CiValue a, CiValue b);
+
+    public abstract CiValue emitShl(CiValue a, CiValue b);
+    public abstract CiValue emitShr(CiValue a, CiValue b);
+    public abstract CiValue emitUShr(CiValue a, CiValue b);
+
+    public abstract CiValue emitConvert(ConvertNode.Op opcode, CiValue inputVal);
+    public abstract void emitMembar(int barriers);
+    public abstract void emitDeoptimizeOn(Condition of, DeoptAction action, Object deoptInfo);
+    public abstract CiValue emitCallToRuntime(CiRuntimeCall runtimeCall, boolean canTrap, CiValue... args);
+
+    public abstract void emitIf(IfNode i);
+    public abstract void emitConditional(ConditionalNode i);
+    public abstract void emitGuardCheck(BooleanNode comp);
+
+    public abstract void emitLookupSwitch(LookupSwitchNode i);
+    public abstract void emitTableSwitch(TableSwitchNode i);
+
+    public abstract void emitInvoke(Invoke i);
+    public abstract void emitRuntimeCall(RuntimeCallNode i);
+
+    // Handling of block-end nodes still needs to be unified in the LIRGenerator.
+    public abstract void visitMerge(MergeNode i);
+    public abstract void visitEndNode(EndNode i);
+    public abstract void visitLoopEnd(LoopEndNode i);
+
+    // The CompareAndSwapNode in its current form needs to be lowered to several Nodes before code generation to separate three parts:
+    // * The write barriers (and possibly read barriers) when accessing an object field
+    // * The distinction of returning a boolean value (semantic similar to a BooleanNode to be used as a condition?) or the old value being read
+    // * The actual compare-and-swap
+    public abstract void visitCompareAndSwap(CompareAndSwapNode i);
+
+    // Functionality that is currently implemented in XIR.
+    // These methods will go away eventually when lowering is done via snippets in the front end.
+    public abstract void visitArrayLength(ArrayLengthNode i);
+    public abstract void visitCheckCast(CheckCastNode i);
+    public abstract void visitMonitorEnter(MonitorEnterNode i);
+    public abstract void visitMonitorExit(MonitorExitNode i);
+    public abstract void visitLoadField(LoadFieldNode i);
+    public abstract void visitStoreField(StoreFieldNode i);
+    public abstract void visitLoadIndexed(LoadIndexedNode i);
+    public abstract void visitStoreIndexed(StoreIndexedNode i);
+    public abstract void visitNewInstance(NewInstanceNode i);
+    public abstract void visitNewTypeArray(NewTypeArrayNode i);
+    public abstract void visitNewObjectArray(NewObjectArrayNode i);
+    public abstract void visitNewMultiArray(NewMultiArrayNode i);
+    public abstract void visitExceptionObject(ExceptionObjectNode i);
+    public abstract void visitReturn(ReturnNode i);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/LIRLowerable.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,28 @@
+/*
+ * 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.max.graal.nodes.spi;
+
+public interface LIRLowerable {
+
+    void generate(LIRGeneratorTool generator);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/Lowerable.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,30 @@
+/*
+ * 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.max.graal.nodes.spi;
+
+import com.oracle.max.graal.cri.*;
+
+public interface Lowerable {
+
+    void lower(CiLoweringTool tool);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/Simplifiable.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,35 @@
+/*
+ * 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.max.graal.nodes.spi;
+
+/**
+ * This interface allows nodes to perform more complicated simplifications, in contrast to {@link Canonicalizable},
+ * which supports only replacing the current node.
+ *
+ * Implementors of this interface need to be aware that they need to call {@link SimplifierTool#addToWorkList(com.oracle.max.graal.graph.Node)} for each node that might
+ * be influenced (in terms of simplification and canonicalization) by the actions performed in simplify.
+ */
+public interface Simplifiable {
+
+    void simplify(SimplifierTool tool);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/SimplifierTool.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,32 @@
+/*
+ * 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.max.graal.nodes.spi;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+
+
+public interface SimplifierTool extends CanonicalizerTool {
+    void deleteBranch(FixedNode branch);
+    void addToWorkList(Node node);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/type/Stamp.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,35 @@
+/*
+ * 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.max.graal.nodes.type;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+
+
+public interface Stamp {
+    boolean nonNull();
+    RiResolvedType declaredType();
+    RiResolvedType exactType();
+    CiKind kind();
+    boolean alwaysDistinct(Stamp other);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/type/StampFactory.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,207 @@
+/*
+ * 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.max.graal.nodes.type;
+
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+
+
+public class StampFactory {
+
+    private static class BasicValueStamp implements Stamp {
+
+        private final CiKind kind;
+        private final boolean nonNull;
+        private RiResolvedType declaredType;
+        private RiResolvedType exactType;
+
+        public BasicValueStamp(CiKind kind) {
+            this(kind, false, null, null);
+        }
+
+        public BasicValueStamp(CiKind kind, boolean nonNull, RiResolvedType declaredType, RiResolvedType exactType) {
+            this.kind = kind;
+            this.nonNull = nonNull;
+            this.declaredType = declaredType;
+            this.exactType = exactType;
+        }
+
+        @Override
+        public CiKind kind() {
+            return kind;
+        }
+
+        @Override
+        public boolean nonNull() {
+            return nonNull;
+        }
+
+        @Override
+        public RiResolvedType declaredType() {
+            return declaredType;
+        }
+
+        @Override
+        public RiResolvedType exactType() {
+            return exactType;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this) {
+                return true;
+            }
+            if (obj instanceof Stamp) {
+                Stamp other = (Stamp) obj;
+                return kind == other.kind() && nonNull() == other.nonNull() && declaredType() == other.declaredType() && exactType() == other.exactType();
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return kind.hashCode();
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%c%s %s %s", kind().typeChar, nonNull ? "!" : "", declaredType == null ? "-" : declaredType.name(), exactType == null ? "-" : exactType.name());
+        }
+
+        @Override
+        public boolean alwaysDistinct(Stamp other) {
+            if (other.kind() != kind()) {
+                return true;
+            } else if (kind() != CiKind.Object) {
+                return false;
+            } else if (other.declaredType() == null || declaredType() == null) {
+                // We have no type information for one of the values.
+                return false;
+            } else if (other.nonNull() || nonNull()) {
+                // One of the two values cannot be null.
+                return !other.declaredType().isInterface() && !declaredType().isInterface() && !other.declaredType().isSubtypeOf(declaredType()) && !declaredType().isSubtypeOf(other.declaredType());
+            } else {
+                // Both values may be null.
+                return false;
+            }
+        }
+    }
+
+    private static final Stamp[] stampCache = new Stamp[CiKind.values().length];
+    static {
+        for (CiKind k : CiKind.values()) {
+            stampCache[k.ordinal()] = new BasicValueStamp(k);
+        }
+    }
+
+    public static Stamp illegal() {
+        return forKind(CiKind.Illegal);
+    }
+
+    public static Stamp intValue() {
+        return forKind(CiKind.Int);
+    }
+
+    public static Stamp forKind(CiKind kind) {
+        return stampCache[kind.stackKind().ordinal()];
+    }
+
+    public static Stamp exactNonNull(final RiResolvedType type) {
+        // (cwi) type can be null for certain Maxine-internal objects such as the static hub. Is this a problem here?
+        assert type == null || type.kind(false) == CiKind.Object;
+        return new BasicValueStamp(CiKind.Object, true, type, type);
+    }
+
+    public static Stamp forConstant(CiConstant value, RiRuntime runtime) {
+        if (runtime != null && value.kind == CiKind.Object && !value.isNull()) {
+            return exactNonNull(runtime.getTypeOf(value));
+        } else {
+            return forKind(value.kind.stackKind());
+        }
+    }
+
+    public static Stamp objectNonNull() {
+        return new BasicValueStamp(CiKind.Object, true, null, null);
+    }
+
+    public static Stamp declared(final RiResolvedType type) {
+        assert type != null;
+        assert type.kind(false) == CiKind.Object;
+        return new BasicValueStamp(CiKind.Object, false, type, type.exactType());
+    }
+
+    public static Stamp declaredNonNull(final RiResolvedType type) {
+        assert type != null;
+        assert type.kind(false) == CiKind.Object;
+        return new BasicValueStamp(CiKind.Object, true, type, type.exactType());
+    }
+
+    public static Stamp or(Collection<? extends StampProvider> values) {
+        if (values.size() == 0) {
+            return illegal();
+        } else {
+            Iterator< ? extends StampProvider> iterator = values.iterator();
+            Stamp first = iterator.next().stamp();
+            if (values.size() == 1) {
+                return first;
+            }
+
+            boolean nonNull = first.nonNull();
+            RiResolvedType declaredType = first.declaredType();
+            RiResolvedType exactType = first.exactType();
+            while (iterator.hasNext()) {
+                Stamp current = iterator.next().stamp();
+                assert current.kind() == first.kind() : values + " first=" + first + " current=" + current + " first kind=" + first.kind() + " current kind=" + current.kind();
+                nonNull &= current.nonNull();
+                declaredType = orTypes(declaredType, current.declaredType());
+                if (exactType != current.exactType()) {
+                    exactType = null;
+                }
+            }
+
+            if (nonNull != first.nonNull() || declaredType != first.declaredType() || exactType != first.exactType()) {
+                return new BasicValueStamp(first.kind(), nonNull, declaredType, exactType);
+            } else {
+                return first;
+            }
+        }
+    }
+
+    private static RiResolvedType orTypes(RiResolvedType a, RiResolvedType b) {
+        if (a == b) {
+            return a;
+        } else if (a == null || b == null) {
+            return null;
+        } else {
+            if (a.isSubtypeOf(b)) {
+                return b;
+            } else if (b.isSubtypeOf(a)) {
+                return a;
+            } else {
+                return null;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/type/StampProvider.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,28 @@
+/*
+ * 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.max.graal.nodes.type;
+
+
+public interface StampProvider {
+    Stamp stamp();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/util/GraphUtil.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,104 @@
+/*
+ * 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.max.graal.nodes.util;
+
+import static com.oracle.max.graal.graph.iterators.NodePredicates.*;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.calc.*;
+
+public class GraphUtil {
+
+    public static void killCFG(FixedNode node) {
+        assert node.isAlive();
+        if (node instanceof EndNode) {
+            // We reached a control flow end.
+            EndNode end = (EndNode) node;
+            killEnd(end);
+        } else {
+            // Normal control flow node.
+            for (Node successor : node.successors().snapshot()) {
+                killCFG((FixedNode) successor);
+            }
+        }
+        propagateKill(node);
+    }
+
+    private static void killEnd(EndNode end) {
+        MergeNode merge = end.merge();
+        merge.removeEnd(end);
+        if (merge instanceof LoopBeginNode && merge.forwardEndCount() == 0) { //dead loop
+            for (PhiNode phi : merge.phis().snapshot()) {
+                propagateKill(phi);
+            }
+            LoopBeginNode begin = (LoopBeginNode) merge;
+            // disconnect and delete loop ends
+            for (LoopEndNode loopend : begin.loopEnds().snapshot()) {
+                loopend.predecessor().replaceFirstSuccessor(loopend, null);
+                loopend.safeDelete();
+            }
+            FixedNode next = begin.next();
+            begin.safeDelete();
+            killCFG(next);
+        } else if (merge instanceof LoopBeginNode && ((LoopBeginNode) merge).loopEnds().isEmpty()) { // not a loop anymore
+            ((StructuredGraph) end.graph()).reduceDegenerateLoopBegin((LoopBeginNode) merge);
+        } else if (merge.phiPredecessorCount() == 1) { // not a merge anymore
+            ((StructuredGraph) end.graph()).reduceTrivialMerge(merge);
+        }
+    }
+
+    public static void propagateKill(Node node) {
+        if (node != null && node.isAlive()) {
+            List<Node> usagesSnapshot = node.usages().filter(isA(FloatingNode.class).or(CallTargetNode.class).or(FrameState.class)).snapshot();
+
+            // null out remaining usages
+            node.replaceAtUsages(null);
+            node.replaceAtPredecessors(null);
+            killUnusedFloatingInputs(node);
+
+            for (Node usage : usagesSnapshot) {
+                if (!usage.isDeleted()) {
+                    if (usage instanceof PhiNode) {
+                        usage.replaceFirstInput(node, null);
+                    } else {
+                        propagateKill(usage);
+                    }
+                }
+            }
+        }
+    }
+
+    public static void killUnusedFloatingInputs(Node node) {
+        List<Node> floatingInputs = node.inputs().filter(isA(FloatingNode.class).or(CallTargetNode.class).or(FrameState.class)).snapshot();
+        node.safeDelete();
+
+        for (Node in : floatingInputs) {
+            if (in.isAlive() && in.usages().isEmpty()) {
+                killUnusedFloatingInputs(in);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/virtual/BoxedVirtualObjectNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,44 @@
+/*
+ * 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.max.graal.nodes.virtual;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+
+
+public class BoxedVirtualObjectNode extends VirtualObjectNode implements LIRLowerable, Node.ValueNumberable {
+
+    @Input ValueNode unboxedValue;
+
+    public BoxedVirtualObjectNode(RiResolvedType type, ValueNode unboxedValue) {
+        super(type, 1);
+        this.unboxedValue = unboxedValue;
+    }
+
+
+    public ValueNode getUnboxedValue() {
+        return unboxedValue;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/virtual/VirtualObjectFieldNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,83 @@
+/*
+ * 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.max.graal.nodes.virtual;
+
+import java.util.*;
+
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public class VirtualObjectFieldNode extends ValueNode implements LIRLowerable {
+
+    @Input private VirtualObjectNode object;
+    @Input private ValueNode lastState;
+    @Input private ValueNode input;
+
+    private int index;
+
+    public VirtualObjectNode object() {
+        return object;
+    }
+
+    public ValueNode lastState() {
+        return lastState;
+    }
+
+    public ValueNode input() {
+        return input;
+    }
+
+    public VirtualObjectFieldNode(VirtualObjectNode object, ValueNode lastState, ValueNode input, int index) {
+        super(StampFactory.illegal());
+        this.index = index;
+        this.object = object;
+        this.lastState = lastState;
+        this.input = input;
+    }
+
+    public int index() {
+        return index;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        // nothing to do...
+    }
+
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> properties = super.getDebugProperties();
+        properties.put("index", index);
+        return properties;
+    }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Name && object().fields() != null) {
+            return super.toString(Verbosity.Name) + " " + object().fields()[index].name();
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/virtual/VirtualObjectNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * 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.max.graal.nodes.virtual;
+
+import java.util.*;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+
+public class VirtualObjectNode extends ValueNode implements LIRLowerable {
+
+    @Data private RiType type;
+    private EscapeField[] fields;
+    private int fieldsCount;
+
+    public VirtualObjectNode(RiType type, EscapeField[] fields) {
+        super(StampFactory.illegal());
+        this.type = type;
+        this.fields = fields;
+        this.fieldsCount = fields.length;
+    }
+
+    public VirtualObjectNode(RiType type, int fieldCount) {
+        super(StampFactory.illegal());
+        this.type = type;
+        this.fieldsCount = fieldCount;
+    }
+
+    public RiType type() {
+        return type;
+    }
+
+    public EscapeField[] fields() {
+        return fields;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        // nothing to do...
+    }
+
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> properties = super.getDebugProperties();
+        properties.put("type", type);
+        return properties;
+    }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Name) {
+            return super.toString(Verbosity.Name) + " " + type.name();
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+
+    public int fieldsCount() {
+        return fieldsCount;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/util/ComputeImmediateDominator.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,261 @@
+/*
+ * 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.max.graal.util;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+
+
+public final class ComputeImmediateDominator {
+    private final MergeNode dominated;
+    private final Queue<FixedNode> toExplore;
+    private final Queue<FixedNode> speculativeExplore;
+    private final NodeMap<DominatorInfo> infoMap;
+    private final DominatorInfo fullInfo;
+    private FixedNode dominator;
+    private int nextBit = 1;
+
+    public ComputeImmediateDominator(MergeNode dominated) {
+        this.dominated = dominated;
+        this.toExplore = new LinkedList<>();
+        this.speculativeExplore = new LinkedList<>();
+        this.infoMap = dominated.graph().createNodeMap();
+        fullInfo = new DominatorInfo(dominated, true);
+
+        this.processMerge(dominated, fullInfo);
+        if (toExplore.size() == 1) {
+            dominator = toExplore.remove();
+        }
+    }
+
+    public FixedNode compute() {
+        try {
+            while (dominator == null && (!toExplore.isEmpty() || !speculativeExplore.isEmpty())) {
+                while (!toExplore.isEmpty()) {
+                    exploreUp(toExplore.remove());
+                    if (dominator != null) {
+                        return dominator;
+                    }
+                }
+                exploreUp(speculativeExplore.remove());
+            }
+            return dominator;
+        } catch (Throwable t) {
+            throw new GraalInternalError(t).addContext("Could not find a dominator").addContext(dominated);
+        }
+    }
+
+    private void exploreUp(FixedNode from) {
+        FixedNode p = from;
+        DominatorInfo info = infoMap.get(from);
+        if (info.isExplored()) {
+            return;
+        }
+        //TTY.println("exploreUp(" + from + ") with " + info);
+        info.setExplored();
+        while (p != null) {
+            if (p instanceof MergeNode) {
+                processMerge((MergeNode) p, info);
+                p = null;
+            } else if (p instanceof ControlSplitNode) {
+                processControlSplit((ControlSplitNode) p, info);
+                p = null;
+            } else {
+                p = (FixedNode) p.predecessor();
+            }
+        }
+    }
+
+    private void processControlSplit(ControlSplitNode cs, DominatorInfo info) {
+        //TTY.println("processControlSplit(" + cs + ", " + info + ")");
+        DominatorInfo csInfo = infoMap.get(cs);
+        if (csInfo == null) {
+            csInfo = new DominatorInfo(cs, false);
+            infoMap.set(cs, csInfo);
+        }
+        csInfo.add(info);
+        FixedNode next = (FixedNode) cs.predecessor();
+        if (checkControlSplitInfo(csInfo)) {
+            return;
+        }
+        if (csInfo.isExplored()) {
+            //TTY.println("  Already explored, propagate update");
+            propagateUpdate(csInfo);
+        } else {
+            if (csInfo.parentCount() == cs.blockSuccessorCount()) { // all paths leading to this CS have been explored
+                //TTY.println("  All parents explored, Enqueue");
+                toExplore.add(next);
+                speculativeExplore.remove(next);
+            } else {
+                //TTY.println("  Not all parents explored : Enqueue speculative");
+                speculativeExplore.add(next);
+            }
+        }
+        infoMap.set(next, csInfo);
+    }
+
+    private boolean propagateUpdate(DominatorInfo di) {
+        //TTY.println("   propagateUpdate(" + di + ")");
+        for (DominatorInfo child : di.children()) {
+            //TTY.println("      add to child " + child);
+            if (child.add(di, false)) {
+                if (child.equals(fullInfo)) {
+                    //TTY.println("   Found DOM!");
+                    dominator = child.node();
+                    return true;
+                }
+                if (propagateUpdate(child)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private boolean checkControlSplitInfo(DominatorInfo di) {
+        //TTY.println("   checkControlSplitInfo(" + di + ")");
+        if (di.equals(fullInfo)) {
+            dominator = di.node();
+            //TTY.println("   Found DOM!");
+            return true;
+        }
+        return false;
+    }
+
+    private void processMerge(MergeNode merge, DominatorInfo info) {
+        //TTY.println("processMerge(" + merge + ", " + info + ")");
+        for (EndNode end : merge.cfgPredecessors()) {
+            toExplore.add(end);
+            infoMap.set(end, info.createChild(end));
+            //TTY.println("  Enqueue end : " + end + " with " + infoMap.get(end));
+        }
+    }
+
+    private class DominatorInfo {
+        private final FixedNode node;
+        private final BitSet bits;
+        private final BitSet ownBits;
+        private final Collection<DominatorInfo> children;
+        private final Collection<DominatorInfo> parents;
+        private boolean explored;
+
+        public DominatorInfo(FixedNode node, boolean full) {
+            this.node = node;
+            this.bits = new BitSet();
+            this.ownBits = new BitSet();
+            this.children = new ArrayList<>(2);
+            this.parents = new ArrayList<>(2);
+            if (full) {
+                addOwnBits(0);
+            }
+        }
+
+        public boolean isExplored() {
+            return explored;
+        }
+
+        public void setExplored() {
+            explored = true;
+        }
+
+        public DominatorInfo createChild(FixedNode childNode) {
+            DominatorInfo di = new DominatorInfo(childNode, false);
+            di.bits.or(bits);
+            di.ownBits.or(ownBits);
+            if (!children.isEmpty() || di.ownBits.isEmpty()) {
+                int newBit = nextBit++;
+                di.bits.xor(ownBits);
+                di.bits.set(newBit);
+                di.ownBits.clear();
+                di.ownBits.set(newBit);
+                addOwnBits(newBit);
+            }
+            children.add(di);
+            di.parents.add(this);
+            return di;
+        }
+
+        private void addOwnBits(int newBit) {
+            if (!bits.get(newBit)) {
+                ownBits.set(newBit);
+                bits.set(newBit);
+                for (DominatorInfo parent : parents) {
+                    parent.addOwnBits(newBit);
+                }
+            }
+        }
+
+        public boolean add(DominatorInfo i) {
+            return add(i, true);
+        }
+
+        public boolean add(DominatorInfo i, boolean addParent) {
+            boolean ret = true;
+            if (addParent) {
+                parents.add(i);
+                i.children.add(this);
+                bits.or(i.bits);
+            } else {
+                BitSet newBits = (BitSet) i.bits.clone();
+                newBits.andNot(bits);
+                newBits.andNot(i.ownBits);
+                ret = !newBits.isEmpty();
+                bits.or(newBits);
+            }
+            return ret;
+        }
+
+        public int parentCount() {
+            return parents.size();
+        }
+
+
+        public FixedNode node() {
+            return node;
+        }
+
+        public Collection<DominatorInfo> children() {
+            return children;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (!(obj instanceof DominatorInfo)) {
+                return false;
+            }
+            return ((DominatorInfo) obj).bits.equals(bits);
+        }
+
+        @Override
+        public String toString() {
+            return bits + " (o" + ownBits + ") " + node;
+        }
+
+        @Override
+        public int hashCode() {
+            return bits.hashCode();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/util/NodeIterators.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * 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.max.graal.util;
+
+import java.util.*;
+
+import com.oracle.max.graal.graph.iterators.*;
+import com.oracle.max.graal.nodes.*;
+
+public class NodeIterators {
+
+    public static NodeIterable<FixedNode> dominators(final FixedNode n) {
+        return new NodeIterable<FixedNode>() {
+            @Override
+            public Iterator<FixedNode> iterator() {
+                return new NodeIterator<FixedNode>(){
+                    FixedNode p = n;
+                    @Override
+                    protected void forward() {
+                        if (current == null) {
+                            if (p instanceof MergeNode) {
+                                current = new ComputeImmediateDominator((MergeNode) p).compute();
+                            } else {
+                                current = (FixedNode) p.predecessor();
+                            }
+                            p = current;
+                        }
+                    }
+                };
+            }
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/util/TreeIterators.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * 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.max.graal.util;
+
+import java.util.*;
+
+public class TreeIterators {
+
+    public abstract static class PrefixTreeIterator<T> implements Iterator<T>{
+        private Deque<T> stack = new LinkedList<>();
+
+        public PrefixTreeIterator(T root) {
+            stack.push(root);
+        }
+
+        public PrefixTreeIterator(Iterable<T> roots) {
+            for (T root : roots) {
+                stack.addLast(root);
+            }
+        }
+
+        @Override
+        public boolean hasNext() {
+            return !stack.isEmpty();
+        }
+
+        @Override
+        public T next() {
+            T top = stack.pop();
+            LinkedList<T> list = new LinkedList<>();
+            for (T child : children(top)) {
+                list.addFirst(child);
+            }
+            for (T child : list) {
+                stack.push(child);
+            }
+            return top;
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        protected abstract Iterable<T> children(T node);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.nodes/test/test/com/oracle/max/graal/nodes/Main.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,29 @@
+/*
+ * 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 test.com.oracle.max.graal.nodes;
+
+
+public class Main {
+    public static void main(String[] args) {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/BasicIdealGraphPrinter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,313 @@
+/*
+ * 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.max.graal.printer;
+
+import java.io.*;
+import java.util.*;
+import java.util.Map.Entry;
+
+/**
+ * Elementary, generic generator of Ideal Graph Visualizer input for use in printers for specific data structures.
+ */
+class BasicIdealGraphPrinter {
+
+    /**
+     * Edge between two nodes.
+     */
+    protected static class Edge {
+        final String from;
+        final int fromIndex;
+        final String to;
+        final int toIndex;
+        final String label;
+
+        public Edge(String from, int fromIndex, String to, int toIndex, String label) {
+            assert (from != null && to != null);
+            this.from = from;
+            this.fromIndex = fromIndex;
+            this.to = to;
+            this.toIndex = toIndex;
+            this.label = label;
+        }
+
+        @Override
+        public int hashCode() {
+            int h = from.hashCode() ^ to.hashCode();
+            h = 3 * h + fromIndex;
+            h = 5 * h + toIndex;
+            if (label != null) {
+                h ^= label.hashCode();
+            }
+            return h;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this) {
+                return true;
+            }
+            if (obj instanceof Edge) {
+                Edge other = (Edge) obj;
+                return from.equals(other.from)
+                        && fromIndex == other.fromIndex
+                        && to.equals(other.to)
+                        && toIndex == other.toIndex
+                        && (label == other.label || (label != null && label.equals(other.label)));
+            }
+            return false;
+        }
+    }
+
+    private final PrintStream stream;
+
+    /**
+     * Creates a new {@link IdealGraphPrinter} that writes to the specified output stream.
+     */
+    protected BasicIdealGraphPrinter(OutputStream stream) {
+        try {
+            this.stream = new PrintStream(stream, false, "US-ASCII");
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Flushes any buffered output.
+     */
+    protected void flush() {
+        stream.flush();
+    }
+
+    /**
+     * Starts a new graph document.
+     */
+    protected void begin() {
+        stream.println("<graphDocument>");
+    }
+
+    protected void beginGroup() {
+        stream.println("<group>");
+    }
+
+    protected void beginMethod(String name, String shortName, int bci) {
+        stream.printf(" <method name='%s' shortName='%s' bci='%d'>%n", escape(name), escape(shortName), bci);
+    }
+
+    protected void beginBytecodes() {
+        stream.println("  <bytecodes>\n<![CDATA[");
+    }
+
+    protected void printBytecode(int bci, String mnemonic, int[] extra) {
+        stream.print(bci);
+        stream.print(' ');
+        stream.print(mnemonic);
+        if (extra != null) {
+            for (int b : extra) {
+                stream.print(' ');
+                stream.print(b);
+            }
+        }
+        stream.println();
+    }
+
+    protected void endBytecodes() {
+        stream.println("  ]]></bytecodes>");
+    }
+
+    protected void endMethod() {
+        stream.println(" </method>");
+    }
+
+    protected void beginGraph(String title) {
+        stream.printf(" <graph name='%s'>%n", escape(title));
+    }
+
+    protected void beginProperties() {
+        stream.print("<properties>");
+    }
+
+    protected void printProperty(String name, String value) {
+        stream.printf("<p name='%s'>%s</p>", escape(name), escape(value));
+    }
+
+    protected void endProperties() {
+        stream.print("</properties>");
+    }
+
+    protected void printProperties(Map<String, String> properties) {
+        beginProperties();
+        for (Entry<String, String> entry : properties.entrySet()) {
+            printProperty(entry.getKey(), entry.getValue());
+        }
+        endProperties();
+    }
+
+    protected void beginNodes() {
+        stream.println("  <nodes>");
+    }
+
+    protected void beginNode(String id) {
+        stream.printf("   <node id='%s'>", escape(id));
+    }
+
+    protected void endNode() {
+        stream.println("   </node>");
+    }
+
+    protected void printNode(String id, Map<String, String> properties) {
+        beginNode(id);
+        if (properties != null) {
+            printProperties(properties);
+        }
+        endNode();
+    }
+
+    protected void endNodes() {
+        stream.println("  </nodes>");
+    }
+
+    protected void beginEdges() {
+        stream.println("  <edges>");
+    }
+
+    protected void printEdge(Edge edge) {
+        stream.printf("   <edge from='%s' fromIndex='%d' to='%s' toIndex='%d' label='%s' />%n", escape(edge.from), edge.fromIndex, escape(edge.to), edge.toIndex, escape(edge.label));
+    }
+
+    protected void endEdges() {
+        stream.println("  </edges>");
+    }
+
+    protected void beginControlFlow() {
+        stream.println("  <controlFlow>");
+    }
+
+    protected void beginBlock(String name) {
+        stream.printf("   <block name='%s'>%n", escape(name));
+    }
+
+    protected void beginSuccessors() {
+        stream.println("    <successors>");
+    }
+
+    protected void printSuccessor(String name) {
+        stream.printf("     <successor name='%s'/>%n", escape(name));
+    }
+
+    protected void endSuccessors() {
+        stream.println("    </successors>");
+    }
+
+    protected void beginBlockNodes() {
+        stream.println("    <nodes>");
+    }
+
+    protected void printBlockNode(String nodeId) {
+        stream.printf("     <node id='%s'/>%n", escape(nodeId));
+    }
+
+    protected void endBlockNodes() {
+        stream.println("    </nodes>");
+    }
+
+    protected void endBlock() {
+        stream.println("   </block>");
+    }
+
+    protected void endControlFlow() {
+        stream.println("  </controlFlow>");
+    }
+
+    protected void endGraph() {
+        stream.println(" </graph>");
+    }
+
+    /**
+     * Ends the current group.
+     */
+    protected void endGroup() {
+        stream.println("</group>");
+    }
+
+    /**
+     * Finishes the graph document and flushes the output stream.
+     */
+    protected void end() {
+        stream.println("</graphDocument>");
+        flush();
+    }
+
+
+    public boolean isValid() {
+        return !stream.checkError();
+    }
+
+
+    private static String escape(String s) {
+        StringBuilder str = null;
+        for (int i = 0; i < s.length(); i++) {
+            char c = s.charAt(i);
+            switch (c) {
+                case '&':
+                case '<':
+                case '>':
+                case '"':
+                case '\'':
+                    if (str == null) {
+                        str = new StringBuilder();
+                        str.append(s, 0, i);
+                    }
+                    switch(c) {
+                        case '&':
+                            str.append("&amp;");
+                            break;
+                        case '<':
+                            str.append("&lt;");
+                            break;
+                        case '>':
+                            str.append("&gt;");
+                            break;
+                        case '"':
+                            str.append("&quot;");
+                            break;
+                        case '\'':
+                            str.append("&apos;");
+                            break;
+                        default:
+                            assert false;
+                    }
+                    break;
+                default:
+                    if (str != null) {
+                        str.append(c);
+                    }
+                    break;
+            }
+        }
+        if (str == null) {
+            return s;
+        } else {
+            return str.toString();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,480 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.printer;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.io.*;
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.alloc.util.*;
+import com.oracle.max.graal.compiler.alloc.*;
+import com.oracle.max.graal.compiler.alloc.Interval.UsePosList;
+import com.oracle.max.graal.compiler.gen.*;
+import com.oracle.max.graal.compiler.schedule.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.graph.Node.Verbosity;
+import com.oracle.max.graal.graph.NodeClass.NodeClassIterator;
+import com.oracle.max.graal.graph.NodeClass.Position;
+import com.oracle.max.graal.java.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.cfg.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.calc.*;
+
+/**
+ * Utility for printing Graal IR at various compilation phases.
+ */
+class CFGPrinter extends CompilationPrinter {
+
+    public final CiTarget target;
+    public final RiRuntime runtime;
+    public LIR lir;
+    public LIRGenerator lirGenerator;
+
+    /**
+     * Creates a control flow graph printer.
+     *
+     * @param buffer where the output generated via this printer shown be written
+     */
+    public CFGPrinter(OutputStream out, CiTarget target, RiRuntime runtime) {
+        super(out);
+        this.target = target;
+        this.runtime = runtime;
+    }
+
+    /**
+     * Prints the control flow graph denoted by a given block map.
+     *
+     * @param label A label describing the compilation phase that produced the control flow graph.
+     * @param blockMap A data structure describing the blocks in a method and how they are connected.
+     */
+    public void printCFG(String label, BciBlockMapping blockMap) {
+        begin("cfg");
+        out.print("name \"").print(label).println('"');
+        for (BciBlockMapping.Block block : blockMap.blocks) {
+            begin("block");
+            printBlock(block);
+            end("block");
+        }
+        end("cfg");
+    }
+
+    private void printBlock(BciBlockMapping.Block block) {
+        out.print("name \"B").print(block.startBci).println('"');
+        out.print("from_bci ").println(block.startBci);
+        out.print("to_bci ").println(block.endBci);
+
+        out.println("predecessors ");
+
+        out.print("successors ");
+        for (BciBlockMapping.Block succ : block.successors) {
+            if (!succ.isExceptionEntry) {
+                out.print("\"B").print(succ.startBci).print("\" ");
+            }
+        }
+        out.println();
+
+        out.print("xhandlers");
+        for (BciBlockMapping.Block succ : block.successors) {
+            if (succ.isExceptionEntry) {
+                out.print("\"B").print(succ.startBci).print("\" ");
+            }
+        }
+        out.println();
+
+        out.print("flags ");
+        if (block.isExceptionEntry) {
+            out.print("\"ex\" ");
+        }
+        if (block.isLoopHeader) {
+            out.print("\"plh\" ");
+        }
+        out.println();
+
+        out.print("loop_depth ").println(Long.bitCount(block.loops));
+    }
+
+
+    /**
+     * Prints the specified list of blocks.
+     *
+     * @param label A label describing the compilation phase that produced the control flow graph.
+     * @param blocks The list of blocks to be printed.
+     */
+    public void printCFG(String label, List<Block> blocks, SchedulePhase schedule) {
+        begin("cfg");
+        out.print("name \"").print(label).println('"');
+        for (Block block : blocks) {
+            printBlock(block, schedule);
+        }
+        end("cfg");
+    }
+
+    private void printBlock(Block block, SchedulePhase schedule) {
+        begin("block");
+
+        out.print("name \"").print(blockToString(block)).println('"');
+        out.println("from_bci -1");
+        out.println("to_bci -1");
+
+        out.print("predecessors ");
+        for (Block pred : block.getPredecessors()) {
+            out.print("\"").print(blockToString(pred)).print("\" ");
+        }
+        out.println();
+
+        out.print("successors ");
+        for (Block succ : block.getSuccessors()) {
+            if (!succ.isExceptionEntry()) {
+                out.print("\"").print(blockToString(succ)).print("\" ");
+            }
+        }
+        out.println();
+
+        out.print("xhandlers");
+        for (Block succ : block.getSuccessors()) {
+            if (succ.isExceptionEntry()) {
+                out.print("\"").print(blockToString(succ)).print("\" ");
+            }
+        }
+        out.println();
+
+        out.print("flags ");
+        if (block.isLoopHeader()) {
+            out.print("\"llh\" ");
+        }
+        if (block.isLoopEnd()) {
+            out.print("\"lle\" ");
+        }
+        if (block.isExceptionEntry()) {
+            out.print("\"ex\" ");
+        }
+        out.println();
+
+        if (block.getLoop() != null) {
+            out.print("loop_index ").println(block.getLoop().index);
+            out.print("loop_depth ").println(block.getLoop().depth);
+        }
+
+        printNodes(block, schedule);
+        printLIR(block);
+        end("block");
+    }
+
+    private void printNodes(Block block, SchedulePhase schedule) {
+        if (schedule == null) {
+            return;
+        }
+        begin("IR");
+        out.println("HIR");
+        out.disableIndentation();
+
+        if (block.getPredecessors().size() == 0) {
+            // Currently method parameters are not in the schedule, so print them separately here.
+            for (ValueNode param : block.getBeginNode().graph().getNodes(LocalNode.class)) {
+                printNode(param);
+            }
+        }
+        if (block.getBeginNode() instanceof MergeNode) {
+            // Currently phi functions are not in the schedule, so print them separately here.
+            for (ValueNode phi : ((MergeNode) block.getBeginNode()).phis()) {
+                printNode(phi);
+            }
+        }
+
+        for (Node node : schedule.nodesFor(block)) {
+            printNode(node);
+        }
+        out.enableIndentation();
+        end("IR");
+    }
+
+    private void printNode(Node node) {
+        if (node instanceof FixedWithNextNode) {
+            out.print("f ").print(HOVER_START).print("#").print(HOVER_SEP).print("fixed with next").print(HOVER_END).println(COLUMN_END);
+        } else if (node instanceof FixedNode) {
+            out.print("f ").print(HOVER_START).print("*").print(HOVER_SEP).print("fixed").print(HOVER_END).println(COLUMN_END);
+        } else if (node instanceof FloatingNode) {
+            out.print("f ").print(HOVER_START).print("~").print(HOVER_SEP).print("floating").print(HOVER_END).println(COLUMN_END);
+        }
+        out.print("tid ").print(nodeToString(node)).println(COLUMN_END);
+
+        if (lirGenerator != null) {
+            CiValue operand = lirGenerator.nodeOperands.get(node);
+            if (operand != null) {
+                out.print("result ").print(operand.toString()).println(COLUMN_END);
+            }
+        }
+
+        if (node instanceof StateSplit) {
+            StateSplit stateSplit = (StateSplit) node;
+            if (stateSplit.stateAfter() != null) {
+                String state = stateToString(stateSplit.stateAfter());
+                out.print("st ").print(HOVER_START).print("st").print(HOVER_SEP).print(state).print(HOVER_END).println(COLUMN_END);
+            }
+        }
+
+        Map<Object, Object> props = new TreeMap<>(node.getDebugProperties());
+        out.print("d ").print(HOVER_START).print("d").print(HOVER_SEP);
+        out.println("=== Debug Properties ===");
+        for (Map.Entry<Object, Object> entry : props.entrySet()) {
+            out.print(entry.getKey().toString()).print(": ").print(entry.getValue() == null ? "[null]" : entry.getValue().toString()).println();
+        }
+        out.println("=== Inputs ===");
+        printNamedNodes(node, node.inputs().iterator(), "", "\n", null);
+        out.println("=== Succesors ===");
+        printNamedNodes(node, node.successors().iterator(), "", "\n", null);
+        out.println("=== Usages ===");
+        if (!node.usages().isEmpty()) {
+            for (Node usage : node.usages()) {
+                out.print(nodeToString(usage)).print(" ");
+            }
+            out.println();
+        }
+        out.println("=== Predecessor ===");
+        out.print(nodeToString(node.predecessor())).print(" ");
+        out.print(HOVER_END).println(COLUMN_END);
+
+        out.print("instruction ");
+        out.print(HOVER_START).print(node.getNodeClass().shortName()).print(HOVER_SEP).print(node.getClass().getName()).print(HOVER_END).print(" ");
+        printNamedNodes(node, node.inputs().iterator(), "", "", "#NDF");
+        printNamedNodes(node, node.successors().iterator(), "#", "", "#NDF");
+        for (Map.Entry<Object, Object> entry : props.entrySet()) {
+            String key = entry.getKey().toString();
+            if (key.startsWith("data.") && !key.equals("data.stamp")) {
+                out.print(key.substring("data.".length())).print(": ").print(entry.getValue() == null ? "[null]" : entry.getValue().toString()).print(" ");
+            }
+        }
+        out.print(COLUMN_END).print(' ').println(COLUMN_END);
+    }
+
+    private void printNamedNodes(Node node, NodeClassIterator iter, String prefix, String suffix, String hideSuffix) {
+        int lastIndex = -1;
+        while (iter.hasNext()) {
+            Position pos = iter.nextPosition();
+            if (hideSuffix != null && node.getNodeClass().getName(pos).endsWith(hideSuffix)) {
+                continue;
+            }
+
+            if (pos.index != lastIndex) {
+                if (lastIndex != -1) {
+                    out.print(suffix);
+                }
+                out.print(prefix).print(node.getNodeClass().getName(pos)).print(": ");
+                lastIndex = pos.index;
+            }
+            out.print(nodeToString(node.getNodeClass().get(node, pos))).print(" ");
+        }
+        if (lastIndex != -1) {
+            out.print(suffix);
+        }
+    }
+
+    private String stateToString(FrameState state) {
+        StringBuilder buf = new StringBuilder();
+        FrameState curState = state;
+        do {
+            buf.append(CiUtil.toLocation(curState.method(), curState.bci)).append('\n');
+
+            if (curState.stackSize() > 0) {
+                buf.append("stack: ");
+                for (int i = 0; i < curState.stackSize(); i++) {
+                    buf.append(stateValueToString(curState.stackAt(i))).append(' ');
+                }
+                buf.append("\n");
+            }
+
+            buf.append("locals: ");
+            for (int i = 0; i < curState.localsSize(); i++) {
+                buf.append(stateValueToString(curState.localAt(i))).append(' ');
+            }
+            buf.append("\n");
+
+            curState = curState.outerFrameState();
+        } while (curState != null);
+
+        return buf.toString();
+    }
+
+    private String stateValueToString(ValueNode value) {
+        String result = nodeToString(value);
+        if (lirGenerator != null && lirGenerator.nodeOperands != null && value != null) {
+            CiValue operand = lirGenerator.nodeOperands.get(value);
+            if (operand != null) {
+                result += ": " + operand;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Prints the LIR for each instruction in a given block.
+     *
+     * @param block the block to print
+     */
+    private void printLIR(Block block) {
+        List<LIRInstruction> lirInstructions = block.lir;
+        if (lirInstructions == null) {
+            return;
+        }
+
+        begin("IR");
+        out.println("LIR");
+
+        for (int i = 0; i < lirInstructions.size(); i++) {
+            LIRInstruction inst = lirInstructions.get(i);
+            out.printf("nr %4d ", inst.id()).print(COLUMN_END);
+
+            if (inst.info != null) {
+                int level = out.indentationLevel();
+                out.adjustIndentation(-level);
+                String state;
+                if (inst.info.hasDebugInfo()) {
+                    state = debugInfoToString(inst.info.debugInfo().codePos, inst.info.debugInfo().registerRefMap, inst.info.debugInfo().frameRefMap, target.arch);
+                } else {
+                    state = debugInfoToString(inst.info.topFrame, null, null, target.arch);
+                }
+                if (state != null) {
+                    out.print(" st ").print(HOVER_START).print("st").print(HOVER_SEP).print(state).print(HOVER_END).print(COLUMN_END);
+                }
+                out.adjustIndentation(level);
+            }
+
+            out.print(" instruction ").print(inst.toString()).print(COLUMN_END);
+            out.println(COLUMN_END);
+        }
+        end("IR");
+    }
+
+    private String nodeToString(Node node) {
+        if (node == null) {
+            return "-";
+        }
+        String prefix;
+        if (node instanceof BeginNode && lir == null) {
+            prefix = "B";
+        } else if (node instanceof ValueNode) {
+            ValueNode value = (ValueNode) node;
+            if (value.kind() == CiKind.Illegal) {
+                prefix = "v";
+            } else {
+                prefix = String.valueOf(value.kind().typeChar);
+            }
+        } else {
+            prefix = "?";
+        }
+        return prefix + node.toString(Verbosity.Id);
+    }
+
+    private String blockToString(Block block) {
+        if (lir == null) {
+            // During all the front-end phases, the block schedule is built only for the debug output.
+            // Therefore, the block numbers would be different for every CFG printed -> use the id of the first instruction.
+            return "B" + block.getBeginNode().toString(Verbosity.Id);
+        } else {
+            // LIR instructions contain references to blocks and these blocks are printed as the blockID -> use the blockID.
+            return "B" + block.getId();
+        }
+    }
+
+
+    public void printIntervals(String label, Interval[] intervals) {
+        begin("intervals");
+        out.println(String.format("name \"%s\"", label));
+
+        for (Interval interval : intervals) {
+            if (interval != null) {
+                printInterval(interval);
+            }
+        }
+
+        end("intervals");
+    }
+
+    private void printInterval(Interval interval) {
+        out.printf("%s %s ", interval.operand, (isRegister(interval.operand) ? "fixed" : interval.kind().name()));
+        if (isRegister(interval.operand)) {
+            out.printf("\"[%s|%c]\"", interval.operand, interval.operand.kind.typeChar);
+        } else {
+            if (interval.location() != null) {
+                out.printf("\"[%s|%c]\"", interval.location(), interval.location().kind.typeChar);
+            }
+        }
+
+        Interval hint = interval.locationHint(false);
+        out.printf("%s %s ", interval.splitParent().operand, hint != null ? hint.operand : -1);
+
+        // print ranges
+        Range cur = interval.first();
+        while (cur != Range.EndMarker) {
+            out.printf("[%d, %d[", cur.from, cur.to);
+            cur = cur.next;
+            assert cur != null : "range list not closed with range sentinel";
+        }
+
+        // print use positions
+        int prev = 0;
+        UsePosList usePosList = interval.usePosList();
+        for (int i = usePosList.size() - 1; i >= 0; --i) {
+            assert prev < usePosList.usePos(i) : "use positions not sorted";
+            out.printf("%d %s ", usePosList.usePos(i), usePosList.registerPriority(i));
+            prev = usePosList.usePos(i);
+        }
+
+        out.printf(" \"%s\"", interval.spillState());
+        out.println();
+    }
+
+    public void printIntervals(String label, IntervalPrinter.Interval[] intervals) {
+        begin("intervals");
+        out.println(String.format("name \"%s\"", label));
+
+        for (IntervalPrinter.Interval interval : intervals) {
+            printInterval(interval);
+        }
+
+        end("intervals");
+    }
+
+    private void printInterval(IntervalPrinter.Interval interval) {
+        out.printf("%s %s \"%s\" %s %s ", interval.name, interval.type, interval.description, interval.variable, "no");
+        if (interval.ranges.size() == 0) {
+            // One range is required in the spec, so output a dummy range.
+            out.printf("[0, 0[ ");
+        } else {
+            for (IntervalPrinter.Range range : interval.ranges) {
+                out.printf("[%d, %d[ ", range.from, range.to);
+            }
+        }
+        for (IntervalPrinter.UsePosition usePos : interval.uses) {
+            out.printf("%d %s ", usePos.pos, usePos.kind);
+        }
+        out.printf("\"%s\"", "no");
+        out.println();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,133 @@
+/*
+ * 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.max.graal.printer;
+
+import java.io.*;
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.alloc.util.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.alloc.*;
+import com.oracle.max.graal.compiler.gen.*;
+import com.oracle.max.graal.compiler.schedule.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.java.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.nodes.*;
+
+/**
+ * Observes compilation events and uses {@link CFGPrinter} to produce a control flow graph for the <a
+ * href="http://java.net/projects/c1visualizer/">C1 Visualizer</a>.
+ */
+public class CFGPrinterObserver implements DebugDumpHandler {
+
+    private CFGPrinter cfgPrinter;
+
+    private GraalCompiler compiler;
+    private RiResolvedMethod method;
+    private SchedulePhase schedule;
+
+    @Override
+    public void dump(final Object object, final String message) {
+        Debug.sandbox("CFGPrinter", new Runnable() {
+            @Override
+            public void run() {
+                dumpSandboxed(object, message);
+            }
+        });
+    }
+
+    private void dumpSandboxed(final Object object, final String message) {
+        if (object instanceof GraalCompiler) {
+            compiler = (GraalCompiler) object;
+            return;
+        } else if (object instanceof SchedulePhase) {
+            schedule = (SchedulePhase) object;
+            return;
+        }
+
+        if (compiler == null) {
+            return;
+        }
+
+        if (cfgPrinter == null) {
+            File file = new File("compilations-" + System.currentTimeMillis() + ".cfg");
+            try {
+                OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
+                cfgPrinter = new CFGPrinter(out, compiler.target, compiler.runtime);
+            } catch (FileNotFoundException e) {
+                throw new InternalError("Could not open " + file.getAbsolutePath());
+            }
+            TTY.println("CFGPrinter: Output to file %s", file);
+        }
+
+        RiRuntime runtime = cfgPrinter.runtime;
+        if (object instanceof LIRGenerator) {
+            cfgPrinter.lirGenerator = (LIRGenerator) object;
+        } else if (object instanceof RiResolvedMethod) {
+            method = (RiResolvedMethod) object;
+            cfgPrinter.printCompilation(method);
+
+            cfgPrinter.lir = null;
+            cfgPrinter.lirGenerator = null;
+            schedule = null;
+            TTY.println("CFGPrinter: Dumping method %s", method);
+
+        } else if (object instanceof BciBlockMapping) {
+            BciBlockMapping blockMap = (BciBlockMapping) object;
+            cfgPrinter.printCFG(message, blockMap);
+            cfgPrinter.printBytecodes(runtime.disassemble(blockMap.method));
+
+        } else if (object instanceof LIR) {
+            cfgPrinter.lir = (LIR) object;
+            cfgPrinter.printCFG(message, ((LIR) object).codeEmittingOrder(), schedule);
+
+        } else if (object instanceof StructuredGraph) {
+            SchedulePhase curSchedule = schedule;
+            if (curSchedule == null) {
+                try {
+                    curSchedule = new SchedulePhase();
+                    curSchedule.apply((StructuredGraph) object);
+                } catch (Throwable ex) {
+                    curSchedule = null;
+                    // ignore
+                }
+            }
+            if (curSchedule != null && curSchedule.getCFG() != null) {
+                cfgPrinter.printCFG(message, Arrays.asList(curSchedule.getCFG().getBlocks()), curSchedule);
+            }
+
+        } else if (object instanceof CiTargetMethod) {
+            cfgPrinter.printMachineCode(runtime.disassemble((CiTargetMethod) object), null);
+        } else if (object instanceof Interval[]) {
+            cfgPrinter.printIntervals(message, (Interval[]) object);
+        } else if (object instanceof IntervalPrinter.Interval[]) {
+            cfgPrinter.printIntervals(message, (IntervalPrinter.Interval[]) object);
+        }
+
+        cfgPrinter.flush();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,278 @@
+/*
+ * 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.max.graal.printer;
+
+import java.io.*;
+import java.util.*;
+import java.util.Map.Entry;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.compiler.schedule.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.graph.Node.Verbosity;
+import com.oracle.max.graal.graph.NodeClass.NodeClassIterator;
+import com.oracle.max.graal.graph.NodeClass.Position;
+import com.oracle.max.graal.java.*;
+import com.oracle.max.graal.lir.cfg.*;
+import com.oracle.max.graal.nodes.*;
+
+/**
+ * Generates a representation of {@link Graph Graphs} that can be visualized and inspected with the <a
+ * href="http://kenai.com/projects/igv">Ideal Graph Visualizer</a>.
+ */
+class IdealGraphPrinter extends BasicIdealGraphPrinter {
+    /**
+     * Creates a new {@link IdealGraphPrinter} that writes to the specified output stream.
+     */
+    public IdealGraphPrinter(OutputStream stream) {
+        super(stream);
+    }
+
+    /**
+     * Starts a new group of graphs with the given name, short name and method byte code index (BCI) as properties.
+     */
+    public void beginGroup(String name, String shortName, RiResolvedMethod method, int bci) {
+        beginGroup();
+        beginProperties();
+        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();
+        }
+        endMethod();
+    }
+
+    public void print(Graph graph, String title) {
+        print(graph, title, null);
+    }
+
+    /**
+     * Prints an entire {@link Graph} with the specified title, optionally using short names for nodes.
+     */
+    public void print(Graph graph, String title, SchedulePhase predefinedSchedule) {
+        beginGraph(title);
+        Set<Node> noBlockNodes = new HashSet<>();
+        SchedulePhase schedule = predefinedSchedule;
+        if (schedule == null) {
+            try {
+                schedule = new SchedulePhase();
+                schedule.apply((StructuredGraph) graph);
+            } catch (Throwable t) {
+                schedule = null;
+            }
+        }
+
+        beginNodes();
+        List<Edge> edges = printNodes(graph, schedule == null ? null : schedule.getCFG().getNodeToBlock(), noBlockNodes);
+        endNodes();
+
+        beginEdges();
+        for (Edge edge : edges) {
+            printEdge(edge);
+        }
+        endEdges();
+
+        if (schedule != null) {
+            beginControlFlow();
+            for (Block block : schedule.getCFG().getBlocks()) {
+                printBlock(graph, block, schedule.getCFG().getNodeToBlock());
+            }
+            printNoBlock(noBlockNodes);
+            endControlFlow();
+        }
+
+        endGraph();
+        flush();
+    }
+
+    private List<Edge> printNodes(Graph graph, NodeMap<Block> nodeToBlock, Set<Node> noBlockNodes) {
+        ArrayList<Edge> edges = new ArrayList<>();
+
+        NodeMap<Set<Entry<String, Integer>>> colors = graph.createNodeMap();
+        NodeMap<Set<Entry<String, String>>> colorsToString = graph.createNodeMap();
+        NodeMap<Set<String>> bits = graph.createNodeMap();
+
+        for (Node node : graph.getNodes()) {
+
+            beginNode(node.toString(Verbosity.Id));
+            beginProperties();
+            printProperty("idx", node.toString(Verbosity.Id));
+
+            Map<Object, Object> props = node.getDebugProperties();
+            if (!props.containsKey("name") || props.get("name").toString().trim().length() == 0) {
+                String name = node.toString(Verbosity.Name);
+                printProperty("name", name);
+            }
+            printProperty("class", node.getClass().getSimpleName());
+            Block block = nodeToBlock == null ? null : nodeToBlock.get(node);
+            if (block != null) {
+                printProperty("block", Integer.toString(block.getId()));
+//                if (!(node instanceof PhiNode || node instanceof FrameState || node instanceof LocalNode) && !block.nodes().contains(node)) {
+//                    printProperty("notInOwnBlock", "true");
+//                }
+            } else {
+                printProperty("block", "noBlock");
+                noBlockNodes.add(node);
+            }
+
+            Set<Entry<String, Integer>> nodeColors = colors.get(node);
+            if (nodeColors != null) {
+                for (Entry<String, Integer> color : nodeColors) {
+                    String name = color.getKey();
+                    Integer value = color.getValue();
+                    printProperty(name, Integer.toString(value));
+                }
+            }
+            Set<Entry<String, String>> nodeColorStrings = colorsToString.get(node);
+            if (nodeColorStrings != null) {
+                for (Entry<String, String> color : nodeColorStrings) {
+                    String name = color.getKey();
+                    String value = color.getValue();
+                    printProperty(name, value);
+                }
+            }
+            Set<String> nodeBits = bits.get(node);
+            if (nodeBits != null) {
+                for (String bit : nodeBits) {
+                    printProperty(bit, "true");
+                }
+            }
+
+            for (Entry<Object, Object> entry : props.entrySet()) {
+                String key = entry.getKey().toString();
+                String value = entry.getValue() == null ? "null" : entry.getValue().toString();
+                printProperty(key, value);
+            }
+
+            endProperties();
+            endNode();
+
+            // successors
+            int fromIndex = 0;
+            NodeClassIterator succIter = node.successors().iterator();
+            while (succIter.hasNext()) {
+                Position position = succIter.nextPosition();
+                Node successor = node.getNodeClass().get(node, position);
+                if (successor != null) {
+                    edges.add(new Edge(node.toString(Verbosity.Id), fromIndex, successor.toString(Verbosity.Id), 0, node.getNodeClass().getName(position)));
+                }
+                fromIndex++;
+            }
+
+            // inputs
+            int toIndex = 1;
+            NodeClassIterator inputIter = node.inputs().iterator();
+            while (inputIter.hasNext()) {
+                Position position = inputIter.nextPosition();
+                Node input = node.getNodeClass().get(node, position);
+                if (input != null) {
+                    edges.add(new Edge(input.toString(Verbosity.Id), input.successors().count(), node.toString(Verbosity.Id), toIndex, node.getNodeClass().getName(position)));
+                }
+                toIndex++;
+            }
+        }
+
+        return edges;
+    }
+
+    private void printBlock(Graph graph, Block block, NodeMap<Block> nodeToBlock) {
+        beginBlock(Integer.toString(block.getId()));
+        beginSuccessors();
+        for (Block sux : block.getSuccessors()) {
+            if (sux != null) {
+                printSuccessor(Integer.toString(sux.getId()));
+            }
+        }
+        endSuccessors();
+        beginBlockNodes();
+
+        Set<Node> nodes = new HashSet<>();
+
+        if (nodeToBlock != null) {
+            for (Node n : graph.getNodes()) {
+                Block blk = nodeToBlock.get(n);
+                if (blk == block) {
+                    nodes.add(n);
+                }
+            }
+        }
+
+        if (nodes.size() > 0) {
+            // if this is the first block: add all locals to this block
+            if (block.getBeginNode() == ((StructuredGraph) graph).start()) {
+                for (Node node : graph.getNodes()) {
+                    if (node instanceof LocalNode) {
+                        nodes.add(node);
+                    }
+                }
+            }
+
+            Set<Node> snapshot = new HashSet<>(nodes);
+            // add all framestates and phis to their blocks
+            for (Node node : snapshot) {
+                if (node instanceof StateSplit && ((StateSplit) node).stateAfter() != null) {
+                    nodes.add(((StateSplit) node).stateAfter());
+                }
+                if (node instanceof MergeNode) {
+                    for (PhiNode phi : ((MergeNode) node).phis()) {
+                        nodes.add(phi);
+                    }
+                }
+            }
+
+            for (Node node : nodes) {
+                printBlockNode(node.toString(Verbosity.Id));
+            }
+        }
+        endBlockNodes();
+        endBlock();
+    }
+
+    private void printNoBlock(Set<Node> noBlockNodes) {
+        if (!noBlockNodes.isEmpty()) {
+            beginBlock("noBlock");
+            beginBlockNodes();
+            for (Node node : noBlockNodes) {
+                printBlockNode(node.toString(Verbosity.Id));
+            }
+            endBlockNodes();
+            endBlock();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinterDumpHandler.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,170 @@
+/*
+ * 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.max.graal.printer;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.criutils.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+
+/**
+ * Observes compilation events and uses {@link IdealGraphPrinter} to generate a graph representation that can be
+ * inspected with the <a href="http://kenai.com/projects/igv">Ideal Graph Visualizer</a>.
+ */
+public class IdealGraphPrinterDumpHandler implements DebugDumpHandler {
+
+    private static final String DEFAULT_FILE_NAME = "output.igv.xml";
+
+    private IdealGraphPrinter printer;
+    private List<String> previousInlineContext = new ArrayList<>();
+    private String fileName;
+    private String host;
+    private int port;
+    private boolean initialized;
+
+    /**
+     * Creates a new {@link IdealGraphPrinterDumpHandler} that writes output to a file named after the compiled method.
+     */
+    public IdealGraphPrinterDumpHandler() {
+        this.fileName = DEFAULT_FILE_NAME;
+    }
+
+    /**
+     * Creates a new {@link IdealGraphPrinterDumpHandler} that sends output to a remote IdealGraphVisualizer instance.
+     */
+    public IdealGraphPrinterDumpHandler(String host, int port) {
+        this.host = host;
+        this.port = port;
+    }
+
+    private void ensureInitialized() {
+        if (!initialized) {
+            initialized = true;
+            if (fileName != null) {
+                initializeFilePrinter();
+            } else {
+                initializeNetworkPrinter();
+            }
+        }
+    }
+
+    private void initializeFilePrinter() {
+        try {
+            FileOutputStream stream = new FileOutputStream(fileName);
+            printer = new IdealGraphPrinter(stream);
+            printer.begin();
+        } catch (IOException e) {
+            printer = null;
+        }
+    }
+
+    private void initializeNetworkPrinter() {
+        try {
+            Socket socket = new Socket(host, port);
+            BufferedOutputStream stream = new BufferedOutputStream(socket.getOutputStream(), 0x4000);
+            printer = new IdealGraphPrinter(stream);
+            printer.begin();
+            TTY.println("Connected to the IGV on port %d", port);
+        } catch (IOException e) {
+            TTY.println("Could not connect to the IGV on port %d: %s", port, e);
+            printer = null;
+        }
+    }
+
+    @Override
+    public void dump(Object object, final String message) {
+        if (object instanceof Graph) {
+            ensureInitialized();
+            final Graph graph = (Graph) object;
+
+            if (printer != null && printer.isValid()) {
+                // Get all current RiResolvedMethod instances in the context.
+                List<String> inlineContext = getInlineContext();
+                Debug.contextSnapshot(RiResolvedMethod.class);
+
+                // Reverse list such that inner method comes after outer method.
+                Collections.reverse(inlineContext);
+
+                // Check for method scopes that must be closed since the previous dump.
+                for (int i = 0; i < previousInlineContext.size(); ++i) {
+                    if (i >= inlineContext.size() || !inlineContext.get(i).equals(previousInlineContext.get(i))) {
+                        for (int j = previousInlineContext.size() - 1; j >= i; --j) {
+                            closeScope();
+                        }
+                        break;
+                    }
+                }
+
+                // Check for method scopes that must be opened since the previous dump.
+                for (int i = 0; i < inlineContext.size(); ++i) {
+                    if (i >= previousInlineContext.size() || !inlineContext.get(i).equals(previousInlineContext.get(i))) {
+                        for (int j = i; j < inlineContext.size(); ++j) {
+                            openScope(inlineContext.get(j));
+                        }
+                        break;
+                    }
+                }
+
+                // Save inline context for next dump.
+                previousInlineContext = inlineContext;
+
+                Debug.sandbox("PrintingGraph", new Runnable() {
+
+                    @Override
+                    public void run() {
+                        // Finally, output the graph.
+                        printer.print(graph, message);
+
+                    }
+                });
+            }
+        }
+    }
+
+    private static List<String> getInlineContext() {
+        List<String> result = new ArrayList<>();
+        for (Object o : Debug.context()) {
+            if (o instanceof RiResolvedMethod) {
+                RiResolvedMethod method = (RiResolvedMethod) o;
+                result.add(CiUtil.format("%H::%n(%p)", method));
+            } else if (o instanceof DebugDumpScope) {
+                DebugDumpScope debugDumpScope = (DebugDumpScope) o;
+                result.add(debugDumpScope.getName());
+            }
+        }
+        return result;
+    }
+
+    private void openScope(String name) {
+        printer.beginGroup(name, name, Debug.contextLookup(RiResolvedMethod.class), -1);
+    }
+
+    private void closeScope() {
+        printer.endGroup();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/ClassSubstitution.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,35 @@
+/*
+ * 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.max.graal.snippets;
+
+import java.lang.annotation.*;
+
+/**
+ * Denotes a class that substitutes methods of another specified class with snippets.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface ClassSubstitution {
+
+    Class<?> value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/DoubleSnippets.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * 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.max.graal.snippets;
+
+import com.oracle.max.cri.util.*;
+import com.oracle.max.graal.nodes.calc.*;
+
+/**
+ * Snippets for {@link java.lang.Double} methods.
+ */
+@ClassSubstitution(java.lang.Double.class)
+public class DoubleSnippets implements SnippetsInterface {
+
+    private static final long NAN_RAW_LONG_BITS = Double.doubleToRawLongBits(Double.NaN);
+
+    public static long doubleToRawLongBits(double value) {
+        @JavacBug(id = 6995200)
+        Long result = ConvertNode.convert(ConvertNode.Op.MOV_D2L, value);
+        return result;
+    }
+
+    // TODO This method is not necessary, since the JDK method does exactly this
+    public static long doubleToLongBits(double value) {
+        if (value != value) {
+            return NAN_RAW_LONG_BITS;
+        } else {
+            @JavacBug(id = 6995200)
+            Long result = ConvertNode.convert(ConvertNode.Op.MOV_D2L, value);
+            return result;
+        }
+    }
+
+    public static double longBitsToDouble(long bits) {
+        @JavacBug(id = 6995200)
+        Double result = ConvertNode.convert(ConvertNode.Op.MOV_L2D, bits);
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/FloatSnippets.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * 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.max.graal.snippets;
+
+import com.oracle.max.cri.util.*;
+import com.oracle.max.graal.nodes.calc.*;
+
+/**
+ * Snippets for {@link java.lang.Float} methods.
+ */
+@ClassSubstitution(java.lang.Float.class)
+public class FloatSnippets implements SnippetsInterface {
+
+    private static final int NAN_RAW_INT_BITS = Float.floatToRawIntBits(Float.NaN);
+
+    public static int floatToRawIntBits(float value) {
+        @JavacBug(id = 6995200)
+        Integer result = ConvertNode.convert(ConvertNode.Op.MOV_F2I, value);
+        return result;
+    }
+
+    // TODO This method is not necessary, since the JDK method does exactly this
+    public static int floatToIntBits(float value) {
+        if (value != value) {
+            return NAN_RAW_INT_BITS;
+        } else {
+            @JavacBug(id = 6995200)
+            Integer result = ConvertNode.convert(ConvertNode.Op.MOV_F2I, value);
+            return result;
+        }
+    }
+
+    public static float intBitsToFloat(int bits) {
+        @JavacBug(id = 6995200)
+        Float result = ConvertNode.convert(ConvertNode.Op.MOV_I2F, bits);
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/GraalIntrinsics.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.snippets;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.cri.*;
+
+/**
+ * Definition of the snippets that are VM-independent and can be intrinsified by Graal in any VM.
+ */
+public class GraalIntrinsics {
+    public static void installIntrinsics(GraalRuntime runtime, CiTarget target, PhasePlan plan) {
+        if (GraalOptions.Intrinsify) {
+            Snippets.install(runtime, target, new MathSnippetsX86(), plan);
+            Snippets.install(runtime, target, new DoubleSnippets(), plan);
+            Snippets.install(runtime, target, new FloatSnippets(), plan);
+            Snippets.install(runtime, target, new NodeClassSnippets(), plan);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/MathSnippetsX86.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * 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.max.graal.snippets;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.snippets.nodes.*;
+import com.oracle.max.graal.snippets.nodes.MathIntrinsicNode.Operation;
+
+/**
+ * Snippets for {@link java.lang.Math} methods.
+ */
+@ClassSubstitution(java.lang.Math.class)
+public class MathSnippetsX86 implements SnippetsInterface {
+
+    private static final double PI_4 = 0.7853981633974483;
+
+    public static double abs(double x) {
+        return MathIntrinsicNode.compute(x, Operation.ABS);
+    }
+
+    public static double sqrt(double x) {
+        return MathIntrinsicNode.compute(x, Operation.SQRT);
+    }
+
+    public static double log(double x) {
+        return MathIntrinsicNode.compute(x, Operation.LOG);
+    }
+
+    public static double log10(double x) {
+        return MathIntrinsicNode.compute(x, Operation.LOG10);
+    }
+
+    // NOTE on snippets below:
+    //   Math.sin(), .cos() and .tan() guarantee a value within 1 ULP of the
+    //   exact result, but x87 trigonometric FPU instructions are only that
+    //   accurate within [-pi/4, pi/4]. Examine the passed value and provide
+    //   a slow path for inputs outside of that interval.
+
+    public static double sin(double x) {
+        if (abs(x) < PI_4) {
+            return MathIntrinsicNode.compute(x, Operation.SIN);
+        } else {
+            return RuntimeCallNode.performCall(CiRuntimeCall.ArithmeticSin, x);
+        }
+    }
+
+    public static double cos(double x) {
+        if (abs(x) < PI_4) {
+            return MathIntrinsicNode.compute(x, Operation.COS);
+        } else {
+            return RuntimeCallNode.performCall(CiRuntimeCall.ArithmeticCos, x);
+        }
+    }
+
+    public static double tan(double x) {
+        if (abs(x) < PI_4) {
+            return MathIntrinsicNode.compute(x, Operation.TAN);
+        } else {
+            return RuntimeCallNode.performCall(CiRuntimeCall.ArithmeticTan, x);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/NodeClassSnippets.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * 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.max.graal.snippets;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.extended.*;
+
+/**
+ * Snippets for {@link NodeClass} methods.
+ */
+@SuppressWarnings("unused")
+@ClassSubstitution(NodeClass.class)
+public class NodeClassSnippets implements SnippetsInterface {
+
+
+    private static Node getNode(Node node, long offset) {
+        return UnsafeCastNode.cast(UnsafeLoadNode.load(node, offset, CiKind.Object), Node.class);
+    }
+
+    private static NodeList<Node> getNodeList(Node node, long offset) {
+        return UnsafeCastNode.cast(UnsafeLoadNode.load(node, offset, CiKind.Object), NodeList.class);
+    }
+
+    private static void putNode(Node node, long offset, Node value) {
+        UnsafeStoreNode.store(node, offset, value, CiKind.Object);
+    }
+
+    private static void putNodeList(Node node, long offset, NodeList value) {
+        UnsafeStoreNode.store(node, offset, value, CiKind.Object);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/Snippet.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,31 @@
+/*
+ * 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.max.graal.snippets;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Snippet {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/Snippets.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,144 @@
+/*
+ * 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.max.graal.snippets;
+
+import java.lang.reflect.*;
+import java.util.concurrent.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.java.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.java.*;
+
+/**
+ * Utilities for snippet installation and management.
+ */
+public class Snippets {
+
+    public static void install(GraalRuntime runtime, CiTarget target, SnippetsInterface obj, PhasePlan plan) {
+        Class<? extends SnippetsInterface> clazz = obj.getClass();
+        BoxingMethodPool pool = new BoxingMethodPool(runtime);
+        if (clazz.isAnnotationPresent(ClassSubstitution.class)) {
+            installSubstitution(runtime, target, plan, clazz, pool, clazz.getAnnotation(ClassSubstitution.class).value());
+        } else {
+            installSnippets(runtime, target, plan, clazz, pool);
+        }
+    }
+
+    private static void installSnippets(GraalRuntime runtime, CiTarget target, PhasePlan plan, Class< ? extends SnippetsInterface> clazz,
+                    BoxingMethodPool pool) {
+        for (Method snippet : clazz.getDeclaredMethods()) {
+            int modifiers = snippet.getModifiers();
+            if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
+                throw new RuntimeException("Snippet must not be abstract or native");
+            }
+            RiResolvedMethod snippetRiMethod = runtime.getRiMethod(snippet);
+            if (snippetRiMethod.compilerStorage().get(Graph.class) == null) {
+                buildSnippetGraph(snippetRiMethod, runtime, target, pool, plan);
+            }
+        }
+    }
+
+    private static void installSubstitution(GraalRuntime runtime, CiTarget target, PhasePlan plan, Class< ? extends SnippetsInterface> clazz,
+                    BoxingMethodPool pool, Class<?> original) throws GraalInternalError {
+        for (Method snippet : clazz.getDeclaredMethods()) {
+            try {
+                Method method = original.getDeclaredMethod(snippet.getName(), snippet.getParameterTypes());
+                if (!method.getReturnType().isAssignableFrom(snippet.getReturnType())) {
+                    throw new RuntimeException("Snippet has incompatible return type");
+                }
+                int modifiers = snippet.getModifiers();
+                if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
+                    throw new RuntimeException("Snippet must not be abstract or native");
+                }
+                RiResolvedMethod snippetRiMethod = runtime.getRiMethod(snippet);
+                StructuredGraph graph = buildSnippetGraph(snippetRiMethod, runtime, target, pool, plan);
+                runtime.getRiMethod(method).compilerStorage().put(Graph.class, graph);
+            } catch (NoSuchMethodException e) {
+                throw new RuntimeException("Could not resolve method to substitute with: " + snippet.getName(), e);
+            }
+        }
+    }
+
+    private static StructuredGraph buildSnippetGraph(final RiResolvedMethod snippetRiMethod, final GraalRuntime runtime, final CiTarget target, final BoxingMethodPool pool, final PhasePlan plan) {
+        return Debug.scope("BuildSnippetGraph", snippetRiMethod, new Callable<StructuredGraph>() {
+
+            @Override
+            public StructuredGraph call() throws Exception {
+                GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault();
+                GraphBuilderPhase graphBuilder = new GraphBuilderPhase(runtime, config);
+                StructuredGraph graph = new StructuredGraph(snippetRiMethod);
+                graphBuilder.apply(graph);
+
+                Debug.dump(graph, "%s: %s", snippetRiMethod.name(), GraphBuilderPhase.class.getSimpleName());
+
+                new SnippetIntrinsificationPhase(runtime, pool).apply(graph);
+
+                for (Invoke invoke : graph.getInvokes()) {
+                    MethodCallTargetNode callTarget = invoke.callTarget();
+                    RiResolvedMethod targetMethod = callTarget.targetMethod();
+                    RiResolvedType holder = targetMethod.holder();
+                    if (holder.isSubtypeOf(runtime.getType(SnippetsInterface.class))) {
+                        StructuredGraph targetGraph = (StructuredGraph) targetMethod.compilerStorage().get(Graph.class);
+                        if (targetGraph == null) {
+                            targetGraph = buildSnippetGraph(targetMethod, runtime, target, pool, plan);
+                        }
+                        InliningUtil.inline(invoke, targetGraph, true);
+                        if (GraalOptions.OptCanonicalizer) {
+                            new CanonicalizerPhase(target, runtime, null).apply(graph);
+                        }
+                    }
+                }
+
+                new SnippetIntrinsificationPhase(runtime, pool).apply(graph);
+
+                Debug.dump(graph, "%s: %s", snippetRiMethod.name(), GraphBuilderPhase.class.getSimpleName());
+                new DeadCodeEliminationPhase().apply(graph);
+                if (GraalOptions.OptCanonicalizer) {
+                    new CanonicalizerPhase(target, runtime, null).apply(graph);
+                }
+
+                // TODO (gd) remove when we have safepoint polling elimination
+                for (LoopEndNode end : graph.getNodes(LoopEndNode.class)) {
+                    end.setSafepointPolling(false);
+                }
+                new InsertStateAfterPlaceholderPhase().apply(graph);
+
+                Debug.dump(graph, "%s: Final", snippetRiMethod.name());
+
+                snippetRiMethod.compilerStorage().put(Graph.class, graph);
+
+                return graph;
+            }
+        });
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/SnippetsInterface.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,30 @@
+/*
+ * 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.max.graal.snippets;
+
+/**
+ * Tagging interface for interfaces or classes providing snippets.
+ */
+public interface SnippetsInterface {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/nodes/ArrayHeaderSizeNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * 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.max.graal.snippets.nodes;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+
+public class ArrayHeaderSizeNode extends FloatingNode implements Lowerable {
+    @Data private final CiKind elementKind;
+
+    public ArrayHeaderSizeNode(CiKind elementKind) {
+        super(StampFactory.forKind(CiKind.Long));
+        this.elementKind = elementKind;
+    }
+
+    @Override
+    public void lower(CiLoweringTool tool) {
+        tool.getRuntime().lower(this, tool);
+    }
+
+    public CiKind elementKind() {
+        return elementKind;
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static long sizeFor(@ConstantNodeParameter CiKind kind) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/nodes/MathIntrinsicNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,101 @@
+/*
+ * 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.max.graal.snippets.nodes;
+
+import static com.oracle.max.graal.lir.amd64.AMD64Arithmetic.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.compiler.target.amd64.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.amd64.AMD64Arithmetic.Op2Reg;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.calc.*;
+import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.type.*;
+import com.oracle.max.graal.snippets.target.amd64.*;
+
+public class MathIntrinsicNode extends FloatingNode implements Canonicalizable, AMD64LIRLowerable {
+
+    @Input private ValueNode x;
+    @Data private final Operation operation;
+
+    public enum Operation {
+        ABS, SQRT, LOG, LOG10, SIN, COS, TAN,
+    }
+
+    public ValueNode x() {
+        return x;
+    }
+
+    public Operation operation() {
+        return operation;
+    }
+
+    public MathIntrinsicNode(ValueNode x, Operation op) {
+        super(StampFactory.forKind(x.kind()));
+        assert x.kind() == CiKind.Double;
+        this.x = x;
+        this.operation = op;
+    }
+
+    @Override
+    public void generateAmd64(AMD64LIRGenerator gen) {
+        Variable input = gen.load(gen.operand(x()));
+        Variable result = gen.newVariable(kind());
+        switch (operation()) {
+            case ABS:   gen.append(new Op2Reg(DAND, result, input, CiConstant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL)))); break;
+            case SQRT:  gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.Opcode.SQRT, result, input)); break;
+            case LOG:   gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.Opcode.LOG, result, input)); break;
+            case LOG10: gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.Opcode.LOG10, result, input)); break;
+            case SIN:   gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.Opcode.SIN, result, input)); break;
+            case COS:   gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.Opcode.COS, result, input)); break;
+            case TAN:   gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.Opcode.TAN, result, input)); break;
+            default:    throw GraalInternalError.shouldNotReachHere();
+        }
+        gen.setResult(this, result);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x().isConstant()) {
+            double value = x().asConstant().asDouble();
+            switch (operation()) {
+                case ABS:   return ConstantNode.forDouble(Math.abs(value), graph());
+                case SQRT:  return ConstantNode.forDouble(Math.sqrt(value), graph());
+                case LOG:   return ConstantNode.forDouble(Math.log(value), graph());
+                case LOG10: return ConstantNode.forDouble(Math.log10(value), graph());
+                case SIN:   return ConstantNode.forDouble(Math.sin(value), graph());
+                case COS:   return ConstantNode.forDouble(Math.cos(value), graph());
+                case TAN:   return ConstantNode.forDouble(Math.tan(value), graph());
+            }
+        }
+        return this;
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static double compute(double x, @ConstantNodeParameter Operation op) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/target/amd64/AMD64MathIntrinsicOp.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2011, 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.max.graal.snippets.target.amd64;
+
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.amd64.*;
+import com.oracle.max.graal.lir.asm.*;
+
+public class AMD64MathIntrinsicOp extends AMD64LIRInstruction {
+    public enum Opcode  {
+        SQRT,
+        SIN, COS, TAN,
+        LOG, LOG10;
+    }
+
+    public AMD64MathIntrinsicOp(Opcode opcode, CiValue result, CiValue input) {
+        super(opcode, new CiValue[] {result}, null, new CiValue[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        Opcode opcode = (Opcode) code;
+        CiValue result = output(0);
+        CiValue input = input(0);
+
+        switch (opcode) {
+            case SQRT:  masm.sqrtsd(asDoubleReg(result), asDoubleReg(input)); break;
+            case LOG:   masm.flog(asDoubleReg(result), asDoubleReg(input), false); break;
+            case LOG10: masm.flog(asDoubleReg(result), asDoubleReg(input), true); break;
+            case SIN:   masm.fsin(asDoubleReg(result), asDoubleReg(input)); break;
+            case COS:   masm.fcos(asDoubleReg(result), asDoubleReg(input)); break;
+            case TAN:   masm.ftan(asDoubleReg(result), asDoubleReg(input)); break;
+            default:    throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+        if (mode == OperandMode.Input && index == 0) {
+            return EnumSet.of(OperandFlag.Register);
+        } else if (mode == OperandMode.Output && index == 0) {
+            return EnumSet.of(OperandFlag.Register);
+        }
+        throw GraalInternalError.shouldNotReachHere();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.snippets/test/test/com/oracle/max/graal/snippets/package-info.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+/**
+ * Test cases for Graal snippets.
+ */
+package test.com.oracle.max.graal.snippets;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/BoxingEliminationTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,139 @@
+/*
+ * 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.max.graal.compiler.tests;
+
+import static com.oracle.max.graal.graph.iterators.NodePredicates.*;
+
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.compiler.phases.PhasePlan.PhasePosition;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.extended.*;
+
+/**
+ * In the following tests, the usages of local variable "a" are replaced with the integer constant 0.
+ * Then boxing elimination is applied and it is verified that the resulting graph is equal to the
+ * graph of the method that just has a "return 1" statement in it.
+ */
+public class BoxingEliminationTest extends GraphTest {
+    private static final Short s = 2;
+    private static final String REFERENCE_SNIPPET = "referenceSnippet";
+
+    @SuppressWarnings("all")
+    public static short referenceSnippet(short a) {
+        return 1;
+    }
+
+    public static Short boxedShort() {
+        return 1;
+    }
+
+    public static Object boxedObject() {
+        return (short) 1;
+    }
+
+    public static Short constantBoxedShort() {
+        return s;
+    }
+
+    @Test
+    public void test1() {
+        test("test1Snippet");
+    }
+
+    @SuppressWarnings("all")
+    public static short test1Snippet(short a) {
+        return boxedShort();
+    }
+
+    @Test
+    public void test2() {
+        test("test2Snippet");
+    }
+
+    @SuppressWarnings("all")
+    public static short test2Snippet(short a) {
+        return (Short) boxedObject();
+    }
+    @Test
+    public void test3() {
+        test("test3Snippet");
+    }
+
+    @SuppressWarnings("all")
+    public static short test3Snippet(short a) {
+        short b = boxedShort();
+        if (b < 0) {
+            b = boxedShort();
+        }
+        return b;
+    }
+
+    @Test
+    public void test4() {
+        test("test4Snippet");
+    }
+
+    @SuppressWarnings("all")
+    public static short test4Snippet(short a) {
+        return constantBoxedShort();
+    }
+
+    private void test(final String snippet) {
+        Debug.scope("BoxingEliminationTest", new DebugDumpScope(snippet), new Runnable() {
+            @Override
+            public void run() {
+                StructuredGraph graph = parse(snippet);
+                BoxingMethodPool pool = new BoxingMethodPool(runtime());
+                IdentifyBoxingPhase identifyBoxingPhase = new IdentifyBoxingPhase(pool);
+                PhasePlan phasePlan = getDefaultPhasePlan();
+                phasePlan.addPhase(PhasePosition.AFTER_PARSING, identifyBoxingPhase);
+                identifyBoxingPhase.apply(graph);
+                LocalNode local = graph.getNodes(LocalNode.class).iterator().next();
+                ConstantNode constant = ConstantNode.forShort((short) 0, graph);
+                for (Node n : local.usages().filter(isNotA(FrameState.class)).snapshot()) {
+                    n.replaceFirstInput(local, constant);
+                }
+                Collection<Invoke> hints = new ArrayList<>();
+                for (Invoke invoke : graph.getInvokes()) {
+                    hints.add(invoke);
+                }
+                new InliningPhase(null, runtime(), hints, null, phasePlan).apply(graph);
+                new CanonicalizerPhase(null, runtime(), null).apply(graph);
+                Debug.dump(graph, "Graph");
+                new BoxingEliminationPhase().apply(graph);
+                Debug.dump(graph, "Graph");
+                new ExpandBoxingNodesPhase(pool).apply(graph);
+                new CanonicalizerPhase(null, runtime(), null).apply(graph);
+                new DeadCodeEliminationPhase().apply(graph);
+                StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET);
+                assertEquals(referenceGraph, graph);
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/ConditionTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2012, 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.max.graal.compiler.tests;
+
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.nodes.calc.*;
+
+
+public class ConditionTest {
+
+    @Test
+    public void testImplies() {
+        Random rand = new Random(13);
+        for (Condition c1 : Condition.values()) {
+            for (Condition c2 : Condition.values()) {
+                boolean implies = c1.implies(c2);
+                if (implies && c1 != Condition.OF && c2 != Condition.OF && c1 != Condition.NOF && c2 != Condition.NOF) {
+                    for (int i = 0; i < 10000; i++) {
+                        CiConstant a = CiConstant.forInt(rand.nextInt());
+                        CiConstant b = CiConstant.forInt(i < 100 ? a.asInt() : rand.nextInt());
+                        boolean result1 = c1.foldCondition(a, b, null, false);
+                        boolean result2 = c2.foldCondition(a, b, null, false);
+                        if (result1 && implies) {
+                            assertTrue(result2);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testJoin() {
+        Random rand = new Random(13);
+        for (Condition c1 : Condition.values()) {
+            for (Condition c2 : Condition.values()) {
+                Condition join = c1.join(c2);
+                assertTrue(join == c2.join(c1));
+                if (join != null && c1 != Condition.OF && c2 != Condition.OF && c1 != Condition.NOF && c2 != Condition.NOF) {
+                    for (int i = 0; i < 10000; i++) {
+                        CiConstant a = CiConstant.forInt(rand.nextInt());
+                        CiConstant b = CiConstant.forInt(i < 100 ? a.asInt() : rand.nextInt());
+                        boolean result1 = c1.foldCondition(a, b, null, false);
+                        boolean result2 = c2.foldCondition(a, b, null, false);
+                        boolean resultJoin = join.foldCondition(a, b, null, false);
+                        if (result1 && result2) {
+                            assertTrue(resultJoin);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testMeet() {
+        Random rand = new Random(13);
+        for (Condition c1 : Condition.values()) {
+            for (Condition c2 : Condition.values()) {
+                Condition meet = c1.meet(c2);
+                assertTrue(meet == c2.meet(c1));
+                if (meet != null && c1 != Condition.OF && c2 != Condition.OF && c1 != Condition.NOF && c2 != Condition.NOF) {
+                    for (int i = 0; i < 10000; i++) {
+                        CiConstant a = CiConstant.forInt(rand.nextInt());
+                        CiConstant b = CiConstant.forInt(i < 100 ? a.asInt() : rand.nextInt());
+                        boolean result1 = c1.foldCondition(a, b, null, false);
+                        boolean result2 = c2.foldCondition(a, b, null, false);
+                        boolean resultMeet = meet.foldCondition(a, b, null, false);
+                        if (result1 || result2) {
+                            assertTrue(resultMeet);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/DegeneratedLoopsTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,94 @@
+/*
+ * 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.max.graal.compiler.tests;
+
+import static com.oracle.max.graal.graph.iterators.NodePredicates.*;
+
+import org.junit.*;
+
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+
+/**
+ * In the following tests, the usages of local variable "a" are replaced with the integer constant 0.
+ * Then canonicalization is applied and it is verified that the resulting graph is equal to the
+ * graph of the method that just has a "return 1" statement in it.
+ */
+public class DegeneratedLoopsTest extends GraphTest {
+
+    private static final String REFERENCE_SNIPPET = "referenceSnippet";
+
+    @SuppressWarnings("all")
+    public static int referenceSnippet(int a) {
+        return 1;
+    }
+
+    @Test
+    public void test1() {
+        test("test1Snippet");
+    }
+
+    private static class UnresolvedException extends RuntimeException {
+        private static final long serialVersionUID = 5215434338750728440L;
+
+        static {
+            if (true) {
+                throw new UnsupportedOperationException("this class may never be initialized");
+            }
+        }
+    }
+
+    @SuppressWarnings("all")
+    public static int test1Snippet(int a) {
+        for (;;) {
+            try {
+                test();
+                break;
+            } catch (UnresolvedException e) {
+            }
+        }
+        return a;
+    }
+
+    private static void test() {
+
+    }
+
+    private void test(String snippet) {
+        StructuredGraph graph = parse(snippet);
+        Debug.dump(graph, "Graph");
+        LocalNode local = graph.getNodes(LocalNode.class).iterator().next();
+        ConstantNode constant = ConstantNode.forInt(0, graph);
+        for (Node n : local.usages().filter(isNotA(FrameState.class)).snapshot()) {
+            n.replaceFirstInput(local, constant);
+        }
+        for (Invoke invoke : graph.getInvokes()) {
+            invoke.intrinsify(null);
+        }
+        new CanonicalizerPhase(null, runtime(), null).apply(graph);
+        StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); Debug.dump(referenceGraph, "Graph");
+        assertEquals(referenceGraph, graph);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/EscapeAnalysisTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,145 @@
+/*
+ * 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.max.graal.compiler.tests;
+
+import junit.framework.*;
+
+import org.junit.Test;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.java.*;
+
+/**
+ * In these test cases the probability of all invokes is set to a high value, such that an InliningPhase should inline them all.
+ * After that, the EscapeAnalysisPhase is expected to remove all allocations and return the correct values.
+ */
+public class EscapeAnalysisTest extends GraphTest {
+
+    @Test
+    public void test1() {
+        test("test1Snippet", CiConstant.forInt(101));
+    }
+
+    @SuppressWarnings("all")
+    public static int test1Snippet(int a) {
+        Integer x = new Integer(101);
+        return x.intValue();
+    }
+
+    @Test
+    public void test2() {
+        test("test2Snippet", CiConstant.forInt(0));
+    }
+
+    @SuppressWarnings("all")
+    public static int test2Snippet(int a) {
+        Integer[] x = new Integer[0];
+        return x.length;
+    }
+
+    @Test
+    public void test3() {
+        test("test3Snippet", CiConstant.forObject(null));
+    }
+
+    @SuppressWarnings("all")
+    public static Object test3Snippet(int a) {
+        Integer[] x = new Integer[1];
+        return x[0];
+    }
+
+    @Test
+    public void testMonitor() {
+        test("testMonitorSnippet", CiConstant.forInt(0));
+    }
+
+    private static native void notInlineable();
+
+    @SuppressWarnings("all")
+    public static int testMonitorSnippet(int a) {
+        Integer x = new Integer(0);
+        Integer[] y = new Integer[0];
+        Integer[] z = new Integer[1];
+        synchronized (x) {
+            synchronized (y) {
+                synchronized (z) {
+                    notInlineable();
+                }
+            }
+        }
+        return x.intValue();
+    }
+
+    public void testMonitor2() {
+        test("testMonitor2Snippet", CiConstant.forInt(0));
+    }
+
+    /**
+     * This test case differs from the last one in that it requires inlining within a synchronized region.
+     */
+    @SuppressWarnings("all")
+    public static int testMonitor2Snippet(int a) {
+        Integer x = new Integer(0);
+        Integer[] y = new Integer[0];
+        Integer[] z = new Integer[1];
+        synchronized (x) {
+            synchronized (y) {
+                synchronized (z) {
+                    notInlineable();
+                    return x.intValue();
+                }
+            }
+        }
+    }
+
+    private void test(String snippet, CiConstant expectedResult) {
+        StructuredGraph graph = parse(snippet);
+        for (Invoke n : graph.getInvokes()) {
+            n.node().setProbability(100000);
+        }
+
+        new InliningPhase(null, runtime(), null, null, getDefaultPhasePlan()).apply(graph);
+        new DeadCodeEliminationPhase().apply(graph);
+        Debug.dump(graph, "Graph");
+        new EscapeAnalysisPhase(null, runtime(), null, getDefaultPhasePlan()).apply(graph);
+        Debug.dump(graph, "Graph");
+        int retCount = 0;
+        for (ReturnNode ret : graph.getNodes(ReturnNode.class)) {
+            Assert.assertTrue(ret.result().isConstant());
+            Assert.assertEquals(ret.result().asConstant(), expectedResult);
+            retCount++;
+        }
+        Assert.assertEquals(1, retCount);
+        int newInstanceCount = 0;
+        for (@SuppressWarnings("unused") NewInstanceNode n : graph.getNodes(NewInstanceNode.class)) {
+            newInstanceCount++;
+        }
+        for (@SuppressWarnings("unused") NewObjectArrayNode n : graph.getNodes(NewObjectArrayNode.class)) {
+            newInstanceCount++;
+        }
+        Assert.assertEquals(0, newInstanceCount);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/FloatingReadTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,77 @@
+/*
+ * 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.max.graal.compiler.tests;
+
+import org.junit.*;
+
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.extended.*;
+import com.oracle.max.graal.nodes.java.*;
+
+public class FloatingReadTest extends GraphScheduleTest {
+
+    public static class Container {
+        public int a;
+    }
+
+    public static void changeField(Container c) {
+        c.a = 0xcafebabe;
+    }
+
+    public static synchronized int test1Snippet() {
+        Container c = new Container();
+        return c.a;
+    }
+
+    @Test
+    public void test1() {
+        test("test1Snippet");
+    }
+
+    private void test(String snippet) {
+        StructuredGraph graph = parse(snippet);
+        new LoweringPhase(runtime()).apply(graph);
+        new FloatingReadPhase().apply(graph);
+
+        ReturnNode returnNode = null;
+        MonitorExitNode monitor = null;
+
+        for (Node n : graph.getNodes()) {
+            if (n instanceof ReturnNode) {
+                returnNode = (ReturnNode) n;
+            } else if (n instanceof MonitorExitNode) {
+                monitor = (MonitorExitNode) n;
+            }
+        }
+
+        Assert.assertNotNull(returnNode);
+        Assert.assertNotNull(monitor);
+        Assert.assertTrue(returnNode.result() instanceof FloatingReadNode);
+
+        FloatingReadNode read = (FloatingReadNode) returnNode.result();
+
+        assertOrderedAfterSchedule(graph, read, monitor);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraalRuntimeAccess.java	Mon Feb 27 13:10:13 2012 +0100
@@ -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.max.graal.compiler.tests;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.max.graal.cri.*;
+
+/**
+ * Utility for getting a {@link GraalRuntime} instance from the current execution environment.
+ */
+class GraalRuntimeAccess {
+
+    /**
+     * The known classes declaring a {@code getGraalRuntime()} method. These class names
+     * have aliases that can be used with the {@code "graal.runtime"} system property to
+     * specify the VM environment to try first when getting a Graal runtime instance.
+     */
+    private static Map<String, String> graalRuntimeFactoryClasses = new LinkedHashMap<>();
+    static {
+        graalRuntimeFactoryClasses.put("HotSpot", "com.oracle.max.graal.hotspot.CompilerImpl");
+        graalRuntimeFactoryClasses.put("Maxine", "com.oracle.max.vm.ext.maxri.MaxRuntime");
+    }
+
+    /**
+     * Gets a Graal runtime instance from the current execution environment.
+     */
+    static GraalRuntime getGraalRuntime() {
+        String vm = System.getProperty("graal.runtime");
+        if (vm != null) {
+            String cn = graalRuntimeFactoryClasses.get(vm);
+            if (cn != null) {
+                GraalRuntime graal = getGraalRuntime(cn);
+                if (graal != null) {
+                    return graal;
+                }
+            }
+        }
+
+        for (String className : graalRuntimeFactoryClasses.values()) {
+            GraalRuntime graal = getGraalRuntime(className);
+            if (graal != null) {
+                return graal;
+            }
+        }
+        throw new InternalError("Could not create a GraalRuntime instance");
+    }
+
+    /**
+     * Calls {@code getGraalRuntime()} via reflection on a given class.
+     *
+     * @return {@code null} if there was an error invoking the methodor if the method return {@code null} itself
+     */
+    private static GraalRuntime getGraalRuntime(String className) {
+        try {
+            Class<?> c = Class.forName(className);
+            Method m = c.getDeclaredMethod("getGraalRuntime");
+            return (GraalRuntime) m.invoke(null);
+        } catch (Exception e) {
+            //e.printStackTrace();
+            System.err.println(e);
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphScheduleTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * 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.max.graal.compiler.tests;
+
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.max.graal.compiler.schedule.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.cfg.*;
+import com.oracle.max.graal.nodes.*;
+
+public class GraphScheduleTest extends GraphTest {
+    protected void assertOrderedAfterSchedule(StructuredGraph graph, Node a, Node b) {
+        SchedulePhase ibp = new SchedulePhase();
+        ibp.apply(graph);
+        NodeMap<Block> nodeToBlock = ibp.getCFG().getNodeToBlock();
+        Block bBlock = nodeToBlock.get(b);
+        Block aBlock = nodeToBlock.get(a);
+
+        if (bBlock == aBlock) {
+            List<Node> instructions = ibp.nodesFor(bBlock);
+            Assert.assertTrue(instructions.indexOf(b) > instructions.indexOf(a));
+        } else {
+            Block block = bBlock;
+            while (block != null) {
+                if (block == aBlock) {
+                    break;
+                }
+                block = block.getDominator();
+            }
+            Assert.assertTrue(block == aBlock);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,138 @@
+/*
+ * 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.max.graal.compiler.tests;
+
+import java.lang.reflect.*;
+
+import junit.framework.Assert;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.compiler.phases.PhasePlan.*;
+import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.java.*;
+import com.oracle.max.graal.nodes.*;
+
+/**
+ * Base class for Graal compiler unit tests. These are white box tests
+ * for Graal compiler transformations. The general pattern for a test is:
+ * <ol>
+ * <li>Create a graph by {@linkplain #parse(String) parsing} a method.</li>
+ * <li>Manually modify the graph (e.g. replace a paramter node with a constant).</li>
+ * <li>Apply a transformation to the graph.</li>
+ * <li>Assert that the transformed graph is equal to an expected graph.</li>
+ * </ol>
+ * <p>
+ * See {@link InvokeTest} as an example.
+ * <p>
+ * The tests can be run in Eclipse with the "Compiler Unit Test" Eclipse
+ * launch configuration found in the top level of this project or by
+ * running {@code mx unittest} on the command line.
+ */
+public abstract class GraphTest {
+
+    protected final GraalRuntime runtime;
+
+    public GraphTest() {
+        this.runtime = GraalRuntimeAccess.getGraalRuntime();
+    }
+
+    protected void assertEquals(StructuredGraph expected, StructuredGraph graph) {
+        if (expected.getNodeCount() != graph.getNodeCount()) {
+            Debug.dump(expected, "Node count not matching - expected");
+            Debug.dump(graph, "Node count not matching - actual");
+            Assert.fail("Graphs do not have the same number of nodes");
+        }
+    }
+
+    protected GraalRuntime runtime() {
+        return runtime;
+    }
+
+    /**
+     * Parses a Java method to produce a graph.
+     *
+     * @param methodName the name of the method in {@code this.getClass()} to be parsed
+     */
+    protected StructuredGraph parse(String methodName) {
+        Method found = null;
+        for (Method m : this.getClass().getMethods()) {
+            if (m.getName().equals(methodName)) {
+                Assert.assertNull(found);
+                found = m;
+            }
+        }
+        if (found != null) {
+            return parse(found);
+        } else {
+            throw new RuntimeException("method not found: " + methodName);
+        }
+    }
+
+    /**
+     * Parses a Java method to produce a graph.
+     *
+     * @param methodName the name of the method in {@code this.getClass()} to be parsed
+     */
+    protected StructuredGraph parseProfiled(String methodName) {
+        Method found = null;
+        for (Method m : this.getClass().getMethods()) {
+            if (m.getName().equals(methodName)) {
+                Assert.assertNull(found);
+                found = m;
+            }
+        }
+        if (found != null) {
+            return parseProfiled(found);
+        } else {
+            throw new RuntimeException("method not found: " + methodName);
+        }
+    }
+
+    /**
+     * Parses a Java method to produce a graph.
+     */
+    protected StructuredGraph parse(Method m) {
+        RiResolvedMethod riMethod = runtime.getRiMethod(m);
+        StructuredGraph graph = new StructuredGraph(riMethod);
+        new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault()).apply(graph);
+        return graph;
+    }
+
+    /**
+     * Parses a Java method to produce a graph.
+     */
+    protected StructuredGraph parseProfiled(Method m) {
+        RiResolvedMethod riMethod = runtime.getRiMethod(m);
+        StructuredGraph graph = new StructuredGraph(riMethod);
+        new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault()).apply(graph);
+        return graph;
+    }
+
+    protected PhasePlan getDefaultPhasePlan() {
+        PhasePlan plan = new PhasePlan();
+        plan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault()));
+        return plan;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/IfBoxingEliminationTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,99 @@
+/*
+ * 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.max.graal.compiler.tests;
+
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.compiler.phases.PhasePlan.PhasePosition;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.extended.*;
+
+public class IfBoxingEliminationTest extends GraphTest {
+
+    private static final String REFERENCE_SNIPPET = "referenceSnippet";
+
+    public static int referenceSnippet(int a) {
+        int result;
+        if (a < 0) {
+            result = 1;
+        } else {
+            result = 2;
+        }
+        return result;
+    }
+
+    public static Integer boxedInteger() {
+        return 1;
+    }
+
+    public static Object boxedObject() {
+        return 2;
+    }
+
+    @Test
+    public void test1() {
+        test("test1Snippet");
+    }
+
+    public static int test1Snippet(int a) {
+        Integer result;
+        if (a < 0) {
+            result = boxedInteger();
+        } else {
+            result = (Integer) boxedObject();
+        }
+        return result;
+    }
+
+    private void test(String snippet) {
+        StructuredGraph graph = parse(snippet);
+        BoxingMethodPool pool = new BoxingMethodPool(runtime());
+        IdentifyBoxingPhase identifyBoxingPhase = new IdentifyBoxingPhase(pool);
+        PhasePlan phasePlan = getDefaultPhasePlan();
+        phasePlan.addPhase(PhasePosition.AFTER_PARSING, identifyBoxingPhase);
+        phasePlan.addPhase(PhasePosition.AFTER_PARSING, new PhiStampPhase());
+        identifyBoxingPhase.apply(graph);
+        Collection<Invoke> hints = new ArrayList<>();
+        for (Invoke invoke : graph.getInvokes()) {
+            hints.add(invoke);
+        }
+        new InliningPhase(null, runtime(), hints, null, phasePlan).apply(graph);
+        new CanonicalizerPhase(null, runtime(), null).apply(graph);
+        new PhiStampPhase().apply(graph);
+        new CanonicalizerPhase(null, runtime(), null).apply(graph);
+        Debug.dump(graph, "Graph");
+        new BoxingEliminationPhase().apply(graph);
+        Debug.dump(graph, "Graph");
+        new ExpandBoxingNodesPhase(pool).apply(graph);
+        new CanonicalizerPhase(null, runtime(), null).apply(graph);
+        new DeadCodeEliminationPhase().apply(graph);
+        StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET);
+        new CanonicalizerPhase(null, runtime(), null).apply(referenceGraph);
+        new DeadCodeEliminationPhase().apply(referenceGraph);
+        assertEquals(referenceGraph, graph);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/IfCanonicalizerTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,150 @@
+/*
+ * 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.max.graal.compiler.tests;
+
+import static com.oracle.max.graal.graph.iterators.NodePredicates.*;
+
+import org.junit.*;
+
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+
+/**
+ * In the following tests, the usages of local variable "a" are replaced with the integer constant 0.
+ * Then canonicalization is applied and it is verified that the resulting graph is equal to the
+ * graph of the method that just has a "return 1" statement in it.
+ */
+public class IfCanonicalizerTest extends GraphTest {
+
+    private static final String REFERENCE_SNIPPET = "referenceSnippet";
+
+    @SuppressWarnings("all")
+    public static int referenceSnippet(int a) {
+        return 1;
+    }
+
+    @Test
+    public void test1() {
+        test("test1Snippet");
+    }
+
+    @SuppressWarnings("all")
+    public static int test1Snippet(int a) {
+        if (a == 0) {
+            return 1;
+        } else {
+            return 2;
+        }
+    }
+
+    @Test
+    public void test2() {
+        test("test2Snippet");
+    }
+
+    @SuppressWarnings("all")
+    public static int test2Snippet(int a) {
+        if (a == 0) {
+            if (a == 0) {
+                if (a == 0) {
+                    return 1;
+                }
+            }
+        } else {
+            return 2;
+        }
+        return 3;
+    }
+
+    @Test
+    public void test3() {
+        test("test3Snippet");
+    }
+
+    @SuppressWarnings("all")
+    public static int test3Snippet(int a) {
+        if (a == 0) {
+            if (a != 1) {
+                if (a == 1) {
+                    return 3;
+                } else {
+                    if (a >= 0) {
+                        if (a <= 0) {
+                            if (a > -1) {
+                                if (a < 1) {
+                                    return 1;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        } else {
+            return 2;
+        }
+        return 3;
+    }
+
+    @Test
+    public void test4() {
+        test("test4Snippet");
+    }
+
+    public static int test4Snippet(int a) {
+        if (a == 0) {
+            return 1;
+        }
+        return 1;
+    }
+
+    @Test
+    public void test5() {
+        test("test5Snippet");
+    }
+
+    public static int test5Snippet(int a) {
+        int val = 2;
+        if (a == 0) {
+            val = 1;
+        }
+        if (a * (3 + val) == 0) {
+            return 1;
+        }
+        return 1;
+    }
+
+    private void test(String snippet) {
+        StructuredGraph graph = parse(snippet);
+        LocalNode local = graph.getNodes(LocalNode.class).iterator().next();
+        ConstantNode constant = ConstantNode.forInt(0, graph);
+        for (Node n : local.usages().filter(isNotA(FrameState.class)).snapshot()) {
+            n.replaceFirstInput(local, constant);
+        }
+        Debug.dump(graph, "Graph");
+        new CanonicalizerPhase(null, runtime(), null).apply(graph);
+        StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET);
+        assertEquals(referenceGraph, graph);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/InvokeExceptionTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,69 @@
+/*
+ * 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.max.graal.compiler.tests;
+
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.nodes.*;
+
+public class InvokeExceptionTest extends GraphTest {
+
+    public static synchronized void throwException(int i) {
+        if (i == 1) {
+            throw new RuntimeException();
+        }
+    }
+
+    @Test
+    public void test1() {
+        // fill the profiling data...
+        for (int i = 0; i < 10000; i++) {
+            try {
+                throwException(i & 1);
+                test1Snippet(0);
+            } catch (Throwable t) {
+                // nothing to do...
+            }
+        }
+        test("test1Snippet");
+    }
+
+    @SuppressWarnings("all")
+    public static void test1Snippet(int a) {
+        throwException(a);
+    }
+
+    private void test(String snippet) {
+        StructuredGraph graph = parseProfiled(snippet);
+        Collection<Invoke> hints = new ArrayList<>();
+        for (Invoke invoke : graph.getInvokes()) {
+            hints.add(invoke);
+        }
+        new InliningPhase(null, runtime(), hints, null, getDefaultPhasePlan()).apply(graph);
+        new CanonicalizerPhase(null, runtime(), null).apply(graph);
+        new DeadCodeEliminationPhase().apply(graph);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/InvokeTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,90 @@
+/*
+ * 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.max.graal.compiler.tests;
+
+import static com.oracle.max.graal.graph.iterators.NodePredicates.*;
+
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+
+/**
+ * In the following tests, the usages of local variable "a" are replaced with the integer constant 0.
+ * Then canonicalization is applied and it is verified that the resulting graph is equal to the
+ * graph of the method that just has a "return 1" statement in it.
+ */
+public class InvokeTest extends GraphTest {
+
+    private static final String REFERENCE_SNIPPET = "referenceSnippet";
+
+    @SuppressWarnings("all")
+    public static int referenceSnippet(int a) {
+        return 1;
+    }
+
+    public static int const1() {
+        return 1;
+    }
+
+    @Test
+    public void test1() {
+        test("test1Snippet");
+    }
+
+    @SuppressWarnings("all")
+    public static int test1Snippet(int a) {
+        return const1();
+    }
+
+    @Test
+    public void test2() {
+        test("test2Snippet");
+    }
+
+    @SuppressWarnings("all")
+    public static int test2Snippet(int a) {
+        return const1() + const1() + const1() + const1() + const1() + const1() + const1();
+    }
+
+    private void test(String snippet) {
+        StructuredGraph graph = parse(snippet);
+        LocalNode local = graph.getNodes(LocalNode.class).iterator().next();
+        ConstantNode constant = ConstantNode.forInt(0, graph);
+        for (Node n : local.usages().filter(isNotA(FrameState.class)).snapshot()) {
+            n.replaceFirstInput(local, constant);
+        }
+        Collection<Invoke> hints = new ArrayList<>();
+        for (Invoke invoke : graph.getInvokes()) {
+            hints.add(invoke);
+        }
+        new InliningPhase(null, runtime(), hints, null, getDefaultPhasePlan()).apply(graph);
+        new CanonicalizerPhase(null, runtime(), null).apply(graph);
+        new DeadCodeEliminationPhase().apply(graph);
+        StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET);
+        assertEquals(referenceGraph, graph);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/MonitorTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,107 @@
+/*
+ * 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.max.graal.compiler.tests;
+
+import static com.oracle.max.graal.graph.iterators.NodePredicates.*;
+
+import java.util.*;
+
+import junit.framework.*;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.graph.iterators.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.java.*;
+
+/**
+ * In the following tests, the usages of local variable "a" are replaced with the integer constant 0.
+ * Then canonicalization is applied and it is verified that the resulting graph is equal to the
+ * graph of the method that just has a "return 1" statement in it.
+ */
+public class MonitorTest extends GraphTest {
+
+    private static final String REFERENCE_SNIPPET = "referenceSnippet";
+
+    @SuppressWarnings("all")
+    public static synchronized int referenceSnippet(int a) {
+        return 1;
+    }
+
+    public static int const1() {
+        return 1;
+    }
+
+    @Test(expected = AssertionFailedError.class)
+    public void test1() {
+        test("test1Snippet");
+    }
+
+    @SuppressWarnings("all")
+    public static synchronized int test1Snippet(int a) {
+        return const1();
+    }
+
+    @Test
+    public void test2() {
+        StructuredGraph graph = parseAndProcess("test2Snippet");
+        NodeIterable<MonitorExitNode> monitors = graph.getNodes(MonitorExitNode.class);
+        Assert.assertEquals(1, monitors.count());
+        Assert.assertEquals(monitors.first().stateAfter().bci, 3);
+    }
+
+    @SuppressWarnings("all")
+    public static int test2Snippet(int a) {
+        return const2();
+    }
+
+    public static synchronized int const2() {
+        return 1;
+    }
+
+    private StructuredGraph parseAndProcess(String snippet) {
+        StructuredGraph graph = parse(snippet);
+        LocalNode local = graph.getNodes(LocalNode.class).first();
+        ConstantNode constant = ConstantNode.forInt(0, graph);
+        for (Node n : local.usages().filter(isNotA(FrameState.class)).snapshot()) {
+            n.replaceFirstInput(local, constant);
+        }
+        Collection<Invoke> hints = new ArrayList<>();
+        for (Invoke invoke : graph.getInvokes()) {
+            hints.add(invoke);
+        }
+        new InliningPhase(null, runtime(), hints, null, getDefaultPhasePlan()).apply(graph);
+        new CanonicalizerPhase(null, runtime(), null).apply(graph);
+        new DeadCodeEliminationPhase().apply(graph);
+        return graph;
+    }
+
+    private void test(String snippet) {
+        StructuredGraph graph = parseAndProcess(snippet);
+        StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET);
+        assertEquals(referenceGraph, graph);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/NestedLoopTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,184 @@
+/*
+ * 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.max.graal.compiler.tests;
+
+import org.junit.*;
+
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.lir.cfg.*;
+import com.oracle.max.graal.nodes.*;
+
+public class NestedLoopTest extends GraphTest {
+
+    @Test
+    public void test1() {
+        test("test1Snippet", 1, 2, 2);
+    }
+
+    @Test
+    public void test2() {
+        test("test2Snippet", 1, 2, 2);
+    }
+
+    @Test
+    public void test3() {
+        test("test3Snippet", 1, 2, 2);
+    }
+
+    @Test
+    public void test4() {
+        test("test4Snippet", 1, 3, 2);
+    }
+
+    @SuppressWarnings("all")
+    public static void test1Snippet(int a) {
+        while (a()) { // a() exits root, while() exits root
+            m1: while (b()) { // b() exits nested & root, while() exits nested
+                while (c()) { // c() exits innermost & nested & root, while() exits innermost
+                    if (d()) { // d() exits innermost & nested & root
+                        break m1; // break exits innermost & nested
+                    }
+                }
+            }
+        }
+    }// total : root = 5 exits, nested = 5, innermost = 4
+
+    @SuppressWarnings("all")
+    public static void test2Snippet(int a) {
+        while (a()) { // a() exits root, while() exits root
+            try {
+                m1: while (b()) { // b() exits nested, while() exits nested
+                    while (c()) { // c() exits innermost & nested, while() exits innermost
+                        if (d()) { // d() exits innermost & nested
+                            break m1; // break exits innermost & nested
+                        }
+                    }
+                }
+            } catch (Throwable t) {
+            }
+        }
+    }// total : root = 2 exits, nested = 5, innermost = 4
+
+    @SuppressWarnings("all")
+    public static void test3Snippet(int a) {
+        while (a == 0) { // while() exits root
+            try {
+                m1: while (b()) { // b() exits nested, while() exits nested
+                    while (c()) { // c() exits innermost & nested, while() exits innermost
+                        if (d()) { // d() exits innermost & nested
+                            a(); // a() exits nothing (already outside innermost & nested)
+                            break m1; // break exits innermost & nested
+                        }
+                    }
+                }
+            } catch (Throwable t) {
+            }
+        }
+    }// total : root = 1 exit, nested = 5, innermost = 4
+
+    public static void test4Snippet(int a) {
+        while (a != 0) { // while() exits root
+            try {
+                m1: while (a != 0) { // while() exits nested
+                    b(); // b() exits nested
+                    while (c()) { // c() exits innermost & nested, while() exits innermost
+                        if (d()) { // d() exits innermost & nested
+                            break m1; // break exits innermost & nested
+                        }
+                    }
+                    if (a != 2) {
+                        a(); // a() exits nothing (already outside innermost & nested)
+                        throw new Exception(); // throw exits nested
+                    }
+                }
+            } catch (Throwable t) {
+            }
+        }
+    } // total : root = 1 exit, nested = 6, innermost = 4
+
+    private static boolean a() {
+        return false;
+    }
+
+    private static boolean b() {
+        return false;
+    }
+
+    private static boolean c() {
+        return false;
+    }
+
+    private static boolean d() {
+        return false;
+    }
+
+    private static Invoke getInvoke(String name, StructuredGraph graph) {
+        for (Invoke invoke : graph.getInvokes()) {
+            if (invoke.callTarget().targetMethod().name().equals(name)) {
+                return invoke;
+            }
+        }
+        return null;
+    }
+
+    private void test(String snippet, int rootExits, int nestedExits, int innerExits) {
+        StructuredGraph graph = parse(snippet);
+        Debug.dump(graph, "Graph");
+        ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true);
+
+        Assert.assertTrue(cfg.getLoops().length == 3);
+        Loop rootLoop = cfg.getLoops()[0];
+        Loop nestedLoop = cfg.getLoops()[1];
+        Loop innerMostLoop = cfg.getLoops()[2];
+        Invoke a = getInvoke("a", graph);
+        Invoke b = getInvoke("b", graph);
+        Invoke c = getInvoke("c", graph);
+        Invoke d = getInvoke("d", graph);
+        Assert.assertTrue(containsDirect(rootLoop, a, cfg));
+        Assert.assertTrue(containsDirect(nestedLoop, b, cfg));
+        Assert.assertTrue(containsDirect(innerMostLoop, c, cfg));
+        Assert.assertTrue(containsDirect(innerMostLoop, d, cfg));
+        Assert.assertTrue(contains(rootLoop, d, cfg));
+        Assert.assertTrue(contains(nestedLoop, d, cfg));
+        Assert.assertEquals(rootExits, rootLoop.exits.size());
+        Assert.assertEquals(nestedExits, nestedLoop.exits.size());
+        Assert.assertEquals(innerExits, innerMostLoop.exits.size());
+        Debug.dump(graph, "Graph");
+    }
+
+    private static boolean contains(Loop loop, Invoke node, ControlFlowGraph cfg) {
+        Block block = cfg.blockFor((Node) node);
+        Assert.assertNotNull(block);
+        return loop.blocks.contains(block);
+    }
+
+    private static boolean containsDirect(Loop loop, Invoke node, ControlFlowGraph cfg) {
+        for (Loop child : loop.children) {
+            if (contains(child, node, cfg)) {
+                return false;
+            }
+        }
+        return contains(loop, node, cfg);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/PhiCreationTests.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,114 @@
+/*
+ * 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.max.graal.compiler.tests;
+
+import org.junit.*;
+
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.nodes.*;
+
+/**
+ * In the following tests, the correct removal of redundant phis during graph building is tested.
+ */
+public class PhiCreationTests extends GraphTest {
+
+    /**
+     * Dummy method to avoid javac dead code elimination.
+     */
+    private static void test() {
+    }
+
+    @Test
+    public void test1() {
+        StructuredGraph graph = parse("test1Snippet");
+        Assert.assertFalse(graph.getNodes(PhiNode.class).iterator().hasNext());
+    }
+
+    public static int test1Snippet(int a) {
+        if (a > 1) {
+            test();
+        }
+        return a;
+    }
+
+    @Test
+    public void test2() {
+        StructuredGraph graph = parse("test2Snippet");
+        Assert.assertFalse(graph.getNodes(PhiNode.class).iterator().hasNext());
+    }
+
+    public static int test2Snippet(int a) {
+        while (a > 1) {
+            test();
+        }
+        return a;
+    }
+
+    @Test
+    public void test3() {
+        StructuredGraph graph = parse("test3Snippet");
+        Debug.dump(graph, "Graph");
+        Assert.assertFalse(graph.getNodes(PhiNode.class).iterator().hasNext());
+    }
+
+    public static int test3Snippet(int a) {
+        while (a > 1) {
+            while (a > 1) {
+                test();
+            }
+        }
+        return a;
+    }
+
+    @Test
+    public void test4() {
+        StructuredGraph graph = parse("test4Snippet");
+        Debug.dump(graph, "Graph");
+        Assert.assertFalse(graph.getNodes(PhiNode.class).iterator().hasNext());
+    }
+
+    public static int test4Snippet(int a) {
+        int b = 5;
+        while (a > 1) {
+            while (a > 1) {
+                while (a > 1) {
+                    try {
+                        test();
+                    } catch (Throwable t) {
+
+                    }
+                }
+            }
+            while (a > 1) {
+                while (a > 1) {
+                    try {
+                        test();
+                    } catch (Throwable t) {
+
+                    }
+                }
+            }
+        }
+        return a + b;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/ScalarTypeSystemTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,171 @@
+/*
+ * 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.max.graal.compiler.tests;
+
+import junit.framework.AssertionFailedError;
+
+import org.junit.*;
+
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.nodes.*;
+
+/**
+ * In the following tests, the scalar type system of the compiler should be complete enough to see the relation between the different conditions.
+ */
+public class ScalarTypeSystemTest extends GraphTest {
+
+    public static int referenceSnippet1(int a) {
+        if (a > 0) {
+            return 1;
+        } else {
+            return 2;
+        }
+    }
+
+    @Test(expected = AssertionFailedError.class)
+    public void test1() {
+        test("test1Snippet", "referenceSnippet1");
+    }
+
+    public static int test1Snippet(int a) {
+        if (a > 0) {
+            if (a > -1) {
+                return 1;
+            } else {
+                return 3;
+            }
+        } else {
+            return 2;
+        }
+    }
+
+    @Test(expected = AssertionFailedError.class)
+    public void test2() {
+        test("test2Snippet", "referenceSnippet1");
+    }
+
+    public static int test2Snippet(int a) {
+        if (a > 0) {
+            if (a == -15) {
+                return 3;
+            } else {
+                return 1;
+            }
+        } else {
+            return 2;
+        }
+    }
+
+    @Test(expected = AssertionFailedError.class)
+    public void test3() {
+        test("test3Snippet", "referenceSnippet2");
+    }
+
+    public static int referenceSnippet2(int a, int b) {
+        if (a > b) {
+            return 1;
+        } else {
+            return 2;
+        }
+    }
+
+    public static int test3Snippet(int a, int b) {
+        if (a > b) {
+            if (a == b) {
+                return 3;
+            } else {
+                return 1;
+            }
+        } else {
+            return 2;
+        }
+    }
+
+    @Test(expected = AssertionFailedError.class)
+    public void test4() {
+        test("test4Snippet", "referenceSnippet2");
+    }
+
+    public static int test4Snippet(int a, int b) {
+        if (a > b) {
+            if (a <= b) {
+                return 3;
+            } else {
+                return 1;
+            }
+        } else {
+            return 2;
+        }
+    }
+
+    @Test(expected = AssertionFailedError.class)
+    public void test5() {
+        test("test5Snippet", "referenceSnippet3");
+    }
+
+    public static int referenceSnippet3(int a, int b) {
+        if (a == b) {
+            return 1;
+        } else {
+            return 2;
+        }
+    }
+
+    public static int test5Snippet(int a, int b) {
+        if (a == b) {
+            if (a != b) {
+                return 3;
+            } else {
+                return 1;
+            }
+        } else {
+            return 2;
+        }
+    }
+
+    @Test(expected = AssertionFailedError.class)
+    public void test6() {
+        test("test6Snippet", "referenceSnippet3");
+    }
+
+    public static int test6Snippet(int a, int b) {
+        if (a == b) {
+            if (a == b + 1) {
+                return 3;
+            } else {
+                return 1;
+            }
+        } else {
+            return 2;
+        }
+    }
+
+    private void test(String snippet, String referenceSnippet) {
+        StructuredGraph graph = parse(snippet);
+        Debug.dump(graph, "Graph");
+        new CanonicalizerPhase(null, runtime(), null).apply(graph);
+        StructuredGraph referenceGraph = parse(referenceSnippet);
+        assertEquals(referenceGraph, graph);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/StraighteningTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,96 @@
+/*
+ * 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.max.graal.compiler.tests;
+
+import junit.framework.AssertionFailedError;
+
+import org.junit.*;
+
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.nodes.*;
+
+public class StraighteningTest extends GraphTest {
+
+    private static final String REFERENCE_SNIPPET = "ref";
+
+    public static boolean ref(int a, int b) {
+        return a == b;
+    }
+
+    public static boolean test1Snippet(int a, int b) {
+        int c = a;
+        if (c == b) {
+            c = 0x55;
+        }
+        if (c != 0x55) {
+            return false;
+        }
+        return true;
+    }
+
+    public static boolean test3Snippet(int a, int b) {
+        int val = (int) System.currentTimeMillis();
+        int c = val + 1;
+        if (a == b) {
+            c = val;
+        }
+        if (c != val) {
+            return false;
+        }
+        return true;
+    }
+
+    public static boolean test2Snippet(int a, int b) {
+        int c;
+        if (a == b) {
+            c = 1;
+        } else {
+            c = 0;
+        }
+        return c == 1;
+    }
+
+    @Test(expected = AssertionFailedError.class)
+    public void test1() {
+        test("test1Snippet");
+    }
+
+    @Test(expected = AssertionFailedError.class)
+    public void test2() {
+        test("test2Snippet");
+    }
+
+    @Test(expected = AssertionFailedError.class)
+    public void test3() {
+        test("test3Snippet");
+    }
+
+    private void test(String snippet) {
+        StructuredGraph graph = parse(snippet);
+        Debug.dump(graph, "Graph");
+        new CanonicalizerPhase(null, runtime(), null).apply(graph);
+        StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET);
+        assertEquals(referenceGraph, graph);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/TypeSystemTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,71 @@
+/*
+ * 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.max.graal.compiler.tests;
+
+import org.junit.*;
+
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.compiler.types.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.nodes.java.*;
+
+/**
+ * In the following tests, the scalar type system of the compiler should be complete enough to see the relation between the different conditions.
+ */
+public class TypeSystemTest extends GraphTest {
+
+    @Test
+    public void test1() {
+        test("test1Snippet", CheckCastNode.class);
+    }
+
+    public static int test1Snippet(Object a) {
+        if (a instanceof Boolean) {
+            return ((Boolean) a).booleanValue() ? 0 : 1;
+        }
+        return 1;
+    }
+
+    @Test
+    public void test2() {
+        test("test2Snippet", CheckCastNode.class);
+    }
+
+    public static int test2Snippet(Object a) {
+        if (a instanceof Integer) {
+            return ((Number) a).intValue();
+        }
+        return 1;
+    }
+
+    private <T extends Node & Node.IterableNodeType> void test(String snippet, Class<T> clazz) {
+        StructuredGraph graph = parse(snippet);
+        Debug.dump(graph, "Graph");
+        new CanonicalizerPhase(null, runtime(), null).apply(graph);
+        new PropagateTypesPhase(null, null, null).apply(graph);
+        Debug.dump(graph, "Graph");
+        Assert.assertFalse("shouldn't have nodes of type " + clazz, graph.getNodes(clazz).iterator().hasNext());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/.cproject	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,671 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?>
+
+<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881" moduleId="org.eclipse.cdt.core.settings" name="Default">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="hotspot" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
+					<folderInfo id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577" name="/" resourcePath="">
+						<toolChain id="cdt.managedbuild.toolchain.gnu.base.1866612258" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.2075405295" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
+							<builder arguments="${workspace_loc:/hotspot}/../domake" autoBuildTarget="jvmg1" buildPath="${workspace_loc:/hotspot}/.." cleanBuildTarget="clean" command="bash" enableAutoBuild="true" enableCleanBuild="false" enabledIncrementalBuild="false" id="cdt.managedbuild.target.gnu.builder.base.81453037" incrementalBuildTarget="jvmg1" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelizationNumber="1" superClass="cdt.managedbuild.target.gnu.builder.base">
+								<outputEntries>
+									<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="outputPath" name=""/>
+								</outputEntries>
+							</builder>
+							<tool id="cdt.managedbuild.tool.gnu.archiver.base.1094883386" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+							<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1342888057" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
+								<option id="gnu.cpp.compiler.option.include.paths.801956928" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths"/>
+								<option id="gnu.cpp.compiler.option.preprocessor.def.634868600" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="_LP64=1"/>
+									<listOptionValue builtIn="false" value="COMPILER1=1"/>
+									<listOptionValue builtIn="false" value="VM_LITTLE_ENDIAN=1"/>
+									<listOptionValue builtIn="false" value="ASSERT=1"/>
+									<listOptionValue builtIn="false" value="_REENTRANT=1"/>
+									<listOptionValue builtIn="false" value="DEBUG=1"/>
+									<listOptionValue builtIn="false" value="AMD64=1"/>
+									<listOptionValue builtIn="false" value="LINUX=1"/>
+									<listOptionValue builtIn="false" value="TARGET_ARCH_x86"/>
+									<listOptionValue builtIn="false" value="TARGET_COMPILER_gcc=1"/>
+								</option>
+								<option id="gnu.cpp.compiler.option.preprocessor.undef.2137486146" name="Undefined symbols (-U)" superClass="gnu.cpp.compiler.option.preprocessor.undef" valueType="undefDefinedSymbols">
+									<listOptionValue builtIn="false" value="PRODUCT"/>
+								</option>
+								<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.866181452" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.1535888880" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
+								<option id="gnu.c.compiler.option.preprocessor.def.symbols.825962493" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="_LP64=1"/>
+									<listOptionValue builtIn="false" value="COMPILER1=1"/>
+									<listOptionValue builtIn="false" value="VM_LITTLE_ENDIAN=1"/>
+									<listOptionValue builtIn="false" value="ASSERT=1"/>
+									<listOptionValue builtIn="false" value="_REENTRANT=1"/>
+									<listOptionValue builtIn="false" value="DEBUG=1"/>
+									<listOptionValue builtIn="false" value="AMD64=1"/>
+								</option>
+								<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.906671119" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.c.linker.base.1271041307" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
+							<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.550499946" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
+								<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.274517766" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.assembler.base.554053529" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
+								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1055083385" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+							</tool>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+			<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+			<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
+			<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="hotspot.null.1712822257" name="hotspot"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+			<buildOutputProvider>
+				<openAction enabled="true" filePath=""/>
+				<parser enabled="true"/>
+			</buildOutputProvider>
+			<scannerInfoProvider id="specsFile">
+				<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+				<parser enabled="true"/>
+			</scannerInfoProvider>
+		</profile>
+		<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+			<buildOutputProvider>
+				<openAction enabled="true" filePath=""/>
+				<parser enabled="true"/>
+			</buildOutputProvider>
+			<scannerInfoProvider id="makefileGenerator">
+				<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
+				<parser enabled="true"/>
+			</scannerInfoProvider>
+		</profile>
+		<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+			<buildOutputProvider>
+				<openAction enabled="true" filePath=""/>
+				<parser enabled="true"/>
+			</buildOutputProvider>
+			<scannerInfoProvider id="specsFile">
+				<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+				<parser enabled="true"/>
+			</scannerInfoProvider>
+		</profile>
+		<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+			<buildOutputProvider>
+				<openAction enabled="true" filePath=""/>
+				<parser enabled="true"/>
+			</buildOutputProvider>
+			<scannerInfoProvider id="specsFile">
+				<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+				<parser enabled="true"/>
+			</scannerInfoProvider>
+		</profile>
+		<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+			<buildOutputProvider>
+				<openAction enabled="true" filePath=""/>
+				<parser enabled="true"/>
+			</buildOutputProvider>
+			<scannerInfoProvider id="specsFile">
+				<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+				<parser enabled="true"/>
+			</scannerInfoProvider>
+		</profile>
+		<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+			<buildOutputProvider>
+				<openAction enabled="true" filePath=""/>
+				<parser enabled="true"/>
+			</buildOutputProvider>
+			<scannerInfoProvider id="specsFile">
+				<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+				<parser enabled="true"/>
+			</scannerInfoProvider>
+		</profile>
+		<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+			<buildOutputProvider>
+				<openAction enabled="true" filePath=""/>
+				<parser enabled="true"/>
+			</buildOutputProvider>
+			<scannerInfoProvider id="specsFile">
+				<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+				<parser enabled="true"/>
+			</scannerInfoProvider>
+		</profile>
+		<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+			<buildOutputProvider>
+				<openAction enabled="true" filePath=""/>
+				<parser enabled="true"/>
+			</buildOutputProvider>
+			<scannerInfoProvider id="specsFile">
+				<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+				<parser enabled="true"/>
+			</scannerInfoProvider>
+		</profile>
+		<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577;cdt.managedbuild.tool.gnu.solaris.cpp.compiler.base.429326045;cdt.managedbuild.tool.gnu.cpp.compiler.input.1860785837">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="makefileGenerator">
+					<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577;cdt.managedbuild.tool.gnu.cpp.compiler.base.1342888057;cdt.managedbuild.tool.gnu.cpp.compiler.input.866181452">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="makefileGenerator">
+					<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577;cdt.managedbuild.tool.gnu.solaris.c.compiler.base.351149667;cdt.managedbuild.tool.gnu.c.compiler.input.820447325">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="makefileGenerator">
+					<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.388217325;cdt.managedbuild.tool.gnu.solaris.c.compiler.base.212558466;cdt.managedbuild.tool.gnu.c.compiler.input.1115218695">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="makefileGenerator">
+					<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.388217325;cdt.managedbuild.tool.gnu.solaris.cpp.compiler.base.377383651;cdt.managedbuild.tool.gnu.cpp.compiler.input.103897085">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="makefileGenerator">
+					<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577;cdt.managedbuild.tool.gnu.c.compiler.base.1535888880;cdt.managedbuild.tool.gnu.c.compiler.input.906671119">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="makefileGenerator">
+					<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+		</scannerConfigBuildInfo>
+	</storageModule>
+	<storageModule moduleId="refreshScope" versionNumber="1">
+		<resource resourceType="PROJECT" workspacePath="/hotspot"/>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+</cproject>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/.project	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>hotspot</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+			<triggers>auto,</triggers>
+			<arguments>
+				<dictionary>
+					<key>?children?</key>
+					<value>?name?=outputEntries\|?children?=?name?=entry\\\\\\\|\\\|\||</value>
+				</dictionary>
+				<dictionary>
+					<key>?name?</key>
+					<value></value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.append_environment</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
+					<value>jvmg1</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildArguments</key>
+					<value>${workspace_loc:/hotspot}/../domake</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildCommand</key>
+					<value>bash</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildLocation</key>
+					<value>${workspace_loc:/hotspot}/..</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
+					<value>clean</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.contents</key>
+					<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
+					<value>false</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableFullBuild</key>
+					<value>false</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
+					<value>jvmg1</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.stopOnError</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+					<value>false</value>
+				</dictionary>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>org.eclipse.cdt.core.ccnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+	</natures>
+	<linkedResources>
+		<link>
+			<name>cpu</name>
+			<type>2</type>
+			<locationURI>PARENT-1-PROJECT_LOC/src/cpu/x86</locationURI>
+		</link>
+		<link>
+			<name>generated</name>
+			<type>2</type>
+			<locationURI>PARENT-1-PROJECT_LOC/build/linux/linux_amd64_graal/generated</locationURI>
+		</link>
+		<link>
+			<name>make</name>
+			<type>2</type>
+			<locationURI>WORKSPACE_LOC/make</locationURI>
+		</link>
+		<link>
+			<name>os</name>
+			<type>2</type>
+			<locationURI>PARENT-1-PROJECT_LOC/src/os/linux</locationURI>
+		</link>
+		<link>
+			<name>os_cpu</name>
+			<type>2</type>
+			<locationURI>PARENT-1-PROJECT_LOC/src/os_cpu/linux_x86</locationURI>
+		</link>
+		<link>
+			<name>vm</name>
+			<type>2</type>
+			<locationURI>PARENT-1-PROJECT_LOC/src/share/vm</locationURI>
+		</link>
+	</linkedResources>
+</projectDescription>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/.settings/org.eclipse.cdt.core.prefs	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,153 @@
+#Wed Sep 01 16:57:34 PDT 2010
+eclipse.preferences.version=1
+org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration=80
+org.eclipse.cdt.core.formatter.alignment_for_compact_if=0
+org.eclipse.cdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.cdt.core.formatter.alignment_for_declarator_list=16
+org.eclipse.cdt.core.formatter.alignment_for_enumerator_list=48
+org.eclipse.cdt.core.formatter.alignment_for_expression_list=0
+org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.cdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.cdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.cdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.cdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.cdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration=end_of_line
+org.eclipse.cdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.cdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.cdt.core.formatter.compact_else_if=true
+org.eclipse.cdt.core.formatter.continuation_indentation=2
+org.eclipse.cdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.cdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header=false
+org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier=true
+org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header=false
+org.eclipse.cdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.cdt.core.formatter.indent_declaration_compare_to_template_header=false
+org.eclipse.cdt.core.formatter.indent_empty_lines=false
+org.eclipse.cdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.cdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch=true
+org.eclipse.cdt.core.formatter.indentation.size=2
+org.eclipse.cdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.cdt.core.formatter.insert_new_line_after_template_declaration=do not insert
+org.eclipse.cdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.cdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.cdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.cdt.core.formatter.insert_new_line_before_identifier_in_function_declaration=do not insert
+org.eclipse.cdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.cdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.cdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.cdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_arguments=insert
+org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_parameters=insert
+org.eclipse.cdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.cdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.cdt.core.formatter.insert_space_after_colon_in_base_clause=insert
+org.eclipse.cdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.cdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.cdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.cdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.cdt.core.formatter.insert_space_after_comma_in_base_types=insert
+org.eclipse.cdt.core.formatter.insert_space_after_comma_in_declarator_list=insert
+org.eclipse.cdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.cdt.core.formatter.insert_space_after_comma_in_expression_list=insert
+org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_arguments=insert
+org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_parameters=insert
+org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_arguments=do not insert
+org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_parameters=do not insert
+org.eclipse.cdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.cdt.core.formatter.insert_space_after_opening_bracket=do not insert
+org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_exception_specification=do not insert
+org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.cdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.cdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.cdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.cdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.cdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.cdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_arguments=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_parameters=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.cdt.core.formatter.insert_space_before_closing_bracket=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_exception_specification=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_colon_in_base_clause=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.cdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_comma_in_base_types=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_comma_in_declarator_list=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_comma_in_expression_list=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_arguments=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_parameters=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_arguments=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_parameters=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_namespace_declaration=insert
+org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.cdt.core.formatter.insert_space_before_opening_bracket=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_exception_specification=insert
+org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.cdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.cdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.cdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.cdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.cdt.core.formatter.insert_space_between_empty_brackets=do not insert
+org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_exception_specification=do not insert
+org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.cdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line=true
+org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.cdt.core.formatter.lineSplit=160
+org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.cdt.core.formatter.tabulation.char=space
+org.eclipse.cdt.core.formatter.tabulation.size=2
+org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations=false
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/.settings/org.eclipse.cdt.ui.prefs	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,5 @@
+#Wed Sep 01 16:21:02 PDT 2010
+eclipse.preferences.version=1
+formatter_profile=_hotspotStyle
+formatter_settings_version=1
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/.settings/org.eclipse.core.runtime.prefs	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,6 @@
+#Wed Sep 01 16:13:40 PDT 2010
+content-types/enabled=true
+content-types/org.eclipse.cdt.core.cxxHeader/file-extensions=hpp,incl
+content-types/org.eclipse.cdt.core.cxxSource/file-extensions=cpp
+eclipse.preferences.version=1
+
--- a/make/Makefile	Fri Feb 24 18:08:59 2012 -0800
+++ b/make/Makefile	Mon Feb 27 13:10:13 2012 +0100
@@ -88,6 +88,7 @@
 KERNEL_VM_TARGETS=productkernel fastdebugkernel optimizedkernel jvmgkernel
 ZERO_VM_TARGETS=productzero fastdebugzero optimizedzero jvmgzero
 SHARK_VM_TARGETS=productshark fastdebugshark optimizedshark jvmgshark
+GRAAL_VM_TARGETS=productgraal fastdebuggraal optimizedgraal jvmggraal
 
 COMMON_VM_PRODUCT_TARGETS=product product1 productkernel docs export_product
 COMMON_VM_FASTDEBUG_TARGETS=fastdebug fastdebug1 fastdebugkernel docs export_fastdebug
@@ -128,6 +129,12 @@
 all_debugshark:     jvmgshark docs export_debug
 all_optimizedshark: optimizedshark docs export_optimized
 
+allgraal:           all_productgraal all_fastdebuggraal
+all_productgraal:   productgraal docs export_product
+all_fastdebuggraal: fastdebuggraal docs export_fastdebug
+all_debuggraal:     jvmggraal docs export_debug
+all_optimizedgraal: optimizedgraal docs export_optimized
+
 # Do everything
 world:         all create_jdk
 
@@ -162,6 +169,10 @@
 	$(CD) $(GAMMADIR)/make; \
 	$(MAKE) VM_TARGET=$@ generic_buildshark $(ALT_OUT)
 
+$(GRAAL_VM_TARGETS):
+	$(CD) $(GAMMADIR)/make; \
+	$(MAKE) VM_TARGET=$@ generic_buildgraal $(ALT_OUT)
+
 # Build compiler1 (client) rule, different for platforms
 generic_build1:
 	$(MKDIR) -p $(OUTPUTDIR)
@@ -178,13 +189,9 @@
 	@$(ECHO) "No compiler1 ($(VM_TARGET)) for ARCH_DATA_MODEL=$(ARCH_DATA_MODEL)"
   endif
 else
-  ifeq ($(ARCH_DATA_MODEL), 32)
 	$(CD) $(OUTPUTDIR); \
 	    $(MAKE) -f $(ABS_OS_MAKEFILE) \
 		      $(MAKE_ARGS) $(VM_TARGET)
-  else
-	@$(ECHO) "No compiler1 ($(VM_TARGET)) for ARCH_DATA_MODEL=$(ARCH_DATA_MODEL)"
-  endif
 endif
 
 # Build compiler2 (server) rule, different for platforms
@@ -234,6 +241,12 @@
 		$(MAKE) -f $(ABS_OS_MAKEFILE) \
 			$(MAKE_ARGS) $(VM_TARGET) 
 
+generic_buildgraal:
+	$(MKDIR) -p $(OUTPUTDIR)
+	$(CD) $(OUTPUTDIR); \
+		$(MAKE) -f $(ABS_OS_MAKEFILE) \
+			$(MAKE_ARGS) $(VM_TARGET) 
+
 # Export file rule
 generic_export: $(EXPORT_LIST)
 export_product:
@@ -265,11 +278,13 @@
 KERNEL_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_kernel
 ZERO_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_zero
 SHARK_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_shark
+GRAAL_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_graal
 C1_DIR=$(C1_BASE_DIR)/$(VM_SUBDIR)
 C2_DIR=$(C2_BASE_DIR)/$(VM_SUBDIR)
 KERNEL_DIR=$(KERNEL_BASE_DIR)/$(VM_SUBDIR)
 ZERO_DIR=$(ZERO_BASE_DIR)/$(VM_SUBDIR)
 SHARK_DIR=$(SHARK_BASE_DIR)/$(VM_SUBDIR)
+GRAAL_DIR=$(GRAAL_BASE_DIR)/$(VM_SUBDIR)
 
 # Misc files and generated files need to come from C1 or C2 area
 ifeq ($(ZERO_BUILD), true)
@@ -425,6 +440,7 @@
 	$(RM) -r $(KERNEL_DIR)
 	$(RM) -r $(ZERO_DIR)
 	$(RM) -r $(SHARK_DIR)
+	$(RM) -r $(GRAAL_DIR)
 clean_export:
 	$(RM) -r $(EXPORT_PATH)
 clean_jdk:
--- a/make/bsd/Makefile	Fri Feb 24 18:08:59 2012 -0800
+++ b/make/bsd/Makefile	Mon Feb 27 13:10:13 2012 +0100
@@ -199,6 +199,7 @@
 SUBDIRS_CORE      = $(addprefix $(OSNAME)_$(BUILDARCH)_core/,$(TARGETS))
 SUBDIRS_ZERO      = $(addprefix $(OSNAME)_$(VARIANTARCH)_zero/,$(TARGETS))
 SUBDIRS_SHARK     = $(addprefix $(OSNAME)_$(VARIANTARCH)_shark/,$(TARGETS))
+SUBDIRS_GRAAL     = $(addprefix $(OSNAME)_$(BUILDARCH)_graal/,$(TARGETS))
 
 TARGETS_C2        = $(TARGETS)
 TARGETS_C1        = $(addsuffix 1,$(TARGETS))
@@ -206,6 +207,7 @@
 TARGETS_CORE      = $(addsuffix core,$(TARGETS))
 TARGETS_ZERO      = $(addsuffix zero,$(TARGETS))
 TARGETS_SHARK     = $(addsuffix shark,$(TARGETS))
+TARGETS_GRAAL     = $(addsuffix graal,$(TARGETS))
 
 BUILDTREE_MAKE    = $(GAMMADIR)/make/$(OSNAME)/makefiles/buildtree.make
 BUILDTREE_VARS    = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OSNAME) SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) LIBRARY_SUFFIX=$(LIBRARY_SUFFIX)
@@ -223,6 +225,7 @@
 	@echo "  $(TARGETS_CORE)"
 	@echo "  $(TARGETS_ZERO)"
 	@echo "  $(TARGETS_SHARK)"
+	@echo "  $(TARGETS_GRAAL)"
 
 checks: check_os_version check_j2se_version
 
@@ -281,6 +284,10 @@
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
 	$(BUILDTREE) VARIANT=shark VARIANTARCH=$(VARIANTARCH)
 
+$(SUBDIRS_GRAAL): $(BUILDTREE_MAKE)
+	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
+	$(BUILDTREE) VARIANT=graal
+
 platform_zero: $(GAMMADIR)/make/$(OSNAME)/platform_zero.in
 	$(SED) 's/@ZERO_ARCHDEF@/$(ZERO_ARCHDEF)/g;s/@ZERO_LIBARCH@/$(ZERO_LIBARCH)/g;' < $< > $@
 
@@ -328,12 +335,19 @@
 	cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && $(MAKE) $(MFLAGS) install
 endif
 
+$(TARGETS_GRAAL):  $(SUBDIRS_GRAAL)
+	cd $(OSNAME)_$(BUILDARCH)_graal/$(patsubst %graal,%,$@) && $(MAKE) $(MFLAGS)
+ifdef INSTALL
+	cd $(OSNAME)_$(BUILDARCH)_graal/$(patsubst %graal,%,$@) && $(MAKE) $(MFLAGS) install
+endif
+
 # Just build the tree, and nothing else:
 tree:      $(SUBDIRS_C2)
 tree1:     $(SUBDIRS_C1)
 treecore:  $(SUBDIRS_CORE)
 treezero:  $(SUBDIRS_ZERO)
 treeshark: $(SUBDIRS_SHARK)
+treegraal: $(SUBDIRS_GRAAL)
 
 # Doc target.  This is the same for all build options.
 #     Hence create a docs directory beside ...$(ARCH)_[...]
@@ -364,8 +378,8 @@
 
 #-------------------------------------------------------------------------------
 
-.PHONY: $(TARGETS_C2) $(TARGETS_C1) $(TARGETS_CORE) $(TARGETS_ZERO) $(TARGETS_SHARK)
-.PHONY: tree tree1 treecore treezero treeshark
-.PHONY: all compiler1 compiler2 core zero shark
-.PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark docs clean_docs
+.PHONY: $(TARGETS_C2) $(TARGETS_C1) $(TARGETS_CORE) $(TARGETS_ZERO) $(TARGETS_SHARK) $(TARGETS_GRAAL)
+.PHONY: tree tree1 treecore treezero treeshark treegraal
+.PHONY: all compiler1 compiler2 core zero shark graal
+.PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark docs clean_docs clean_graal
 .PHONY: checks check_os_version check_j2se_version
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/bsd/makefiles/graal.make	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2008, 2010 Red Hat, Inc.
+# 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.
+#  
+#
+
+# Sets make macros for making Graal version of VM
+
+TYPE = GRAAL
+
+VM_SUBDIR = graal
+
+CFLAGS += -DGRAAL -DCOMPILER1
--- a/make/bsd/makefiles/vm.make	Fri Feb 24 18:08:59 2012 -0800
+++ b/make/bsd/makefiles/vm.make	Mon Feb 27 13:10:13 2012 +0100
@@ -126,7 +126,7 @@
 # By default, link the *.o into the library, not the executable.
 LINK_INTO$(LINK_INTO) = LIBJVM
 
-JDK_LIBDIR = $(JAVA_HOME)/jre/lib/$(LIBARCH)
+JDK_LIBDIR = $(JAVA_HOME)/jre/lib
 
 #----------------------------------------------------------------------
 # jvm_db & dtrace
@@ -145,7 +145,7 @@
   LIBJVM_G = lib$(JVM)$(G_SUFFIX).so
 endif
 
-SPECIAL_PATHS:=adlc c1 gc_implementation opto shark libadt
+SPECIAL_PATHS:=adlc c1 gc_implementation opto shark libadt graal
 
 SOURCE_PATHS=\
   $(shell find $(HS_COMMON_SRC)/share/vm/* -type d \! \
@@ -175,6 +175,11 @@
 
 SHARK_PATHS := $(GAMMADIR)/src/share/vm/shark
 
+GRAAL_PATHS := $(call altsrc,$(HS_COMMON_SRC)/share/vm/c1)
+GRAAL_PATHS += $(HS_COMMON_SRC)/share/vm/c1
+GRAAL_PATHS += $(call altsrc,$(HS_COMMON_SRC)/share/vm/graal)
+GRAAL_PATHS += $(HS_COMMON_SRC)/share/vm/graal
+
 # Include dirs per type.
 Src_Dirs/CORE      := $(CORE_PATHS)
 Src_Dirs/COMPILER1 := $(CORE_PATHS) $(COMPILER1_PATHS)
@@ -182,12 +187,14 @@
 Src_Dirs/TIERED    := $(CORE_PATHS) $(COMPILER1_PATHS) $(COMPILER2_PATHS)
 Src_Dirs/ZERO      := $(CORE_PATHS)
 Src_Dirs/SHARK     := $(CORE_PATHS) $(SHARK_PATHS)
+Src_Dirs/GRAAL     := $(CORE_PATHS) $(GRAAL_PATHS)
 Src_Dirs := $(Src_Dirs/$(TYPE))
 
 COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp chaitin\* c2_\* runtime_\*
 COMPILER1_SPECIFIC_FILES := c1_\*
 SHARK_SPECIFIC_FILES     := shark
 ZERO_SPECIFIC_FILES      := zero
+GRAAL_SPECIFIC_FILES     := graal
 
 # Always exclude these.
 Src_Files_EXCLUDE := jsig.c jvmtiEnvRecommended.cpp jvmtiEnvStub.cpp
@@ -199,6 +206,7 @@
 Src_Files_EXCLUDE/TIERED    := $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES)
 Src_Files_EXCLUDE/ZERO      := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) ciTypeFlow.cpp
 Src_Files_EXCLUDE/SHARK     := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES)
+Src_Files_EXCLUDE/GRAAL     := $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) ciTypeFlow.cpp
 
 Src_Files_EXCLUDE +=  $(Src_Files_EXCLUDE/$(TYPE))
 
--- a/make/linux/Makefile	Fri Feb 24 18:08:59 2012 -0800
+++ b/make/linux/Makefile	Mon Feb 27 13:10:13 2012 +0100
@@ -199,6 +199,7 @@
 SUBDIRS_CORE      = $(addprefix $(OSNAME)_$(BUILDARCH)_core/,$(TARGETS))
 SUBDIRS_ZERO      = $(addprefix $(OSNAME)_$(VARIANTARCH)_zero/,$(TARGETS))
 SUBDIRS_SHARK     = $(addprefix $(OSNAME)_$(VARIANTARCH)_shark/,$(TARGETS))
+SUBDIRS_GRAAL     = $(addprefix $(OSNAME)_$(BUILDARCH)_graal/,$(TARGETS))
 
 TARGETS_C2        = $(TARGETS)
 TARGETS_C1        = $(addsuffix 1,$(TARGETS))
@@ -206,6 +207,7 @@
 TARGETS_CORE      = $(addsuffix core,$(TARGETS))
 TARGETS_ZERO      = $(addsuffix zero,$(TARGETS))
 TARGETS_SHARK     = $(addsuffix shark,$(TARGETS))
+TARGETS_GRAAL     = $(addsuffix graal,$(TARGETS))
 
 BUILDTREE_MAKE    = $(GAMMADIR)/make/$(OSNAME)/makefiles/buildtree.make
 BUILDTREE_VARS    = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OSNAME) SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH)
@@ -224,6 +226,7 @@
 	@echo "  $(TARGETS_CORE)"
 	@echo "  $(TARGETS_ZERO)"
 	@echo "  $(TARGETS_SHARK)"
+	@echo "  $(TARGETS_GRAAL)"
 
 checks: check_os_version check_j2se_version
 
@@ -281,6 +284,10 @@
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
 	$(BUILDTREE) VARIANT=shark VARIANTARCH=$(VARIANTARCH)
 
+$(SUBDIRS_GRAAL): $(BUILDTREE_MAKE)
+	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
+	$(BUILDTREE) VARIANT=graal
+
 platform_zero: $(GAMMADIR)/make/$(OSNAME)/platform_zero.in
 	$(SED) 's/@ZERO_ARCHDEF@/$(ZERO_ARCHDEF)/g;s/@ZERO_LIBARCH@/$(ZERO_LIBARCH)/g;' < $< > $@
 
@@ -328,12 +335,19 @@
 	cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && $(MAKE) $(MFLAGS) install
 endif
 
+$(TARGETS_GRAAL):  $(SUBDIRS_GRAAL)
+	cd $(OSNAME)_$(BUILDARCH)_graal/$(patsubst %graal,%,$@) && $(MAKE) $(MFLAGS)
+ifdef INSTALL
+	cd $(OSNAME)_$(BUILDARCH)_graal/$(patsubst %graal,%,$@) && $(MAKE) $(MFLAGS) install
+endif
+
 # Just build the tree, and nothing else:
 tree:      $(SUBDIRS_C2)
 tree1:     $(SUBDIRS_C1)
 treecore:  $(SUBDIRS_CORE)
 treezero:  $(SUBDIRS_ZERO)
 treeshark: $(SUBDIRS_SHARK)
+treegraal: $(SUBDIRS_GRAAL)
 
 # Doc target.  This is the same for all build options.
 #     Hence create a docs directory beside ...$(ARCH)_[...]
@@ -364,8 +378,8 @@
 
 #-------------------------------------------------------------------------------
 
-.PHONY: $(TARGETS_C2) $(TARGETS_C1) $(TARGETS_CORE) $(TARGETS_ZERO) $(TARGETS_SHARK)
-.PHONY: tree tree1 treecore treezero treeshark
-.PHONY: all compiler1 compiler2 core zero shark
-.PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark docs clean_docs
+.PHONY: $(TARGETS_C2) $(TARGETS_C1) $(TARGETS_CORE) $(TARGETS_ZERO) $(TARGETS_SHARK) $(TARGETS_GRAAL)
+.PHONY: tree tree1 treecore treezero treeshark treegraal
+.PHONY: all compiler1 compiler2 core zero shark graal
+.PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark docs clean_docs clean_graal
 .PHONY: checks check_os_version check_j2se_version
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/linux/makefiles/graal.make	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2008, 2010 Red Hat, Inc.
+# 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.
+#  
+#
+
+# Sets make macros for making Graal version of VM
+
+TYPE = GRAAL
+
+VM_SUBDIR = graal
+
+CFLAGS += -DGRAAL -DCOMPILER1
--- a/make/linux/makefiles/vm.make	Fri Feb 24 18:08:59 2012 -0800
+++ b/make/linux/makefiles/vm.make	Mon Feb 27 13:10:13 2012 +0100
@@ -141,7 +141,7 @@
 LIBJVM_DEBUGINFO   = lib$(JVM).debuginfo
 LIBJVM_G_DEBUGINFO = lib$(JVM)$(G_SUFFIX).debuginfo
 
-SPECIAL_PATHS:=adlc c1 gc_implementation opto shark libadt
+SPECIAL_PATHS:=adlc c1 gc_implementation opto shark libadt graal
 
 SOURCE_PATHS=\
   $(shell find $(HS_COMMON_SRC)/share/vm/* -type d \! \
@@ -171,6 +171,11 @@
 
 SHARK_PATHS := $(GAMMADIR)/src/share/vm/shark
 
+GRAAL_PATHS := $(call altsrc,$(HS_COMMON_SRC)/share/vm/c1)
+GRAAL_PATHS += $(HS_COMMON_SRC)/share/vm/c1
+GRAAL_PATHS += $(call altsrc,$(HS_COMMON_SRC)/share/vm/graal)
+GRAAL_PATHS += $(HS_COMMON_SRC)/share/vm/graal
+
 # Include dirs per type.
 Src_Dirs/CORE      := $(CORE_PATHS)
 Src_Dirs/COMPILER1 := $(CORE_PATHS) $(COMPILER1_PATHS)
@@ -178,12 +183,14 @@
 Src_Dirs/TIERED    := $(CORE_PATHS) $(COMPILER1_PATHS) $(COMPILER2_PATHS)
 Src_Dirs/ZERO      := $(CORE_PATHS)
 Src_Dirs/SHARK     := $(CORE_PATHS) $(SHARK_PATHS)
+Src_Dirs/GRAAL     := $(CORE_PATHS) $(GRAAL_PATHS)
 Src_Dirs := $(Src_Dirs/$(TYPE))
 
 COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp chaitin\* c2_\* runtime_\*
 COMPILER1_SPECIFIC_FILES := c1_\*
 SHARK_SPECIFIC_FILES     := shark
 ZERO_SPECIFIC_FILES      := zero
+GRAAL_SPECIFIC_FILES     := graal
 
 # Always exclude these.
 Src_Files_EXCLUDE := jsig.c jvmtiEnvRecommended.cpp jvmtiEnvStub.cpp
@@ -195,6 +202,7 @@
 Src_Files_EXCLUDE/TIERED    := $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES)
 Src_Files_EXCLUDE/ZERO      := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) ciTypeFlow.cpp
 Src_Files_EXCLUDE/SHARK     := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES)
+Src_Files_EXCLUDE/GRAAL     := $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) ciTypeFlow.cpp
 
 Src_Files_EXCLUDE +=  $(Src_Files_EXCLUDE/$(TYPE))
 
--- a/make/windows/build.make	Fri Feb 24 18:08:59 2012 -0800
+++ b/make/windows/build.make	Mon Feb 27 13:10:13 2012 +0100
@@ -112,6 +112,8 @@
 VARIANT_TEXT=Tiered
 !elseif "$(Variant)" == "kernel"
 VARIANT_TEXT=Kernel
+!elseif "$(Variant)" == "graal"
+VARIANT_TEXT=Graal
 !endif
 
 #########################################################################
@@ -302,9 +304,9 @@
 checks: checkVariant checkWorkSpace checkSA
 
 checkVariant:
-	@ if "$(Variant)"=="" echo Need to specify "Variant=[tiered|compiler2|compiler1|kernel|core]" && false
-	@ if "$(Variant)" NEQ "tiered" if "$(Variant)" NEQ "compiler2" if "$(Variant)" NEQ "compiler1" if "$(Variant)" NEQ "kernel" if "$(Variant)" NEQ "core" \
-          echo Need to specify "Variant=[tiered|compiler2|compiler1|kernel|core]" && false
+	@ if "$(Variant)"=="" echo Need to specify "Variant=[graal|tiered|compiler2|compiler1|kernel|core]" && false
+	@ if "$(Variant)" NEQ "graal" if "$(Variant)" NEQ "tiered" if "$(Variant)" NEQ "compiler2" if "$(Variant)" NEQ "compiler1" if "$(Variant)" NEQ "kernel" if "$(Variant)" NEQ "core" \
+          echo Need to specify "Variant=[graal|tiered|compiler2|compiler1|kernel|core]" && false
 
 checkWorkSpace:
 	@ if "$(WorkSpace)"=="" echo Need to specify "WorkSpace=..." && false
--- a/make/windows/build_vm_def.sh	Fri Feb 24 18:08:59 2012 -0800
+++ b/make/windows/build_vm_def.sh	Mon Feb 27 13:10:13 2012 +0100
@@ -54,6 +54,7 @@
 CAT="$MKS_HOME/cat.exe"
 RM="$MKS_HOME/rm.exe"
 DUMPBIN="link.exe /dump"
+export VS_UNICODE_OUTPUT= 
 
 # When called from IDE the first param should contain the link version, otherwise may be nill
 if [ "x$1" != "x" ]; then
--- a/make/windows/create.bat	Fri Feb 24 18:08:59 2012 -0800
+++ b/make/windows/create.bat	Mon Feb 27 13:10:13 2012 +0100
@@ -37,10 +37,10 @@
 REM that "grep" be accessible on the PATH. An MKS install does this.
 REM 
 
-cl 2>NUL >NUL
-if %errorlevel% == 0 goto nexttest
-echo Make sure cl.exe is in your PATH before running this script.
-goto end
+rem cl 2>NUL >NUL
+rem if %errorlevel% == 0 goto nexttest
+rem echo Make sure cl.exe is in your PATH before running this script.
+rem goto end
 
 :nexttest
 grep -V 2>NUL >NUL
@@ -52,6 +52,8 @@
 :testit
 cl 2>&1 | grep "x64" >NUL
 if %errorlevel% == 0 goto amd64
+cl 2>&1 | grep "x64" >NUL
+if %errorlevel% == 0 goto amd64
 set ARCH=x86
 set BUILDARCH=i486
 set Platform_arch=x86
@@ -148,7 +150,7 @@
 
 REM This is now safe to do.
 :copyfiles
-for /D %%i in (compiler1, compiler2, tiered, core, kernel) do (
+for /D %%i in (graal, compiler1, compiler2, tiered, core, kernel) do (
 if NOT EXIST %HotSpotBuildSpace%\%%i\generated mkdir %HotSpotBuildSpace%\%%i\generated
 copy %HotSpotWorkSpace%\make\windows\projectfiles\%%i\* %HotSpotBuildSpace%\%%i\generated > NUL
 )
@@ -156,7 +158,7 @@
 REM force regneration of ProjectFile
 if exist %ProjectFile% del %ProjectFile%
 
-for /D %%i in (compiler1, compiler2, tiered, core, kernel) do (
+for /D %%i in (graal, compiler1, compiler2, tiered, core, kernel) do (
 echo -- %%i --
 echo # Generated file!                                                        >    %HotSpotBuildSpace%\%%i\local.make
 echo # Changing a variable below and then deleting %ProjectFile% will cause  >>    %HotSpotBuildSpace%\%%i\local.make
--- a/make/windows/makefiles/projectcreator.make	Fri Feb 24 18:08:59 2012 -0800
+++ b/make/windows/makefiles/projectcreator.make	Mon Feb 27 13:10:13 2012 +0100
@@ -211,6 +211,14 @@
 $(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=compiler1)
 
 ##################################################
+# Graal compiler specific options
+##################################################
+ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \
+ -define_graal COMPILER1 \
+ -define_graal GRAAL \
+$(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=graal)
+
+##################################################
 # Server(C2) compiler specific options
 ##################################################
 #NOTE! This list must be kept in sync with GENERATED_NAMES in adlc.make.
--- a/make/windows/makefiles/vm.make	Fri Feb 24 18:08:59 2012 -0800
+++ b/make/windows/makefiles/vm.make	Mon Feb 27 13:10:13 2012 +0100
@@ -60,6 +60,10 @@
 CXX_FLAGS=$(CXX_FLAGS) /D "COMPILER1" /D "COMPILER2"
 !endif
 
+!if "$(Variant)" == "graal"
+CPP_FLAGS=$(CPP_FLAGS) /D "COMPILER1" /D "GRAAL"
+!endif
+
 !if "$(BUILDARCH)" == "i486"
 HOTSPOT_LIB_ARCH=i386
 !else
@@ -157,6 +161,7 @@
 VM_PATH=$(VM_PATH);../generated/adfiles
 VM_PATH=$(VM_PATH);../generated/jvmtifiles
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/c1
+VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/graal
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/compiler
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/code
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/interpreter
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/windows/projectfiles/graal/Makefile	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 1999, 2010, 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.
+#  
+#
+
+!include ../local.make
+
+!include $(HOTSPOTWORKSPACE)/make/windows/projectfiles/common/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/windows/projectfiles/graal/vm.def	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,7 @@
+;
+; This .DEF file is a placeholder for one which is automatically
+; generated during the build process. See
+; make\windows\build_vm_def.sh and
+; make\windows\makefiles\projectcreator.make (esp. the "-prelink"
+; options).
+;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/windows/projectfiles/graal/vm.dsw	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "vm"=.\vm.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mx.cmd	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+python mxtool/mx.py %*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mx.sh	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+mxtool/mx
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mx/.project	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>mx</name>
+	<comment></comment>
+	<projects>
+		<project>mxtool</project>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.python.pydev.PyDevBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.python.pydev.pythonNature</nature>
+	</natures>
+</projectDescription>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mx/.pydevproject	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?eclipse-pydev version="1.0"?>
+
+<pydev_project>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
+<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
+<path>/mx</path>
+</pydev_pathproperty>
+<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
+<path>/mxtool</path>
+</pydev_pathproperty>
+
+</pydev_project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mx/commands.py	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,899 @@
+#
+# commands.py - the GraalVM specific commands
+#
+# ----------------------------------------------------------------------------------------------------
+#
+# Copyright (c) 2007, 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.
+#
+# ----------------------------------------------------------------------------------------------------
+
+import os, sys, shutil, zipfile, tempfile, re, time, datetime, platform, subprocess, multiprocessing
+from os.path import join, exists, dirname, basename
+from argparse import ArgumentParser, REMAINDER
+import mx
+import sanitycheck
+import json
+
+_graal_home = dirname(dirname(__file__))
+
+""" Used to distinguish an exported GraalVM (see 'mx export'). """
+_vmSourcesAvailable = exists(join(_graal_home, 'make')) and exists(join(_graal_home, 'src')) 
+
+""" The VM that will be run by the 'vm' command: graal(default), client or server.
+    This can be set via the global '--vm' option. """
+_vm = 'graal'
+
+""" The VM build that will be run by the 'vm' command: product(default), fastdebug or debug.
+    This can be set via the global '--fastdebug' and '--debug' options. """
+_vmbuild = 'product'
+
+_jacoco = False
+
+_jacocoExcludes = ['com.oracle.max.graal.hotspot.snippets.ArrayCopySnippets',
+                   'com.oracle.max.graal.snippets.DoubleSnippets',
+                   'com.oracle.max.graal.snippets.FloatSnippets',
+                   'com.oracle.max.graal.snippets.MathSnippetsX86',
+                   'com.oracle.max.graal.snippets.NodeClassSnippets',
+                   'com.oracle.max.graal.hotspot.snippets.SystemSnippets',
+                   'com.oracle.max.graal.hotspot.snippets.UnsafeSnippets']
+
+_copyrightTemplate = """/*
+ * Copyright (c) {0}, 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.
+ */
+ 
+"""
+
+def clean(args):
+    """cleans the GraalVM source tree"""
+    opts = mx.clean(args, parser=ArgumentParser(prog='mx clean'))
+    if opts.native:
+        os.environ.update(ARCH_DATA_MODEL='64', LANG='C', HOTSPOT_BUILD_JOBS='16')
+        mx.run([mx.gmake_cmd(), 'clean'], cwd=join(_graal_home, 'make'))
+
+def copyrightcheck(args):
+    """run copyright check on the Mercurial controlled source files"""
+    res = mx.run_java(['-cp', mx.classpath('com.oracle.max.base', resolve=False), 'com.sun.max.tools.CheckCopyright', '-cfp=' + join(mx.project('com.oracle.max.base').dir, '.copyright.regex')] + args)
+    mx.log("copyright check result = " + str(res))
+    return res
+
+def export(args):
+    """create a GraalVM zip file for distribution"""
+    
+    parser = ArgumentParser(prog='mx export');
+    parser.add_argument('--omit-vm-build', action='store_false', dest='vmbuild', help='omit VM build step')
+    parser.add_argument('--omit-dist-init', action='store_false', dest='distInit', help='omit class files and IDE configurations from distribution')
+    parser.add_argument('zipfile', nargs=REMAINDER, metavar='zipfile')
+
+    args = parser.parse_args(args)
+    
+    tmp = tempfile.mkdtemp(prefix='tmp', dir=_graal_home)
+    if args.vmbuild:
+        # Make sure the product VM binary is up to date
+        build(['product'])
+        
+    mx.log('Copying Java sources and mx files...')
+    mx.run(('hg archive -I graal -I mx -I mxtool -I mx.sh ' + tmp).split())
+    
+    # Copy the GraalVM JDK
+    mx.log('Copying GraalVM JDK...')
+    src = _jdk()
+    dst = join(tmp, basename(src))
+    shutil.copytree(src, dst)
+    zfName = join(_graal_home, 'graalvm-' + mx.get_os() + '.zip')
+    zf = zipfile.ZipFile(zfName, 'w')
+    for root, _, files in os.walk(tmp):
+        for f in files:
+            name = join(root, f)
+            arcname = name[len(tmp) + 1:]
+            zf.write(join(tmp, name), arcname)
+
+    # create class files and IDE configurations
+    if args.distInit:
+        mx.log('Creating class files...')
+        mx.run('mx build'.split(), cwd=tmp)
+        mx.log('Creating IDE configurations...')
+        mx.run('mx ideinit'.split(), cwd=tmp)
+        
+    # clean up temp directory
+    mx.log('Cleaning up...')
+    shutil.rmtree(tmp)
+    
+    mx.log('Created distribution in ' + zfName)
+
+def example(args):
+    """run some or all Graal examples"""
+    examples = {
+        'safeadd': ['com.oracle.max.graal.examples.safeadd', 'com.oracle.max.graal.examples.safeadd.Main'],
+        'vectorlib': ['com.oracle.max.graal.examples.vectorlib', 'com.oracle.max.graal.examples.vectorlib.Main'],
+    }
+
+    def run_example(verbose, project, mainClass):
+        cp = mx.classpath(project)
+        sharedArgs = ['-Xcomp', '-XX:CompileOnly=Main', mainClass]
+        
+        res = []
+        mx.log("=== Server VM ===")
+        printArg = '-XX:+PrintCompilation' if verbose else '-XX:-PrintCompilation'
+        res.append(vm(['-cp', cp, printArg] + sharedArgs, vm='server'))
+        mx.log("=== Graal VM ===")
+        printArg = '-G:+PrintCompilation' if verbose else '-G:-PrintCompilation'
+        res.append(vm(['-cp', cp, printArg, '-G:-Extend', '-G:-Inline'] + sharedArgs))
+        mx.log("=== Graal VM with extensions ===")
+        res.append(vm(['-cp', cp, printArg, '-G:+Extend', '-G:-Inline'] + sharedArgs))
+        
+        if len([x for x in res if x != 0]) != 0:
+            return 1
+        return 0
+
+    verbose = False
+    if '-v' in args:
+        verbose = True
+        args = [a for a in args if a != '-v']
+
+    if len(args) == 0:
+        args = examples.keys()
+    for a in args:
+        config = examples.get(a)
+        if config is None:
+            mx.log('unknown example: ' + a + '  {available examples = ' + str(examples.keys()) + '}')
+        else:
+            mx.log('--------- ' + a + ' ------------')
+            project, mainClass = config
+            run_example(verbose, project, mainClass)
+
+def dacapo(args):
+    """run one or all DaCapo benchmarks
+    
+    DaCapo options are distinguished from VM options by a '@' prefix.
+    For example, '@--iterations @5' will pass '--iterations 5' to the
+    DaCapo harness."""
+
+    numTests = {}
+    
+    if len(args) > 0:
+        level = getattr(sanitycheck.SanityCheckLevel, args[0], None)
+        if level is not None:
+            del args[0]
+            for (bench, ns) in sanitycheck.dacapoSanityWarmup.items():
+                if ns[level] > 0:
+                    numTests[bench] = ns[level]
+        else:
+            while len(args) != 0 and args[0][0] not in ['-', '@']:
+                n = 1
+                if args[0].isdigit():
+                    n = int(args[0])
+                    assert len(args) > 1 and args[1][0] not in ['-', '@'] and not args[1].isdigit()
+                    bm = args[1]
+                    del args[0]
+                else:
+                    bm = args[0]
+                
+                del args[0]
+                if bm not in sanitycheck.dacapoSanityWarmup.keys():
+                    mx.abort('unknown benchmark: ' + bm + '\nselect one of: ' + str(sanitycheck.dacapoSanityWarmup.keys()))
+                numTests[bm] = n
+    
+    if len(numTests) is 0:    
+        for bench in sanitycheck.dacapoSanityWarmup.keys():
+            numTests[bench] = 1
+    
+    # Extract DaCapo options
+    dacapoArgs = [(arg[1:]) for arg in args if arg.startswith('@')]
+    
+    # The remainder are VM options 
+    vmOpts = [arg for arg in args if not arg.startswith('@')]
+    
+    failed = []
+    for (test, n) in numTests.items():
+        if not sanitycheck.getDacapo(test, n, dacapoArgs).test('graal', opts=vmOpts):
+            failed.append(test)
+    
+    if len(failed) != 0:
+        mx.abort('DaCapo failures: ' + str(failed))
+    
+
+def scaladacapo(args):
+    """run one or all Scala DaCapo benchmarks
+    
+    Scala DaCapo options are distinguished from VM options by a '@' prefix.
+    For example, '@--iterations @5' will pass '--iterations 5' to the
+    DaCapo harness."""
+
+    numTests = {}
+    
+    if len(args) > 0:
+        level = getattr(sanitycheck.SanityCheckLevel, args[0], None)
+        if level is not None:
+            del args[0]
+            for (bench, ns) in sanitycheck.dacapoScalaSanityWarmup.items():
+                if ns[level] > 0:
+                    numTests[bench] = ns[level]
+        else:
+            while len(args) != 0 and args[0][0] not in ['-', '@']:
+                n = 1
+                if args[0].isdigit():
+                    n = int(args[0])
+                    assert len(args) > 1 and args[1][0] not in ['-', '@'] and not args[1].isdigit()
+                    bm = args[1]
+                    del args[0]
+                else:
+                    bm = args[0]
+                
+                del args[0]
+                if bm not in sanitycheck.dacapoScalaSanityWarmup.keys():
+                    mx.abort('unknown benchmark: ' + bm + '\nselect one of: ' + str(sanitycheck.dacapoScalaSanityWarmup.keys()))
+                numTests[bm] = n
+    
+    if len(numTests) is 0:    
+        for bench in sanitycheck.dacapoScalaSanityWarmup.keys():
+            numTests[bench] = 1
+    
+    # Extract DaCapo options
+    dacapoArgs = [(arg[1:]) for arg in args if arg.startswith('@')]
+    
+    # The remainder are VM options 
+    vmOpts = [arg for arg in args if not arg.startswith('@')]
+    
+    failed = []
+    for (test, n) in numTests.items():
+        if not sanitycheck.getScalaDacapo(test, n, dacapoArgs).test('graal', opts=vmOpts):
+            failed.append(test)
+    
+    if len(failed) != 0:
+        mx.abort('Scala DaCapo failures: ' + str(failed))
+
+def _vmLibDirInJdk(jdk):
+    """
+    Get the directory within a JDK where jvm.cfg file and the server
+    and client subdirectories are located.
+    """
+    if platform.system() == 'Darwin':
+        return join(jdk, 'jre', 'lib')
+    return join(jdk, 'jre', 'lib', 'amd64')
+
+def _jdk(build='product', create=False):
+    """
+    Get the JDK into which Graal is installed, creating it first if necessary.
+    """
+    jdk = join(_graal_home, 'jdk' + mx.java().version, build)
+    jdkContents = ['bin', 'db', 'include', 'jre', 'lib']
+    if mx.get_os() != 'windows':
+        jdkContents.append('man')
+    if create:
+        if not exists(jdk):
+            srcJdk = mx.java().jdk
+            mx.log('Creating ' + jdk + ' from ' + srcJdk)
+            os.makedirs(jdk)
+            for d in jdkContents:
+                src = join(srcJdk, d)
+                dst = join(jdk, d)
+                if not exists(src):
+                    mx.abort('Host JDK directory is missing: ' + src)
+                shutil.copytree(src, dst)
+                
+            # Make a copy of the default VM so that this JDK can be
+            # reliably used as the bootstrap for a HotSpot build.                
+            jvmCfg = join(_vmLibDirInJdk(jdk), 'jvm.cfg')
+            if not exists(jvmCfg):
+                mx.abort(jvmCfg + ' does not exist')
+                
+            lines = []
+            defaultVM = None
+            with open(jvmCfg) as f:
+                for line in f:
+                    if line.startswith('-') and defaultVM is None:
+                        parts = line.split()
+                        assert len(parts) == 2, parts
+                        assert parts[1] == 'KNOWN', parts[1]
+                        defaultVM = parts[0][1:]
+                        lines.append('-' + defaultVM + '0 KNOWN\n')
+                    lines.append(line)
+
+            assert defaultVM is not None, 'Could not find default VM in ' + jvmCfg
+            shutil.copytree(join(_vmLibDirInJdk(jdk), defaultVM), join(_vmLibDirInJdk(jdk), defaultVM + '0'))
+            
+            with open(jvmCfg, 'w') as f:
+                for line in lines:
+                    f.write(line)
+                    
+    else:
+        if not exists(jdk):
+            mx.abort('The ' + build + ' VM has not been created - run \'mx clean; mx build ' + build + '\'')
+    return jdk 
+
+# run a command in the windows SDK Debug Shell
+def _runInDebugShell(cmd, workingDir, logFile=None, findInOutput=None, respondTo={}):
+    newLine = os.linesep
+    STARTTOKEN = 'RUNINDEBUGSHELL_STARTSEQUENCE'
+    ENDTOKEN = 'RUNINDEBUGSHELL_ENDSEQUENCE'
+    
+    winSDK = mx.get_env('WIN_SDK', 'C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\')
+
+    p = subprocess.Popen('cmd.exe /E:ON /V:ON /K ""' + winSDK + '/Bin/SetEnv.cmd" & echo ' + STARTTOKEN + '"', \
+            shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
+    stdout = p.stdout
+    stdin = p.stdin
+    if logFile:
+        log = open(logFile, 'w')
+    ret = False
+    while True:
+        line = stdout.readline().decode()
+        if logFile:
+            log.write(line)
+        line = line.strip()
+        mx.log(line)
+        if line == STARTTOKEN:
+            stdin.write('cd /D ' + workingDir + ' & ' + cmd + ' & echo ' + ENDTOKEN + newLine)
+        for regex in respondTo.keys():
+            match = regex.search(line)
+            if match:
+                stdin.write(respondTo[regex] + newLine)
+        if findInOutput:
+            match = findInOutput.search(line)
+            if match:
+                ret = True
+        if line == ENDTOKEN:
+            break
+    stdin.write('exit' + newLine)
+    if logFile:
+        log.close()
+    return ret
+    
+def build(args, vm=None):
+    """build the VM binary
+    
+    The global '--vm' option selects which VM to build. This command also
+    compiles the Graal classes irrespective of what VM is being built.
+    The optional last argument specifies what build level is to be used
+    for the VM binary."""
+    
+    # Call mx.build to compile the Java sources        
+    opts2 = mx.build(['--source', '1.7'] + args, parser=ArgumentParser(prog='mx build'))
+
+    if not _vmSourcesAvailable or not opts2.native:
+        return
+
+    builds = opts2.remainder
+    if len(builds) == 0:
+        builds = ['product']
+
+    if vm is None:
+        vm = _vm
+        
+    if vm == 'server':
+        buildSuffix = ''
+    elif vm == 'client':
+        buildSuffix = '1'
+    else:
+        assert vm == 'graal', vm
+        buildSuffix = 'graal'
+        
+    for build in builds:
+        jdk = _jdk(build, create=True)
+            
+        vmDir = join(_vmLibDirInJdk(jdk), vm)
+        if not exists(vmDir):
+            mx.log('Creating VM directory in JDK7: ' + vmDir)
+            os.makedirs(vmDir)
+    
+        def filterXusage(line):
+            if not 'Xusage.txt' in line:
+                sys.stderr.write(line + os.linesep)
+                
+        if platform.system() == 'Windows':
+            compilelogfile = _graal_home + '/graalCompile.log'
+            mksHome = mx.get_env('MKS_HOME', 'C:\\cygwin\\bin')
+
+            variant = {'client': 'compiler1', 'server': 'compiler2'}.get(vm, vm)
+            project_config = variant + '_' + build
+            _runInDebugShell('msbuild ' + _graal_home + r'\build\vs-amd64\jvm.vcproj /p:Configuration=' + project_config + ' /target:clean', _graal_home)
+            winCompileCmd = r'set HotSpotMksHome=' + mksHome + r'& set OUT_DIR=' + jdk + r'& set JAVA_HOME=' + jdk + r'& set path=%JAVA_HOME%\bin;%path%;%HotSpotMksHome%& cd /D "' +_graal_home + r'\make\windows"& call create.bat ' + _graal_home
+            print(winCompileCmd)
+            winCompileSuccess = re.compile(r"^Writing \.vcxproj file:")
+            if not _runInDebugShell(winCompileCmd, _graal_home, compilelogfile, winCompileSuccess):
+                mx.log('Error executing create command')
+                return 
+            winBuildCmd = 'msbuild ' + _graal_home + r'\build\vs-amd64\jvm.vcxproj /p:Configuration=' + project_config + ' /p:Platform=x64'
+            winBuildSuccess = re.compile('Build succeeded.')
+            if not _runInDebugShell(winBuildCmd, _graal_home, compilelogfile, winBuildSuccess):
+                mx.log('Error building project')
+                return 
+        else:
+            cpus = multiprocessing.cpu_count()
+            if build == 'debug':
+                build = 'jvmg'
+            env = os.environ
+            env.setdefault('ARCH_DATA_MODEL', '64')
+            env.setdefault('LANG', 'C')
+            env.setdefault('HOTSPOT_BUILD_JOBS', str(cpus))
+            env['ALT_BOOTDIR'] = jdk
+            env.setdefault('INSTALL', 'y')
+            
+            # Clear these 2 variables as having them set can cause very confusing build problems
+            env.pop('LD_LIBRARY_PATH', None)
+            env.pop('CLASSPATH', None)
+            
+            mx.run([mx.gmake_cmd(), build + buildSuffix], cwd=join(_graal_home, 'make'), err=filterXusage)
+        
+        jvmCfg = join(_vmLibDirInJdk(jdk), 'jvm.cfg')
+        found = False
+        if not exists(jvmCfg):
+            mx.abort(jvmCfg + ' does not exist')
+        
+        prefix = '-' + vm
+        vmKnown = prefix + ' KNOWN\n'
+        lines = []
+        with open(jvmCfg) as f:
+            for line in f:
+                if vmKnown in line:
+                    found = True
+                    break
+                if not line.startswith(prefix):
+                    lines.append(line)
+        if not found:
+            mx.log('Appending "' + prefix + ' KNOWN" to ' + jvmCfg)
+            lines.append(vmKnown)
+            with open(jvmCfg, 'w') as f:
+                for line in lines:
+                    f.write(line)
+    
+def vm(args, vm=None, nonZeroIsFatal=True, out=None, err=None, cwd=None, timeout=None, vmbuild=None):
+    """run the VM selected by the '--vm' option"""
+
+    if vm is None:
+        vm = _vm
+        
+    build = vmbuild if vmbuild is not None else _vmbuild if _vmSourcesAvailable else 'product'
+    mx.expand_project_in_args(args)  
+    if mx.java().debug:
+        args = ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000'] + args
+    if _jacoco:
+        jacocoagent = mx.library("JACOCOAGENT", True)
+        agentOptions = {
+                        'append' : 'false',
+                        'bootclasspath' : 'true',
+                        'includes' : 'com.oracle.max.*',
+                        'excludes' : ':'.join(_jacocoExcludes)
+        }
+        args = ['-javaagent:' + jacocoagent.get_path(True) + '=' + ','.join([k + '=' + v for k, v in agentOptions.items()])] + args
+    exe = join(_jdk(build), 'bin', mx.exe_suffix('java'))
+    return mx.run([exe, '-' + vm] + args, nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd, timeout=timeout)
+
+
+# Table of unit tests.
+# Keys are project names, values are package name lists.
+# All source files in the given (project,package) pairs are scanned for lines
+# containing '@Test'. These are then determined to be the classes defining
+# unit tests.
+_unittests = {
+    'com.oracle.max.graal.tests': ['com.oracle.max.graal.compiler.tests'],
+}
+_jtttests = {
+    'com.oracle.max.graal.jtt': ['com.oracle.max.graal.jtt'],
+}
+
+def _add_test_classes(testClassList, searchDir, pkgRoot):
+    pkgDecl = re.compile(r"^package\s+([a-zA-Z_][\w\.]*)\s*;$")
+    for root, _, files in os.walk(searchDir):
+        for name in files:
+            if name.endswith('.java') and name != 'package-info.java':
+                hasTest = False
+                with open(join(root, name)) as f:
+                    pkg = None
+                    for line in f:
+                        if line.startswith("package "):
+                            match = pkgDecl.match(line)
+                            if match:
+                                pkg = match.group(1)
+                        else:
+                            if line.strip().startswith('@Test'):
+                                hasTest = True
+                                break
+                if hasTest:
+                    assert pkg is not None
+                    if pkg.startswith(pkgRoot):
+                        testClassList.append(pkg + '.' + name[:-len('.java')])
+
+def unittest(args):
+    """run the Graal Compiler Unit Tests in the GraalVM
+    
+    If filters are supplied, only tests whose fully qualified name
+    include a filter as a substring are run. Negative filters are
+    those with a '-' prefix. VM args should have a @ prefix."""
+    
+    pos = [a for a in args if a[0] != '-' and a[0] != '@' ]
+    neg = [a[1:] for a in args if a[0] == '-']
+    vmArgs = [a[1:] for a in args if a[0] == '@']
+
+    def containsAny(c, substrings):
+        for s in substrings:
+            if s in c:
+                return True
+        return False
+    
+    for proj in _unittests.iterkeys():
+        p = mx.project(proj)
+        classes = []
+        for pkg in _unittests[proj]:
+            _add_test_classes(classes, join(p.dir, 'src'), pkg)
+    
+        if len(pos) != 0:
+            classes = [c for c in classes if containsAny(c, pos)]
+        if len(neg) != 0:
+            classes = [c for c in classes if not containsAny(c, neg)]
+            
+        vm(['-XX:-BootstrapGraal', '-esa'] + vmArgs + ['-cp', mx.classpath(proj), 'org.junit.runner.JUnitCore'] + classes)
+    
+def jtt(args):
+    """run the Java Tester Tests in the GraalVM
+    
+    If filters are supplied, only tests whose fully qualified name
+    include a filter as a substring are run. Negative filters are
+    those with a '-' prefix. VM args should have a @ prefix."""
+    
+    pos = [a for a in args if a[0] != '-' and a[0] != '@' ]
+    neg = [a[1:] for a in args if a[0] == '-']
+    vmArgs = [a[1:] for a in args if a[0] == '@']
+
+    def containsAny(c, substrings):
+        for s in substrings:
+            if s in c:
+                return True
+        return False
+    
+    for proj in _jtttests.iterkeys():
+        p = mx.project(proj)
+        classes = []
+        for pkg in _jtttests[proj]:
+            _add_test_classes(classes, join(p.dir, 'src'), pkg)
+    
+        if len(pos) != 0:
+            classes = [c for c in classes if containsAny(c, pos)]
+        if len(neg) != 0:
+            classes = [c for c in classes if not containsAny(c, neg)]
+            
+        vm(['-XX:-BootstrapGraal', '-XX:CompileOnly=::test', '-Xcomp', '-esa'] + vmArgs + ['-cp', mx.classpath(proj), 'org.junit.runner.JUnitCore'] + classes)
+    
+def buildvms(args):
+    """build one or more VMs in various configurations"""
+    
+    parser = ArgumentParser(prog='mx buildvms');
+    parser.add_argument('--vms', help='a comma separated list of VMs to build (default: server,client,graal)', default='server,client,graal')
+    parser.add_argument('--builds', help='a comma separated list of build types (default: product,fastdebug,debug)', default='product,fastdebug,debug')
+
+    args = parser.parse_args(args)
+    vms = args.vms.split(',')
+    builds = args.builds.split(',')
+    
+    allStart = time.time()
+    for v in vms:
+        for vmbuild in builds:
+            logFile = join(v + '-' + vmbuild + '.log')
+            log = open(join(_graal_home, logFile), 'wb')
+            start = time.time()
+            mx.log('BEGIN: ' + v + '-' + vmbuild + '\t(see: ' + logFile + ')')
+            # Run as subprocess so that output can be directed to a file
+            subprocess.check_call([sys.executable, '-u', join('mxtool', 'mx.py'), '--vm', v, 'build', vmbuild], cwd=_graal_home, stdout=log, stderr=subprocess.STDOUT)
+            duration = datetime.timedelta(seconds=time.time() - start)
+            mx.log('END:   ' + v + '-' + vmbuild + '\t[' + str(duration) + ']')
+    allDuration = datetime.timedelta(seconds=time.time() - allStart)
+    mx.log('TOTAL TIME:   ' + '[' + str(allDuration) + ']')
+
+def gate(args):
+    """run the tests used to validate a push
+
+    If this command exits with a 0 exit code, then the source code is in
+    a state that would be accepted for integration into the main repository."""
+    
+    class Task:
+        def __init__(self, title):
+            self.start = time.time()
+            self.title = title
+            self.end = None
+            self.duration = None
+            mx.log(time.strftime('gate: %d %b %Y %H:%M:%S: BEGIN: ') + title)
+        def stop(self):
+            self.end = time.time()
+            self.duration = datetime.timedelta(seconds=self.end - self.start)
+            mx.log(time.strftime('gate: %d %b %Y %H:%M:%S: END:   ') + self.title + ' [' + str(self.duration) + ']')
+            return self
+        def abort(self, codeOrMessage):
+            self.end = time.time()
+            self.duration = datetime.timedelta(seconds=self.end - self.start)
+            mx.log(time.strftime('gate: %d %b %Y %H:%M:%S: ABORT: ') + self.title + ' [' + str(self.duration) + ']')
+            mx.abort(codeOrMessage)
+            return self
+             
+    parser = ArgumentParser(prog='mx gate');
+    parser.add_argument('-n', '--omit-native-build', action='store_false', dest='buildNative', help='omit cleaning and building native code')
+    parser.add_argument('-g', '--only-build-graalvm', action='store_false', dest='buildNonGraal', help='only build the Graal VM')
+
+    args = parser.parse_args(args)
+
+    tasks = []             
+    total = Task('Gate')
+    try:
+        
+        t = Task('Clean')
+        clean([] if args.buildNative else ['--no-native'])
+        tasks.append(t.stop())
+        
+        t = Task('Checkstyle')
+        if mx.checkstyle([]) != 0:
+            t.abort('Checkstyle warnings were found')
+        tasks.append(t.stop())
+    
+        t = Task('Canonicalization Check')
+        mx.log(time.strftime('%d %b %Y %H:%M:%S - Ensuring mx/projects files are canonicalized...'))
+        if mx.canonicalizeprojects([]) != 0:
+            t.abort('Rerun "mx canonicalizeprojects" and check-in the modified mx/projects files.')
+        tasks.append(t.stop())
+    
+        t = Task('BuildJava')
+        build(['--no-native'])
+        tasks.append(t.stop())
+    
+        t = Task('CleanAndBuildGraalVisualizer')
+        mx.run(['ant', '-f', join(_graal_home, 'visualizer', 'build.xml'), '-q', 'clean', 'build'])
+        tasks.append(t.stop())
+
+        # Prevent Graal modifications from breaking the standard builds
+        if args.buildNative and args.buildNonGraal:
+            t = Task('BuildHotSpotVarieties')
+            buildvms(['--vms', 'client,server', '--builds', 'fastdebug,product'])
+            tasks.append(t.stop())
+        
+        for vmbuild in ['fastdebug', 'product']:
+            global _vmbuild
+            _vmbuild = vmbuild
+            
+            if args.buildNative:
+                t = Task('BuildHotSpotGraal:' + vmbuild)
+                buildvms(['--vms', 'graal', '--builds', vmbuild])
+                tasks.append(t.stop())
+            
+            t = Task('BootstrapWithSystemAssertions:' + vmbuild)
+            vm(['-esa', '-version'])
+            tasks.append(t.stop())
+            
+            t = Task('UnitTests:' + vmbuild)
+            unittest([])
+            tasks.append(t.stop())
+            
+            t = Task('JavaTesterTests:' + vmbuild)
+            jtt([])
+            tasks.append(t.stop())
+            
+            for test in sanitycheck.getDacapos(level=sanitycheck.SanityCheckLevel.Gate, gateBuildLevel=vmbuild):
+                t = Task(str(test) + ':' + vmbuild)
+                if not test.test('graal'):
+                    t.abort(test.group + ' ' + test.name + ' Failed')
+                tasks.append(t.stop())
+    except KeyboardInterrupt:
+        total.abort(1)
+    
+    except BaseException as e:
+        import traceback
+        traceback.print_exc()
+        total.abort(str(e))
+
+    total.stop()
+    
+    mx.log('Gate task times:')
+    for t in tasks:
+        mx.log('  ' + str(t.duration) + '\t' + t.title)
+    mx.log('  =======')
+    mx.log('  ' + str(total.duration))
+
+def gv(args):
+    """run the Graal Visualizer"""
+    mx.run(['ant', '-f', join(_graal_home, 'visualizer', 'build.xml'), '-q', 'run'])
+    
+def bench(args):
+    """run benchmarks and parse their output for results
+
+    Results are JSON formated : {group : {benchmark : score}}."""
+    resultFile = None
+    if '-resultfile' in args:
+        index = args.index('-resultfile')
+        if index + 1 < len(args):
+            resultFile = args[index + 1]
+            del args[index]
+            del args[index]
+        else:
+            mx.abort('-resultfile must be followed by a file name')
+    vm = _vm
+    if len(args) is 0:
+        args += ['all']
+
+    results = {}
+    benchmarks = []
+    #DaCapo
+    if ('dacapo' in args or 'all' in args):
+        benchmarks += sanitycheck.getDacapos(level=sanitycheck.SanityCheckLevel.Benchmark)
+    else:
+        dacapos = [a[7:] for a in args if a.startswith('dacapo:')]
+        for dacapo in dacapos:
+            if dacapo not in sanitycheck.dacapoSanityWarmup.keys():
+                mx.abort('Unknown dacapo : ' + dacapo)
+            benchmarks += [sanitycheck.getDacapo(dacapo, sanitycheck.dacapoSanityWarmup[dacapo][sanitycheck.SanityCheckLevel.Benchmark])]
+    
+    if ('scaladacapo' in args or 'all' in args):
+        benchmarks += sanitycheck.getScalaDacapos(level=sanitycheck.SanityCheckLevel.Benchmark)
+    else:
+        dacapos = [a[7:] for a in args if a.startswith('scaladacapo:')]
+        for dacapo in dacapos:
+            if dacapo not in sanitycheck.dacapoScalaSanityWarmup.keys():
+                mx.abort('Unknown dacapo : ' + dacapo)
+            benchmarks += [sanitycheck.getScalaDacapo(dacapo, sanitycheck.dacapoScalaSanityWarmup[dacapo][sanitycheck.SanityCheckLevel.Benchmark])]
+        
+    #Bootstrap
+    if ('bootstrap' in args or 'all' in args):
+        benchmarks += sanitycheck.getBootstraps()
+    #SPECjvm2008
+    if ('specjvm2008' in args or 'all' in args):
+        benchmarks += [sanitycheck.getSPECjvm2008([], True, 120, 120)]
+    else:
+        specjvms = [a[12:] for a in args if a.startswith('specjvm2008:')]
+        for specjvm in specjvms:
+            benchmarks += [sanitycheck.getSPECjvm2008([specjvm], True, 120, 120)]
+    
+    for test in benchmarks:
+        if not results.has_key(test.group):
+            results[test.group] = {}
+        results[test.group].update(test.bench(vm))
+    mx.log(json.dumps(results))
+    if resultFile:
+        with open(resultFile, 'w') as f:
+            f.write(json.dumps(results))
+    
+def specjvm2008(args):
+    """run one or all SPECjvm2008 benchmarks
+    
+    All options begining with - will be passed to the vm except for -ikv -wt and -it.
+    Other options are supposed to be benchmark names and will be passed to SPECjvm2008."""
+    benchArgs = [a for a in args if a[0] != '-']
+    vmArgs = [a for a in args if a[0] == '-']
+    wt = None
+    it = None
+    skipValid = False
+    if '-ikv' in vmArgs:
+        skipValid = True
+        vmArgs.remove('-ikv')
+    if '-wt' in vmArgs:
+        wtIdx = args.index('-wt')
+        try:
+            wt = int(args[wtIdx+1])
+        except:
+            mx.abort('-wt (Warmup time) needs a numeric value (seconds)')
+        vmArgs.remove('-wt')
+        benchArgs.remove(args[wtIdx+1])
+    if '-it' in vmArgs:
+        itIdx = args.index('-it')
+        try:
+            it = int(args[itIdx+1])
+        except:
+            mx.abort('-it (Iteration time) needs a numeric value (seconds)')
+        vmArgs.remove('-it')
+        benchArgs.remove(args[itIdx+1])
+    sanitycheck.getSPECjvm2008(benchArgs, skipValid, wt, it).bench('graal', opts=vmArgs)
+    
+def hsdis(args):
+    """install the hsdis library
+
+    This is needed to support HotSpot's assembly dumping features.
+    By default it installs the Intel syntax version, use the 'att' argument to install AT&T syntax."""
+    flavor = 'intel'
+    if 'att' in args:
+        flavor = 'att'
+    build = _vmbuild if _vmSourcesAvailable else 'product'
+    lib = mx.lib_suffix('hsdis-amd64')
+    path = join(_vmLibDirInJdk(_jdk(build)), lib)
+    mx.download(path, ['http://lafo.ssw.uni-linz.ac.at/hsdis/' + flavor + "/" + lib])
+    
+def jacocoreport(args):
+    """creates a JaCoCo coverage report
+
+    Creates the report from the 'jacoco.exec' file in the current directory.
+    Default output directory is 'coverage', but an alternative can be provided as an argument."""
+    jacocoreport = mx.library("JACOCOREPORT", True)
+    out = 'coverage'
+    if len(args) == 1:
+        out = args[0]
+    elif len(args) > 1:
+        mx.abort('jacocoreport takes only one argument : an output directory')
+    mx.run_java(['-jar', jacocoreport.get_path(True), '-in', 'jacoco.exec', '-g', join(_graal_home, 'graal'), out])
+    
+def mx_init():
+    _vmbuild = 'product'
+    commands = {
+        'build': [build, '[-options]'],
+        'buildvms': [buildvms, '[-options]'],
+        'clean': [clean, ''],
+        'copyrightcheck': [copyrightcheck, ''],
+        'hsdis': [hsdis, '[att]'],
+        'dacapo': [dacapo, '[[n] benchmark] [VM options|@DaCapo options]'],
+        'scaladacapo': [scaladacapo, '[[n] benchmark] [VM options|@Scala DaCapo options]'],
+        'specjvm2008': [specjvm2008, '[VM options|@specjvm2008 options]'],
+        'example': [example, '[-v] example names...'],
+        'gate' : [gate, '[-options]'],
+        'gv' : [gv, ''],
+        'bench' : [bench, '[-resultfile file] [all(default)|dacapo|specjvm2008|bootstrap]'],
+        'unittest' : [unittest, '[filters...]'],
+        'jtt' : [jtt, '[filters...]'],
+        'jacocoreport' : [jacocoreport, '[output directory]'],
+        'vm': [vm, '[-options] class [args...]']
+    }
+    
+    mx.add_argument('--jacoco', action='store_true', dest='jacoco', help='instruments com.oracle.max.* classes using JaCoCo')
+
+    if (_vmSourcesAvailable):
+        mx.add_argument('--vm', action='store', dest='vm', default='graal', choices=['graal', 'server', 'client'], help='the VM to build/run (default: graal)')
+        mx.add_argument('--product', action='store_const', dest='vmbuild', const='product', help='select the product build of the VM')
+        mx.add_argument('--debug', action='store_const', dest='vmbuild', const='debug', help='select the debug build of the VM')
+        mx.add_argument('--fastdebug', action='store_const', dest='vmbuild', const='fastdebug', help='select the fast debug build of the VM')
+        
+        commands.update({
+            'export': [export, '[-options] [zipfile]'],
+            'build': [build, '[-options] [product|debug|fastdebug]...']
+        })
+    
+    mx.commands.update(commands)
+
+def mx_post_parse_cmd_line(opts):
+    version = mx.java().version
+    parts = version.split('.')
+    assert len(parts) >= 2
+    assert parts[0] == '1'
+    major = int(parts[1])
+    if not major >= 7:
+        mx.abort('Requires Java version 1.7 or greater, got version ' + version)
+    
+    if (_vmSourcesAvailable):
+        if hasattr(opts, 'vm') and opts.vm is not None:
+            global _vm
+            _vm = opts.vm
+        if hasattr(opts, 'vmbuild') and opts.vmbuild is not None:
+            global _vmbuild
+            _vmbuild = opts.vmbuild
+    if opts.jacoco:
+        global _jacoco
+        _jacoco = True
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mx/eclipse-settings/org.eclipse.jdt.core.prefs	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,384 @@
+#Sun Dec 18 01:19:17 CET 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=ignore
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=ignore
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=error
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=disabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=error
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unsafeTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.processAnnotations=disabled
+org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled
+org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL
+org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=1
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
+org.eclipse.jdt.core.formatter.comment.line_length=120
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=4
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=4
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
+org.eclipse.jdt.core.formatter.indentation.size=8
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=true
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=200
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=true
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=false
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mx/eclipse-settings/org.eclipse.jdt.ui.prefs	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,121 @@
+cleanup.add_default_serial_version_id=false
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=false
+cleanup.add_missing_deprecated_annotations=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=false
+cleanup.add_serial_version_id=false
+cleanup.always_use_blocks=false
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=false
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.format_source_code=false
+cleanup.make_local_variable_final=false
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_variable_declarations_final=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=false
+cleanup.organize_imports=false
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=false
+cleanup.qualify_static_member_accesses_with_declaring_class=false
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=false
+cleanup.remove_trailing_whitespaces=false
+cleanup.remove_trailing_whitespaces_all=false
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=false
+cleanup.remove_unnecessary_nls_tags=false
+cleanup.remove_unused_imports=false
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=false
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=false
+cleanup.remove_unused_private_types=false
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.use_blocks=false
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_parentheses_in_expressions=false
+cleanup.use_this_for_non_static_field_access=false
+cleanup.use_this_for_non_static_field_access_only_if_necessary=false
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=false
+cleanup_profile=_CleanUpAgitarTests
+cleanup_settings_version=2
+comment_clear_blank_lines=false
+comment_format_comments=true
+comment_format_header=false
+comment_format_html=true
+comment_format_source_code=true
+comment_indent_parameter_description=true
+comment_indent_root_tags=true
+comment_line_length=120
+comment_new_line_for_parameter=true
+comment_separate_root_tags=true
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_MaxineJavaCodeStyle
+formatter_settings_version=11
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=java;javax;org;com;
+org.eclipse.jdt.ui.javadoc=false
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.ondemandthreshold=0
+org.eclipse.jdt.ui.overrideannotation=true
+org.eclipse.jdt.ui.staticondemandthreshold=0
+sp_cleanup.add_default_serial_version_id=false
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=false
+sp_cleanup.add_missing_deprecated_annotations=false
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=false
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=false
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=false
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=false
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=false
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=false
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=false
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=false
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=false
+sp_cleanup.remove_unused_private_types=false
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=false
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=false
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mx/outputparser.py	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,91 @@
+# ----------------------------------------------------------------------------------------------------
+#
+# Copyright (c) 2007, 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.
+#
+# ----------------------------------------------------------------------------------------------------
+
+import mx
+import commands
+import subprocess
+
+class OutputParser:
+    
+    def __init__(self, nonZeroIsFatal=True):
+        self.matchers = []
+        self.nonZeroIsFatal = nonZeroIsFatal
+        
+    def addMatcher(self, matcher):
+        self.matchers.append(matcher)
+    
+    def parse(self, vm, cmd, cwd=None, vmbuild=None):
+        ret = []
+        
+        def parseLine(line):
+            anyMatch = False
+            for matcher in self.matchers:
+                parsed = matcher.parse(line.strip())
+                if parsed:
+                    anyMatch = True
+                    if len(ret) is 0 or (matcher.startNewLine and len(ret[len(ret)-1]) > 0):
+                        ret.append({})
+                    ret[len(ret)-1].update(parsed)
+            if anyMatch :
+                mx.log('>' + line.rstrip())
+            else :
+                mx.log( line.rstrip())
+        
+        retcode = commands.vm(cmd, vm, nonZeroIsFatal=self.nonZeroIsFatal, out=parseLine, err=subprocess.STDOUT, cwd=cwd, vmbuild=vmbuild)
+        return {'parsed' : ret, 'retcode' : retcode}
+
+class Matcher:
+    
+    def __init__(self, regex, valuesToParse, startNewLine=False):
+        assert isinstance(valuesToParse, dict)
+        self.regex = regex
+        self.valuesToParse = valuesToParse
+        self.startNewLine = startNewLine
+        
+    def parse(self, line):
+        match = self.regex.search(line)
+        if not match:
+            return False
+        ret = {}
+        for key, value in self.valuesToParse.items():
+            ret[self.parsestr(match, key)] = self.parsestr(match, value)
+        return ret
+        
+    def parsestr(self, match, key):
+        if isinstance(key, tuple):
+            if len(key) != 2:
+                raise Exception('Tuple arguments must have a length of 2')
+            tup1, tup2 = key
+            # check if key is a function
+            if hasattr(tup1, '__call__'):
+                return tup1(self.parsestr(match, tup2))
+            elif hasattr(tup2, '__call__'):
+                return tup2(self.parsestr(match, tup1))
+            else:
+                raise Exception('Tuple must contain a function pointer')
+        elif key.startswith('const:'):
+            return key.split(':')[1]
+        else:
+            return match.group(key)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mx/projects	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,145 @@
+# Library specification format:
+#
+#     library@<name>@<prop>=<value>
+#
+# Library properties (* = required):
+#
+#    *path: the file system path for the library to appear on a class path
+#     urls: a comma seperated list of URLs from which the library can be downloaded
+#     optional: if "true" then this library will be omitted from a class path if it doesn't exist on the file system and no URLs are specified
+#     eclipse.container: the name of the Eclipse library container corresponding to the library
+#
+# Project specification format:
+#
+#     project@<name>@<prop>=<value>
+#
+# The name of a project also denotes the directory it is in.
+#
+# Project properties:
+#
+#    *sourceDirs: a comma separated list of source directoriy names (relative to the project directory)
+#     dependencies: a comma separated list of the libraries and project the project depends upon (transitive dependencies may be omitted)
+#     eclipse.output: the output directory name (relative to the project directory)
+#     checkstyle: the project whose Checkstyle configuration (i.e. <project>/.checkstyle_checks.xml) is used
+#
+# The eclipse.* properties are only used when generating Eclipse project configuration files.
+#
+# Values can use environment variables with the syntax used in a Bash shell script.
+#
+
+
+library@JDK_TOOLS@path=${JAVA_HOME}/lib/tools.jar
+library@JDK_TOOLS@optional=true
+
+library@JUNIT@path=lib/junit-4.8.jar
+library@JUNIT@urls=http://repo1.maven.org/maven2/junit/junit/4.8/junit-4.8.jar
+library@JUNIT@eclipse.container=org.eclipse.jdt.junit.JUNIT_CONTAINER/4
+
+library@CHECKSTYLE@path=lib/checkstyle-5.5-all.jar
+library@CHECKSTYLE@urls=jar:http://sourceforge.net/projects/checkstyle/files/checkstyle/5.5/checkstyle-5.5-bin.zip/download!/checkstyle-5.5/checkstyle-5.5-all.jar
+
+library@DACAPO@path=lib/dacapo-9.12-bach.jar
+library@DACAPO@urls=http://dfn.dl.sourceforge.net/project/dacapobench/9.12-bach/dacapo-9.12-bach.jar
+
+library@JACOCOAGENT@path=lib/jacocoagent.jar
+library@JACOCOAGENT@urls=http://lafo.ssw.uni-linz.ac.at/jacoco/jacocoagent.jar
+
+library@JACOCOREPORT@path=lib/jacocoreport.jar
+library@JACOCOREPORT@urls=http://lafo.ssw.uni-linz.ac.at/jacoco/jacocoreport.jar
+
+library@DACAPO_SCALA@path=lib/dacapo-scala-0.1.0.jar
+library@DACAPO_SCALA@urls=http://repo.scalabench.org/snapshots/org/scalabench/benchmarks/scala-benchmark-suite/0.1.0-SNAPSHOT/scala-benchmark-suite-0.1.0-20110908.085753-2.jar
+
+# graal.hotspot
+project@com.oracle.max.graal.hotspot@subDir=graal
+project@com.oracle.max.graal.hotspot@sourceDirs=src
+project@com.oracle.max.graal.hotspot@dependencies=com.oracle.max.graal.snippets
+project@com.oracle.max.graal.hotspot@checkstyle=com.oracle.max.graal.graph
+
+# graal.graph
+project@com.oracle.max.graal.graph@subDir=graal
+project@com.oracle.max.graal.graph@sourceDirs=src
+project@com.oracle.max.graal.graph@dependencies=com.oracle.max.graal.debug,JUNIT
+
+# graal.debug
+project@com.oracle.max.graal.debug@subDir=graal
+project@com.oracle.max.graal.debug@sourceDirs=src
+project@com.oracle.max.graal.debug@checkstyle=com.oracle.max.graal.graph
+
+# graal.lir
+project@com.oracle.max.graal.lir@subDir=graal
+project@com.oracle.max.graal.lir@sourceDirs=src
+project@com.oracle.max.graal.lir@dependencies=com.oracle.max.asm,com.oracle.max.graal.nodes
+project@com.oracle.max.graal.lir@checkstyle=com.oracle.max.graal.graph
+
+# graal.lir.amd64
+project@com.oracle.max.graal.lir.amd64@subDir=graal
+project@com.oracle.max.graal.lir.amd64@sourceDirs=src
+project@com.oracle.max.graal.lir.amd64@dependencies=com.oracle.max.graal.lir
+project@com.oracle.max.graal.lir.amd64@checkstyle=com.oracle.max.graal.graph
+
+# graal.alloc
+project@com.oracle.max.graal.alloc@subDir=graal
+project@com.oracle.max.graal.alloc@sourceDirs=src
+project@com.oracle.max.graal.alloc@dependencies=com.oracle.max.graal.lir
+project@com.oracle.max.graal.alloc@checkstyle=com.oracle.max.graal.graph
+
+# graal.snippets
+project@com.oracle.max.graal.snippets@subDir=graal
+project@com.oracle.max.graal.snippets@sourceDirs=src,test
+project@com.oracle.max.graal.snippets@dependencies=com.oracle.max.graal.printer
+project@com.oracle.max.graal.snippets@checkstyle=com.oracle.max.graal.graph
+
+# graal.nodes
+project@com.oracle.max.graal.nodes@subDir=graal
+project@com.oracle.max.graal.nodes@sourceDirs=src,test
+project@com.oracle.max.graal.nodes@dependencies=com.oracle.max.cri,com.oracle.max.graal.graph
+project@com.oracle.max.graal.nodes@checkstyle=com.oracle.max.graal.graph
+
+# graal.compiler
+project@com.oracle.max.graal.compiler@subDir=graal
+project@com.oracle.max.graal.compiler@sourceDirs=src
+project@com.oracle.max.graal.compiler@dependencies=com.oracle.max.graal.lir.amd64,com.oracle.max.graal.alloc
+project@com.oracle.max.graal.compiler@checkstyle=com.oracle.max.graal.graph
+
+# graal.java
+project@com.oracle.max.graal.java@subDir=graal
+project@com.oracle.max.graal.java@sourceDirs=src
+project@com.oracle.max.graal.java@dependencies=com.oracle.max.graal.compiler
+project@com.oracle.max.graal.java@checkstyle=com.oracle.max.graal.graph
+
+# graal.printer
+project@com.oracle.max.graal.printer@subDir=graal
+project@com.oracle.max.graal.printer@sourceDirs=src
+project@com.oracle.max.graal.printer@dependencies=com.oracle.max.graal.java
+project@com.oracle.max.graal.printer@checkstyle=com.oracle.max.graal.graph
+
+# graal.test
+project@com.oracle.max.graal.tests@subDir=graal
+project@com.oracle.max.graal.tests@sourceDirs=src
+project@com.oracle.max.graal.tests@dependencies=com.oracle.max.graal.printer
+project@com.oracle.max.graal.tests@checkstyle=com.oracle.max.graal.graph
+
+# graal.jtt
+project@com.oracle.max.graal.jtt@subDir=graal
+project@com.oracle.max.graal.jtt@sourceDirs=src
+project@com.oracle.max.graal.jtt@dependencies=JUNIT
+project@com.oracle.max.graal.jtt@checkstyle=com.oracle.max.graal.graph
+
+# max.asm
+project@com.oracle.max.asm@subDir=graal
+project@com.oracle.max.asm@sourceDirs=src
+project@com.oracle.max.asm@dependencies=com.oracle.max.criutils
+project@com.oracle.max.asm@checkstyle=com.oracle.max.graal.graph
+
+# max.cri
+project@com.oracle.max.cri@subDir=graal
+project@com.oracle.max.cri@sourceDirs=src
+project@com.oracle.max.cri@dependencies=
+project@com.oracle.max.cri@checkstyle=com.oracle.max.graal.graph
+
+# max.criutils
+project@com.oracle.max.criutils@subDir=graal
+project@com.oracle.max.criutils@sourceDirs=src
+project@com.oracle.max.criutils@dependencies=com.oracle.max.cri
+project@com.oracle.max.criutils@checkstyle=com.oracle.max.graal.graph
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mx/sanitycheck.py	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,281 @@
+# ----------------------------------------------------------------------------------------------------
+#
+# Copyright (c) 2007, 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.
+#
+# ----------------------------------------------------------------------------------------------------
+
+from outputparser import OutputParser, Matcher
+import re
+import mx
+import os
+from os.path import isfile, join, exists
+
+dacapoSanityWarmup = {
+    'avrora':     [0, 0,  3,  6, 13],
+    'batik':      [0, 0,  5,  5, 20],
+    'eclipse':    [2, 4,  5, 10, 16],
+    'fop':        [4, 8, 10, 20, 30],
+    'h2':         [0, 0,  5,  5,  8],
+    'jython':     [0, 0,  5, 10, 13],
+    'luindex':    [0, 0,  5, 10, 10],
+    'lusearch':   [0, 4,  5,  5,  8],
+    'pmd':        [0, 0,  5, 10, 13],
+    'sunflow':    [0, 2,  5, 10, 15],
+    'tomcat':     [0, 0,  5, 10, 15],
+    'tradebeans': [0, 0,  5, 10, 13],
+    'tradesoap':  [2, 4,  5, 10, 15],
+    'xalan':      [0, 0,  5, 10, 18],
+}
+
+dacapoScalaSanityWarmup = {
+    'actors':     [0, 0, 2,  8, 10],
+    'apparat':    [0, 0, 1,  2,  3],
+    'factorie':   [0, 0, 2,  5,  5],
+    'kiama':      [0, 0, 3, 13, 15],
+    'scalac':     [0, 0, 5, 15, 20],
+    'scaladoc':   [0, 0, 5, 15, 15],
+    'scalap':     [0, 0, 5, 15, 20],
+    'scalariform':[0, 0, 6, 15, 20],
+    'scalatest':  [0, 0, 2, 10, 12],
+    'scalaxb':    [0, 0, 5, 15, 25],
+    'specs':      [0, 0, 3, 13, 18],
+    'tmt':        [0, 0, 3, 10, 12]
+}
+
+dacapoGateBuildLevels = {
+    'avrora':     ['product', 'fastdebug', 'debug'],
+    'batik':      ['product', 'fastdebug', 'debug'],
+    'eclipse':    ['product'],
+    'fop':        [           'fastdebug', 'debug'],
+    'h2':         ['product', 'fastdebug', 'debug'],
+    'jython':     ['product', 'fastdebug', 'debug'],
+    'luindex':    ['product', 'fastdebug', 'debug'],
+    'lusearch':   ['product'],
+    'pmd':        ['product', 'fastdebug', 'debug'],
+    'sunflow':    ['product', 'fastdebug', 'debug'],
+    'tomcat':     ['product', 'fastdebug', 'debug'],
+    'tradebeans': ['product', 'fastdebug', 'debug'],
+    'tradesoap':  ['product', 'fastdebug'],
+    'xalan':      ['product', 'fastdebug', 'debug'],
+}
+
+dacapoScalaGateBuildLevels = {
+    'actors':     ['product', 'fastdebug', 'debug'],
+    'apparat':    ['product', 'fastdebug', 'debug'],
+    'factorie':   ['product', 'fastdebug', 'debug'],
+    'kiama':      ['product', 'fastdebug', 'debug'],
+    'scalac':     ['product', 'fastdebug', 'debug'],
+    'scaladoc':   ['product', 'fastdebug', 'debug'],
+    'scalap':     ['product', 'fastdebug', 'debug'],
+    'scalariform':['product', 'fastdebug', 'debug'],
+    'scalatest':  ['product', 'fastdebug', 'debug'],
+    'scalaxb':    ['product', 'fastdebug', 'debug'],
+    'specs':      ['product', 'fastdebug', 'debug'],
+    'tmt':        ['product', 'fastdebug', 'debug'],
+}
+
+class SanityCheckLevel:
+    Fast, Gate, Normal, Extensive, Benchmark = range(5)
+    
+def getSPECjvm2008(benchArgs = [], skipKitValidation=False, warmupTime=None, iterationTime=None):
+    
+    specjvm2008 = mx.get_env('SPECJVM2008')
+    if specjvm2008 is None or not exists(join(specjvm2008, 'SPECjvm2008.jar')):
+        mx.abort('Please set the SPECJVM2008 environment variable to a SPECjvm2008 directory')
+    
+    score = re.compile(r"^(Score on|Noncompliant) (?P<benchmark>[a-zA-Z0-9\._]+)( result)?: (?P<score>[0-9]+(,|\.)[0-9]+)( SPECjvm2008 Base)? ops/m$")
+    error = re.compile(r"^Errors in benchmark: ")
+    # The ' ops/m' at the end of the success string is important : it's how you can tell valid and invalid runs apart
+    success = re.compile(r"^(Noncompliant c|C)omposite result: [0-9]+(,|\.)[0-9]+( SPECjvm2008 (Base|Peak))? ops/m$")
+    matcher = Matcher(score, {'const:name' : 'benchmark', 'const:score' : 'score'}, startNewLine=True)
+    
+    opts = []
+    if warmupTime is not None:
+        opts += ['-wt', str(warmupTime)]
+    if iterationTime is not None:
+        opts += ['-it', str(iterationTime)]
+    if skipKitValidation:
+        opts += ['-ikv']
+    
+    return Test("SPECjvm2008", "SPECjvm2008", ['-jar', 'SPECjvm2008.jar'] + opts + benchArgs, [success], [error], [matcher], vmOpts=['-Xms3g'], defaultCwd=specjvm2008)
+
+def getDacapos(level=SanityCheckLevel.Normal, gateBuildLevel=None, dacapoArgs=[]):
+    checks = []
+    
+    for (bench, ns) in dacapoSanityWarmup.items():
+        if ns[level] > 0:
+            if gateBuildLevel is None or gateBuildLevel in dacapoGateBuildLevels[bench]:
+                checks.append(getDacapo(bench, ns[level], dacapoArgs))
+    
+    return checks
+
+def getDacapo(name, n, dacapoArgs=[]):
+    dacapo = mx.get_env('DACAPO_CP')
+    if dacapo is None:
+        l = mx.library('DACAPO', False)
+        if l is not None:
+            dacapo = l.get_path(True)
+        else:
+            mx.abort('DaCapo 9.12 jar file must be specified with DACAPO_CP environment variable or as DACAPO library')
+    
+    if not isfile(dacapo) or not dacapo.endswith('.jar'):
+        mx.abort('Specified DaCapo jar file does not exist or is not a jar file: ' + dacapo)
+    
+    dacapoSuccess = re.compile(r"^===== DaCapo 9\.12 ([a-zA-Z0-9_]+) PASSED in ([0-9]+) msec =====$")
+    dacapoFail = re.compile(r"^===== DaCapo 9\.12 ([a-zA-Z0-9_]+) FAILED (warmup|) =====$")
+    dacapoTime = re.compile(r"===== DaCapo 9\.12 (?P<benchmark>[a-zA-Z0-9_]+) PASSED in (?P<time>[0-9]+) msec =====")
+    
+    dacapoMatcher = Matcher(dacapoTime, {'const:name' : 'benchmark', 'const:score' : 'time'})
+    
+    return Test("DaCapo-" + name, "DaCapo", ['-jar', dacapo, name, '-n', str(n), ] + dacapoArgs, [dacapoSuccess], [dacapoFail], [dacapoMatcher], ['-Xms2g', '-XX:MaxPermSize=256m'])
+
+def getScalaDacapos(level=SanityCheckLevel.Normal, gateBuildLevel=None, dacapoArgs=[]):
+    checks = []
+    
+    for (bench, ns) in dacapoScalaSanityWarmup.items():
+        if ns[level] > 0:
+            if gateBuildLevel is None or gateBuildLevel in dacapoScalaGateBuildLevels[bench]:
+                checks.append(getScalaDacapo(bench, ns[level], dacapoArgs))
+    
+    return checks
+
+def getScalaDacapo(name, n, dacapoArgs=[]):
+    dacapo = mx.get_env('DACAPO_SCALA_CP')
+    if dacapo is None:
+        l = mx.library('DACAPO_SCALA', False)
+        if l is not None:
+            dacapo = l.get_path(True)
+        else:
+            mx.abort('Scala DaCapo 0.1.0 jar file must be specified with DACAPO_SCALA_CP environment variable or as DACAPO_SCALA library')
+    
+    if not isfile(dacapo) or not dacapo.endswith('.jar'):
+        mx.abort('Specified Scala DaCapo jar file does not exist or is not a jar file: ' + dacapo)
+    
+    dacapoSuccess = re.compile(r"^===== DaCapo 0\.1\.0(-SNAPSHOT)? ([a-zA-Z0-9_]+) PASSED in ([0-9]+) msec =====$")
+    dacapoFail = re.compile(r"^===== DaCapo 0\.1\.0(-SNAPSHOT)? ([a-zA-Z0-9_]+) FAILED (warmup|) =====$")
+    dacapoTime = re.compile(r"===== DaCapo 0\.1\.0(-SNAPSHOT)? (?P<benchmark>[a-zA-Z0-9_]+) PASSED in (?P<time>[0-9]+) msec =====")
+    
+    dacapoMatcher = Matcher(dacapoTime, {'const:name' : 'benchmark', 'const:score' : 'time'})
+    
+    return Test("Scala-DaCapo-" + name, "Scala-DaCapo", ['-jar', dacapo, name, '-n', str(n), ] + dacapoArgs, [dacapoSuccess], [dacapoFail], [dacapoMatcher], ['-Xms2g', '-XX:MaxPermSize=256m'])
+
+def getBootstraps():
+    time = re.compile(r"Bootstrapping Graal\.+ in (?P<time>[0-9]+) ms")
+    scoreMatcher = Matcher(time, {'const:name' : 'const:BootstrapTime', 'const:score' : 'time'})
+    tests = []
+    tests.append(Test("Bootstrap", "Bootstrap", ['-version'], successREs=[time], scoreMatchers=[scoreMatcher]))
+    tests.append(Test("Bootstrap-bigHeap", "Bootstrap-bigHeap", ['-version'], successREs=[time], scoreMatchers=[scoreMatcher], vmOpts=['-Xms2g']))
+    return tests
+
+"""
+Encapsulates a single program that is a sanity test and/or a benchmark.
+"""
+class Test:
+    def __init__(self, name, group, cmd, successREs=[], failureREs=[], scoreMatchers=[], vmOpts=[], defaultCwd=None):
+        self.name = name
+        self.group = group
+        self.successREs = successREs
+        self.failureREs = failureREs + [re.compile(r"Exception occured in scope: ")]
+        self.scoreMatchers = scoreMatchers
+        self.vmOpts = vmOpts
+        self.cmd = cmd
+        self.defaultCwd = defaultCwd
+        
+    def __str__(self):
+        return self.name
+    
+    def test(self, vm, cwd=None, opts=[], vmbuild=None):
+        """
+        Run this program as a sanity test.
+        """
+        if cwd is None:
+            cwd = self.defaultCwd
+        parser = OutputParser(nonZeroIsFatal = False)
+        jvmError = re.compile(r"(?P<jvmerror>([A-Z]:|/).*[/\\]hs_err_pid[0-9]+\.log)")
+        parser.addMatcher(Matcher(jvmError, {'const:jvmError' : 'jvmerror'}))
+        
+        for successRE in self.successREs:
+            parser.addMatcher(Matcher(successRE, {'const:passed' : 'const:1'}))
+        for failureRE in self.failureREs:
+            parser.addMatcher(Matcher(failureRE, {'const:failed' : 'const:1'}))
+        
+        result = parser.parse(vm, self.vmOpts + opts + self.cmd, cwd, vmbuild)
+        
+        parsedLines = result['parsed']
+        if len(parsedLines) == 0:
+            return False
+        
+        assert len(parsedLines) == 1, 'Test matchers should not return more than one line'
+        
+        parsed = parsedLines[0]
+        
+        if parsed.has_key('jvmError'):
+            mx.log('/!\\JVM Error : dumping error log...')
+            f = open(parsed['jvmError'], 'rb');
+            for line in iter(f.readline, ''):
+                mx.log(line.rstrip())
+            f.close()
+            os.unlink(parsed['jvmError'])
+            return False
+        
+        if parsed.has_key('failed') and parsed['failed'] is '1':
+            return False
+        
+        return result['retcode'] is 0 and parsed.has_key('passed') and parsed['passed'] is '1'
+    
+    def bench(self, vm, cwd=None, opts=[], vmbuild=None):
+        """
+        Run this program as a benchmark.
+        """
+        if cwd is None:
+            cwd = self.defaultCwd
+        parser = OutputParser(nonZeroIsFatal = False)
+        
+        for successRE in self.successREs:
+            parser.addMatcher(Matcher(successRE, {'const:passed' : 'const:1'}))
+        for failureRE in self.failureREs:
+            parser.addMatcher(Matcher(failureRE, {'const:failed' : 'const:1'}))
+        for scoreMatcher in self.scoreMatchers:
+            parser.addMatcher(scoreMatcher)
+            
+        result = parser.parse(vm, self.vmOpts + opts + self.cmd, cwd, vmbuild)
+        if result['retcode'] is not 0:
+            mx.abort("Benchmark failed (non-zero retcode)")
+        
+        parsed = result['parsed']
+        
+        ret = {}
+        
+        passed = False;
+        
+        for line in parsed:
+            assert (line.has_key('name') and line.has_key('score')) or line.has_key('passed')
+            if line.has_key('failed') and line['failed'] is '1':
+                mx.abort("Benchmark failed")
+            if line.has_key('passed') and line['passed'] is '1':
+                passed = True
+            ret[line['name']] = line['score']
+        
+        if not passed:
+            mx.abort("Benchmark failed (not passed)")
+        
+        return ret
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mxtool/.project	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>mxtool</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.python.pydev.PyDevBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.python.pydev.pythonNature</nature>
+	</natures>
+</projectDescription>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mxtool/.pydevproject	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?eclipse-pydev version="1.0"?>
+
+<pydev_project>
+<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
+<path>/mxtool</path>
+</pydev_pathproperty>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
+</pydev_project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mxtool/URLConnectionDownload.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.regex.*;
+
+/**
+ * Downloads content from a given URL to a given file.
+ *
+ * @param path where to write the content
+ * @param urls the URLs to try, stopping after the first successful one
+ */
+public class URLConnectionDownload {
+
+	/**
+	 * Downloads content from a given URL to a given file.
+	 * 
+	 * @param args
+	 *            arg[0] is the path where to write the content. The remainder
+	 *            of args are the URLs to try, stopping after the first
+	 *            successful one
+	 */
+    public static void main(String[] args) {
+    	File path = new File(args[0]);
+    	String[] urls = new String[args.length - 1];
+    	System.arraycopy(args, 1, urls, 0, urls.length);
+
+        File parent = path.getParentFile();
+        makeDirectory(parent);
+        
+        // Enable use of system proxies
+        System.setProperty("java.net.useSystemProxies", "true");
+
+        String proxy = System.getenv("HTTP_PROXY");
+        String proxyMsg = "";
+        if (proxy != null) {
+            Pattern p = Pattern.compile("(?:http://)?([^:]+)(:\\d+)?");
+            Matcher m = p.matcher(proxy);
+            if (m.matches()) {
+                String host = m.group(1);
+                String port = m.group(2);
+                System.setProperty("http.proxyHost", host);
+                if (port != null) {
+                    port = port.substring(1); // strip ':'
+                    System.setProperty("http.proxyPort", port);
+                }
+                proxyMsg = " via proxy  " + proxy;
+            } else {
+            	System.err.println("Value of HTTP_PROXY is not valid:  " + proxy);
+            }
+        } else {
+        	System.err.println("** If behind a firewall without direct internet access, use the HTTP_PROXY environment variable (e.g. 'env HTTP_PROXY=proxy.company.com:80 max ...') or download manually with a web browser.");
+        }
+
+        for (String s : urls) {
+            try {
+                System.err.println("Downloading " + s + " to  " + path + proxyMsg);
+                URL url = new URL(s);
+                URLConnection conn = url.openConnection();
+                // 10 second timeout to establish connection
+                conn.setConnectTimeout(10000);
+                InputStream in = conn.getInputStream();
+                int size = conn.getContentLength();
+                FileOutputStream out = new FileOutputStream(path);
+                int read = 0;
+                byte[] buf = new byte[8192];
+                int n = 0;
+                while ((read = in.read(buf)) != -1) {
+                    n += read;
+                    long percent = ((long) n * 100 / size);
+                    System.err.print("\r " + n + " bytes " + (size == -1 ? "" : " (" + percent + "%)"));
+                    out.write(buf, 0, read);
+                }
+                System.err.println();
+                out.close();
+                in.close();
+                return;
+            } catch (MalformedURLException e) {
+                throw new Error("Error in URL " + s, e);
+            } catch (IOException e) {
+                System.err.println("Error reading from  " + s + ":  " + e);
+                path.delete();
+            }
+        }
+        throw new Error("Could not download content to  " + path + " from  " + Arrays.toString(urls));
+    }
+
+    private static void makeDirectory(File directory) {
+        if (!directory.exists() && !directory.mkdirs()) {
+            throw new Error("Could not make directory " + directory);
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mxtool/mx	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+#!/bin/bash
+#
+# ----------------------------------------------------------------------------------------------------
+#
+# Copyright (c) 2007, 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.
+#
+# ----------------------------------------------------------------------------------------------------
+
+dir=`/bin/pwd`
+
+# Resolve location of this script so that mx.py can be found in the same directory
+source="${BASH_SOURCE[0]}"
+while [ -h "$source" ] ; do source="$(readlink "$source")"; done
+dir="$( cd -P "$( dirname "$source" )" && pwd )"
+
+if [ ! -f "$dir/mx.py" ]; then
+    echo "Cannot find mx.py in $dir"
+    exit 1
+fi
+
+python <<END
+import sys
+major, minor, micro, _, _ = sys.version_info
+if major != 2 or minor != 7:
+    raise SystemExit('The mx.py script requires Python 2.7, not {0}.{1}.{2}'.format(major, minor, micro))
+END
+if [ $? -eq 0 ]; then
+    exec python -u "$dir/mx.py" "$@"
+fi
+
+#end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mxtool/mx.py	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1674 @@
+#!/usr/bin/python
+#
+# ----------------------------------------------------------------------------------------------------
+#
+# Copyright (c) 2007, 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.
+#
+# ----------------------------------------------------------------------------------------------------
+#
+# mx is a command line tool inspired by mvn (http://maven.apache.org/)
+# and hg (http://mercurial.selenic.com/). It includes a mechanism for
+# managing the dependencies between a set of projects (like Maven)
+# as well as making it simple to run commands
+# (like hg is the interface to the Mercurial commands).
+#
+# The organizing principle of mx is a project suite. A suite is a directory
+# containing one or more projects. It's not coincidental that this closely
+# matches the layout of one or more projects in a Mercurial repository.
+# The configuration information for a suite lives in an 'mx' sub-directory
+# at the top level of the suite. 
+#
+# When launched, mx treats the current working directory as a suite.
+# This is the primary suite. All other suites are called included suites.
+#
+# The configuration files (i.e. in the 'mx' sub-directory) of a suite are:
+#
+#   projects    - Defines the projects and libraries in the suite and the dependencies between them
+#   commands.py - Suite specific extensions to the commands available to mx. This is only processed
+#                 for the primary suite.
+#   includes    - Other suites to be loaded. This is recursive. 
+#   env         - A set of environment variable definitions.
+#
+# The includes and env files are typically not put under version control
+# as they usually contain local file-system paths.
+#
+# The projects file is like the pom.xml file from Maven except that
+# it is a properties file (not XML). Each non-comment line
+# in the file specifies an attribute of a project or library. The main 
+# difference between a project and a library is that the former contains
+# source code built by the mx tool where as the latter is an external
+# dependency. The format of the projects file is 
+#
+# Library specification format:
+#
+#     library@<name>@<prop>=<value>
+#
+# Built-in library properties (* = required):
+#
+#    *path: the file system path for the library to appear on a class path
+#     urls: a comma seperated list of URLs from which the library can be downloaded
+#     optional: if "true" then this library will be omitted from a class path if it doesn't exist on the file system and no URLs are specified
+#
+# Project specification format:
+#
+#     project@<name>@<prop>=<value>
+#
+# The name of a project also denotes the directory it is in.
+#
+# Built-in project properties:
+#
+#    *sourceDirs: a comma separated list of source directoriy names (relative to the project directory)
+#     dependencies: a comma separated list of the libraries and project the project depends upon (transitive dependencies may be omitted)
+#     checkstyle: the project whose Checkstyle configuration (i.e. <project>/.checkstyle_checks.xml) is used
+#
+# Other properties can be specified for projects and libraries for use by extension commands.
+#
+# Values can use environment variables with Bash syntax (e.g. ${HOME}).
+
+import sys, os, errno, time, subprocess, shlex, types, urllib2, contextlib, StringIO, zipfile, signal
+import shutil, fnmatch, re, xml.dom.minidom
+from collections import Callable
+from threading import Thread
+from argparse import ArgumentParser, REMAINDER
+from os.path import join, dirname, exists, getmtime, isabs, expandvars, isdir, isfile
+
+DEFAULT_JAVA_ARGS = '-ea -Xss2m -Xmx1g'
+
+_projects = dict()
+_libs = dict()
+_suites = dict()
+_mainSuite = None
+_opts = None
+_java = None
+
+"""
+A dependency is a library or project specified in a suite.
+"""
+class Dependency:
+    def __init__(self, suite, name):
+        self.name = name
+        self.suite = suite
+        
+    def __str__(self):
+        return self.name
+    
+    def __eq__(self, other):
+        return self.name == other.name
+    
+    def __ne__(self, other):
+        return self.name != other.name
+
+    def __hash__(self):
+        return hash(self.name)
+    
+    def isLibrary(self):
+        return isinstance(self, Library)
+    
+class Project(Dependency):
+    def __init__(self, suite, name, srcDirs, deps, dir):
+        Dependency.__init__(self, suite, name)
+        self.srcDirs = srcDirs
+        self.deps = deps
+        self.checkstyleProj = name
+        self.native = False
+        self.dir = dir
+        
+    def all_deps(self, deps, includeLibs, includeSelf=True):
+        """
+        Add the transitive set of dependencies for this project, including
+        libraries if 'includeLibs' is true, to the 'deps' list.
+        """
+        if self in deps:
+            return deps
+        for name in self.deps:
+            assert name != self.name
+            dep = _libs.get(name, None)
+            if dep is not None:
+                if includeLibs and not dep in deps:
+                    deps.append(dep)
+            else:
+                dep = project(name)
+                if not dep in deps:
+                    dep.all_deps(deps, includeLibs)
+        if not self in deps and includeSelf:
+            deps.append(self)
+        return deps
+    
+    def _compute_max_dep_distances(self, name, distances, dist):
+        currentDist = distances.get(name);
+        if currentDist is None or currentDist < dist:
+            distances[name] = dist
+            p = project(name, False)
+            if p is not None:
+                for dep in p.deps:
+                    self._compute_max_dep_distances(dep, distances, dist + 1)
+                
+    def canonical_deps(self):
+        """
+        Get the dependencies of this project that are not recursive (i.e. cannot be reached
+        via other dependencies).
+        """
+        distances = dict()
+        result = set()
+        self._compute_max_dep_distances(self.name, distances, 0)
+        for n,d in distances.iteritems():
+            assert d > 0 or n == self.name
+            if d == 1:
+                result.add(n)
+                
+            
+        if len(result) == len(self.deps) and frozenset(self.deps) == result:
+            return self.deps
+        return result;
+    
+
+    def source_dirs(self):
+        """
+        Get the directories in which the sources of this project are found.
+        """
+        return [join(self.dir, s) for s in self.srcDirs]
+        
+    def output_dir(self):
+        """
+        Get the directory in which the class files of this project are found/placed.
+        """
+        if self.native:
+            return None
+        return join(self.dir, 'bin')
+
+    def append_to_classpath(self, cp, resolve):
+        if not self.native:
+            cp.append(self.output_dir())
+
+class Library(Dependency):
+    def __init__(self, suite, name, path, mustExist, urls):
+        Dependency.__init__(self, suite, name)
+        self.path = path.replace('/', os.sep)
+        self.urls = urls
+        self.mustExist = mustExist
+    
+    def get_path(self, resolve):
+        path = self.path
+        if not isabs(path):
+            path = join(self.suite.dir, path)
+        if resolve and self.mustExist and not exists(path):
+            assert not len(self.urls) == 0, 'cannot find required library  ' + self.name + " " + path;
+            print('Downloading ' + self.name + ' from ' + str(self.urls))
+            download(path, self.urls)
+            
+        return path
+        
+    def append_to_classpath(self, cp, resolve):
+        path = self.get_path(resolve)
+        if exists(path) or not resolve:
+            cp.append(path)
+    
+class Suite:
+    def __init__(self, dir, primary):
+        self.dir = dir
+        self.projects = []
+        self.libs = []
+        self.includes = []
+        self.commands = None
+        self.primary = primary
+        mxDir = join(dir, 'mx')
+        self._load_env(mxDir)
+        if primary:
+            self._load_commands(mxDir)
+
+    def _load_projects(self, mxDir):
+        libsMap = dict()
+        projsMap = dict() 
+        projectsFile = join(mxDir, 'projects')
+        if not exists(projectsFile):
+            return
+        with open(projectsFile) as f:
+            for line in f:
+                line = line.strip()
+                if len(line) != 0 and line[0] != '#':
+                    key, value = line.split('=', 1)
+                    
+                    parts = key.split('@')
+                    
+                    if len(parts) == 2:
+                        pass
+                    if len(parts) != 3:
+                        abort('Property name does not have 3 parts separated by "@": ' + key)
+                    kind, name, attr = parts
+                    if kind == 'project':
+                        m = projsMap
+                    elif kind == 'library':
+                        m = libsMap
+                    else:
+                        abort('Property name does not start with "project@" or "library@": ' + key)
+                        
+                    attrs = m.get(name)
+                    if attrs is None:
+                        attrs = dict()
+                        m[name] = attrs
+                    value = expandvars_in_property(value)
+                    attrs[attr] = value
+                        
+        def pop_list(attrs, name):
+            v = attrs.pop(name, None)
+            if v is None or len(v.strip()) == 0:
+                return []
+            return [n.strip() for n in v.split(',')]
+        
+        for name, attrs in projsMap.iteritems():
+            srcDirs = pop_list(attrs, 'sourceDirs')
+            deps = pop_list(attrs, 'dependencies')
+            subDir = attrs.pop('subDir', None);
+            if subDir is None:
+                dir = join(self.dir, name)
+            else:
+                dir = join(self.dir, subDir, name)
+            p = Project(self, name, srcDirs, deps, dir)
+            p.checkstyleProj = attrs.pop('checkstyle', name)
+            p.native = attrs.pop('native', '') == 'true'
+            p.__dict__.update(attrs)
+            self.projects.append(p)
+
+        for name, attrs in libsMap.iteritems():
+            path = attrs.pop('path')
+            mustExist = attrs.pop('optional', 'false') != 'true'
+            urls = pop_list(attrs, 'urls')
+            l = Library(self, name, path, mustExist, urls)
+            l.__dict__.update(attrs)
+            self.libs.append(l)
+        
+    def _load_commands(self, mxDir):
+        commands = join(mxDir, 'commands.py')
+        if exists(commands):
+            # temporarily extend the Python path
+            sys.path.insert(0, mxDir)
+    
+            mod = __import__('commands')
+    
+            # revert the Python path
+            del sys.path[0]
+
+            if not hasattr(mod, 'mx_init'):
+                abort(commands + ' must define an mx_init(env) function')
+            if hasattr(mod, 'mx_post_parse_cmd_line'):
+                self.mx_post_parse_cmd_line = mod.mx_post_parse_cmd_line
+                
+            mod.mx_init()
+            self.commands = mod
+                
+    def _load_includes(self, mxDir):
+        includes = join(mxDir, 'includes')
+        if exists(includes):
+            with open(includes) as f:
+                for line in f:
+                    self.includes.append(expandvars_in_property(line.strip()))
+        
+    def _load_env(self, mxDir):
+        e = join(mxDir, 'env')
+        if exists(e):
+            with open(e) as f:
+                for line in f:
+                    line = line.strip()
+                    if len(line) != 0 and line[0] != '#':
+                        key, value = line.split('=', 1)
+                        os.environ[key.strip()] = expandvars_in_property(value.strip())
+    
+    def _post_init(self, opts):
+        mxDir = join(self.dir, 'mx')
+        self._load_includes(mxDir)
+        self._load_projects(mxDir)
+        if self.mx_post_parse_cmd_line is not None:
+            self.mx_post_parse_cmd_line(opts)
+        for p in self.projects:
+            existing = _projects.get(p.name)
+            if existing is not None:
+                abort('cannot override project  ' + p.name + ' in ' + p.dir + " with project of the same name in  " + existing.dir)
+            _projects[p.name] = p
+        for l in self.libs:
+            existing = _libs.get(l.name)
+            if existing is not None:
+                abort('cannot redefine library  ' + l.name)
+            _libs[l.name] = l
+        
+def get_os():
+    """
+    Get a canonical form of sys.platform.
+    """
+    if sys.platform.startswith('darwin'):
+        return 'darwin'
+    elif sys.platform.startswith('linux'):
+        return 'linux'
+    elif sys.platform.startswith('sunos'):
+        return 'solaris'
+    elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'):
+        return 'windows'
+    else:
+        abort('Unknown operating system ' + sys.platform)
+
+def _loadSuite(dir, primary=False):
+    mxDir = join(dir, 'mx')
+    if not exists(mxDir) or not isdir(mxDir):
+        return None
+    if not _suites.has_key(dir):
+        suite = Suite(dir, primary)
+        _suites[dir] = suite
+        return suite 
+
+def suites():
+    """
+    Get the list of all loaded suites.
+    """
+    return _suites.values()
+
+def projects():
+    """
+    Get the list of all loaded projects.
+    """
+    return _projects.values()
+    
+def project(name, fatalIfMissing=True):
+    """
+    Get the project for a given name. This will abort if the named project does
+    not exist and 'fatalIfMissing' is true.
+    """
+    p = _projects.get(name)
+    if p is None and fatalIfMissing:
+        abort('project named ' + name + ' not found')
+    return p
+
+def library(name, fatalIfMissing=True):
+    """
+    Gets the library for a given name. This will abort if the named library does
+    not exist and 'fatalIfMissing' is true.
+    """
+    l = _libs.get(name)
+    if l is None and fatalIfMissing:
+        abort('library named ' + name + ' not found')
+    return l
+
+def _as_classpath(deps, resolve):
+    cp = []
+    if _opts.cp_prefix is not None:
+        cp = [_opts.cp_prefix]
+    for d in deps:
+        d.append_to_classpath(cp, resolve)
+    if _opts.cp_suffix is not None:
+        cp += [_opts.cp_suffix]
+    return os.pathsep.join(cp)
+
+def classpath(names=None, resolve=True, includeSelf=True):
+    """
+    Get the class path for a list of given projects, resolving each entry in the
+    path (e.g. downloading a missing library) if 'resolve' is true.
+    """
+    if names is None:
+        return _as_classpath(sorted_deps(True), resolve)
+    deps = []
+    if isinstance(names, types.StringTypes):
+        project(names).all_deps(deps, True, includeSelf)
+    else:
+        for n in names:
+            project(n).all_deps(deps, True, includeSelf)
+    return _as_classpath(deps, resolve)
+    
+def sorted_deps(includeLibs=False):
+    """
+    Gets the loaded projects and libraries sorted such that dependencies
+    are before the projects that depend on them. Unless 'includeLibs' is
+    true, libraries are omitted from the result.
+    """
+    deps = []
+    for p in _projects.itervalues():
+        p.all_deps(deps, includeLibs)
+    return deps
+
+class ArgParser(ArgumentParser):
+
+    # Override parent to append the list of available commands
+    def format_help(self):
+        return ArgumentParser.format_help(self) + _format_commands()
+    
+    
+    def __init__(self):
+        self.java_initialized = False
+        ArgumentParser.__init__(self, prog='mx')
+    
+        self.add_argument('-v', action='store_true', dest='verbose', help='enable verbose output')
+        self.add_argument('-d', action='store_true', dest='java_dbg', help='make Java processes wait on port 8000 for a debugger')
+        self.add_argument('--cp-pfx', dest='cp_prefix', help='class path prefix', metavar='<arg>')
+        self.add_argument('--cp-sfx', dest='cp_suffix', help='class path suffix', metavar='<arg>')
+        self.add_argument('--J', dest='java_args', help='Java VM arguments (e.g. --J @-dsa)', metavar='@<args>', default=DEFAULT_JAVA_ARGS)
+        self.add_argument('--Jp', action='append', dest='java_args_pfx', help='prefix Java VM arguments (e.g. --Jp @-dsa)', metavar='@<args>', default=[])
+        self.add_argument('--Ja', action='append', dest='java_args_sfx', help='suffix Java VM arguments (e.g. --Ja @-dsa)', metavar='@<args>', default=[])
+        self.add_argument('--user-home', help='users home directory', metavar='<path>', default=os.path.expanduser('~'))
+        self.add_argument('--java-home', help='JDK installation directory (must be JDK 6 or later)', metavar='<path>')
+        if get_os() != 'windows':
+            # Time outs are (currently) implemented with Unix specific functionality
+            self.add_argument('--timeout', help='Timeout (in seconds) for command', type=int, default=0, metavar='<secs>')
+            self.add_argument('--ptimeout', help='Timeout (in seconds) for subprocesses', type=int, default=0, metavar='<secs>')
+        
+    def _parse_cmd_line(self, args=None):
+        if args is None:
+            args = sys.argv[1:]
+
+        self.add_argument('commandAndArgs', nargs=REMAINDER, metavar='command args...')
+        
+        opts = self.parse_args()
+        
+        # Give the timeout options a default value to avoid the need for hasattr() tests
+        opts.__dict__.setdefault('timeout', 0)
+        opts.__dict__.setdefault('ptimeout', 0)
+
+        if opts.java_home is None:
+            opts.java_home = os.environ.get('JAVA_HOME')
+
+        if opts.java_home is None or opts.java_home == '':
+            abort('Could not find Java home. Use --java-home option or ensure JAVA_HOME environment variable is set.')
+
+        if opts.user_home is None or opts.user_home == '':
+            abort('Could not find user home. Use --user-home option or ensure HOME environment variable is set.')
+    
+        os.environ['JAVA_HOME'] = opts.java_home
+        os.environ['HOME'] = opts.user_home
+        
+        commandAndArgs = opts.__dict__.pop('commandAndArgs')
+        return opts, commandAndArgs
+    
+def _format_commands():
+    msg = '\navailable commands:\n\n'
+    for cmd in sorted(commands.iterkeys()):
+        c, _ = commands[cmd][:2]
+        doc = c.__doc__
+        if doc is None:
+            doc = ''
+        msg += ' {0:<20} {1}\n'.format(cmd, doc.split('\n', 1)[0])
+    return msg + '\n'
+
+def java():
+    """
+    Get a JavaConfig object containing Java commands launch details.
+    """
+    assert _java is not None
+    return _java
+
+def run_java(args, nonZeroIsFatal=True, out=None, err=None, cwd=None):
+    return run(java().format_cmd(args), nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd)
+
+def _kill_process_group(pid):
+    pgid = os.getpgid(pid)
+    try:
+        os.killpg(pgid, signal.SIGKILL)
+        return True
+    except:
+        log('Error killing subprocess ' + str(pgid) + ': ' + str(sys.exc_info()[1]))
+        return False
+
+def _waitWithTimeout(process, args, timeout):
+    def _waitpid(pid):
+        while True:
+            try:
+                return os.waitpid(pid, os.WNOHANG)
+            except OSError, e:
+                if e.errno == errno.EINTR:
+                    continue
+                raise
+    
+    def _returncode(status):
+        if os.WIFSIGNALED(status):
+            return -os.WTERMSIG(status)
+        elif os.WIFEXITED(status):
+            return os.WEXITSTATUS(status)
+        else:
+            # Should never happen
+            raise RuntimeError("Unknown child exit status!")
+        
+    end = time.time() + timeout
+    delay = 0.0005
+    while True:
+        (pid, status) = _waitpid(process.pid)
+        if pid == process.pid:
+            return _returncode(status)
+        remaining = end - time.time()
+        if remaining <= 0:
+            abort('Process timed out after {0} seconds: {1}'.format(timeout, ' '.join(args)))
+        delay = min(delay * 2, remaining, .05)
+        time.sleep(delay)
+
+# Makes the current subprocess accessible to the abort() function
+# This is a tuple of the Popen object and args.
+_currentSubprocess = None
+
+def waitOn(p):
+    if get_os() == 'windows':
+        # on windows use a poll loop, otherwise signal does not get handled
+        retcode = None
+        while retcode == None:
+            retcode = p.poll()
+            time.sleep(0.05)
+    else:
+        retcode = p.wait()
+    return retcode
+
+def run(args, nonZeroIsFatal=True, out=None, err=None, cwd=None, timeout=None):
+    """
+    Run a command in a subprocess, wait for it to complete and return the exit status of the process.
+    If the exit status is non-zero and `nonZeroIsFatal` is true, then mx is exited with
+    the same exit status.
+    Each line of the standard output and error streams of the subprocess are redirected to
+    out and err if they are callable objects.
+    """
+    
+    assert isinstance(args, types.ListType), "'args' must be a list: " + str(args)
+    for arg in args:
+        assert isinstance(arg, types.StringTypes), 'argument is not a string: ' + str(arg)
+    
+    if _opts.verbose:
+        log(' '.join(args))
+        
+    if timeout is None and _opts.ptimeout != 0:
+        timeout = _opts.ptimeout
+
+    global _currentSubprocess
+        
+    try:
+        # On Unix, the new subprocess should be in a separate group so that a timeout alarm
+        # can use os.killpg() to kill the whole subprocess group
+        preexec_fn = None
+        creationflags = 0
+        if get_os() == 'windows':
+            creationflags = subprocess.CREATE_NEW_PROCESS_GROUP
+        else:
+            preexec_fn = os.setsid  
+        
+        if not callable(out) and not callable(err) and timeout is None:
+            # The preexec_fn=os.setsid
+            p = subprocess.Popen(args, cwd=cwd, preexec_fn=preexec_fn, creationflags=creationflags)
+            _currentSubprocess = (p, args)
+	    retcode = waitOn(p)
+        else:
+            def redirect(stream, f):
+                for line in iter(stream.readline, ''):
+                    f(line)
+                stream.close()
+            stdout=out if not callable(out) else subprocess.PIPE
+            stderr=err if not callable(err) else subprocess.PIPE
+            p = subprocess.Popen(args, cwd=cwd, stdout=stdout, stderr=stderr, preexec_fn=preexec_fn, creationflags=creationflags)
+            _currentSubprocess = (p, args)
+            if callable(out):
+                t = Thread(target=redirect, args=(p.stdout, out))
+                t.daemon = True # thread dies with the program
+                t.start()
+            if callable(err):
+                t = Thread(target=redirect, args=(p.stderr, err))
+                t.daemon = True # thread dies with the program
+                t.start()
+            if timeout is None or timeout == 0:
+                retcode = waitOn(p)
+            else:
+                if get_os() == 'windows':
+                    abort('Use of timeout not (yet) supported on Windows')
+                retcode = _waitWithTimeout(p, args, timeout)
+    except OSError as e:
+        log('Error executing \'' + ' '.join(args) + '\': ' + str(e))
+        if _opts.verbose:
+            raise e
+        abort(e.errno)
+    except KeyboardInterrupt:
+        abort(1)
+    finally:
+        _currentSubprocess = None
+
+    if retcode and nonZeroIsFatal:
+        if _opts.verbose:
+            raise subprocess.CalledProcessError(retcode, ' '.join(args))
+        abort(retcode)
+        
+    return retcode
+
+def exe_suffix(name):
+    """
+    Gets the platform specific suffix for an executable 
+    """
+    if get_os() == 'windows':
+        return name + '.exe'
+    return name
+
+def lib_suffix(name):
+    """
+    Gets the platform specific suffix for a library
+    """
+    os = get_os();
+    if os == 'windows':
+        return name + '.dll'
+    if os == 'linux':
+        return name + '.so'
+    return name
+
+"""
+A JavaConfig object encapsulates info on how Java commands are run.
+"""
+class JavaConfig:
+    def __init__(self, opts):
+        self.jdk = opts.java_home
+        self.debug = opts.java_dbg
+        self.java =  exe_suffix(join(self.jdk, 'bin', 'java'))
+        self.javac = exe_suffix(join(self.jdk, 'bin', 'javac'))
+        self.javap = exe_suffix(join(self.jdk, 'bin', 'javap'))
+
+        if not exists(self.java):
+            abort('Java launcher derived from JAVA_HOME does not exist: ' + self.java)
+
+        def delAtAndSplit(s):
+            return shlex.split(s.lstrip('@'))
+        
+        self.java_args = delAtAndSplit(_opts.java_args)
+        self.java_args_pfx = sum(map(delAtAndSplit, _opts.java_args_pfx), [])
+        self.java_args_sfx = sum(map(delAtAndSplit, _opts.java_args_sfx), [])
+        
+        # Prepend the -d64 VM option only if the java command supports it
+        try:
+            output = subprocess.check_output([self.java, '-d64', '-version'], stderr=subprocess.STDOUT)
+            self.java_args = ['-d64'] + self.java_args
+        except subprocess.CalledProcessError as e:
+            try:
+                output = subprocess.check_output([self.java, '-version'], stderr=subprocess.STDOUT)
+            except subprocess.CalledProcessError as e:
+                print e.output
+                abort(e.returncode)
+        
+        output = output.split()
+        assert output[1] == 'version'
+        self.version = output[2].strip('"')
+        
+        if self.debug:
+            self.java_args += ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000']
+
+    def format_cmd(self, args):
+        return [self.java] + self.java_args_pfx + self.java_args + self.java_args_sfx + args
+    
+def check_get_env(key):
+    """
+    Gets an environment variable, aborting with a useful message if it is not set.
+    """
+    value = get_env(key)
+    if value is None:
+        abort('Required environment variable ' + key + ' must be set')
+    return value
+
+def get_env(key, default=None):
+    """
+    Gets an environment variable.
+    """
+    value = os.environ.get(key, default)
+    return value
+
+def log(msg=None):
+    """
+    Write a message to the console.
+    All script output goes through this method thus allowing a subclass
+    to redirect it. 
+    """
+    if msg is None:
+        print
+    else:
+        print msg
+
+def expand_project_in_class_path_arg(cpArg):
+    cp = []
+    for part in cpArg.split(os.pathsep):
+        if part.startswith('@'):
+            cp += classpath(part[1:]).split(os.pathsep)
+        else:
+            cp.append(part)
+    return os.pathsep.join(cp)
+    
+def expand_project_in_args(args):
+    for i in range(len(args)):
+        if args[i] == '-cp' or args[i] == '-classpath':
+            if i + 1 < len(args):
+                args[i + 1] = expand_project_in_class_path_arg(args[i + 1])
+            return
+
+
+def gmake_cmd():
+    for a in ['make', 'gmake', 'gnumake']:
+        try:
+            output = subprocess.check_output([a, '--version'])
+            if 'GNU' in output:
+                return a;
+        except:
+            pass
+    abort('Could not find a GNU make executable on the current path.')
+
+def expandvars_in_property(value):
+        result = expandvars(value)
+        if '$' in result or '%' in result:
+            abort('Property contains an undefined environment variable: ' + value)
+        return result
+
+           
+def abort(codeOrMessage):
+    """
+    Aborts the program with a SystemExit exception.
+    If 'codeOrMessage' is a plain integer, it specifies the system exit status;
+    if it is None, the exit status is zero; if it has another type (such as a string),
+    the object's value is printed and the exit status is one.
+    """
+    
+    #import traceback
+    #traceback.print_stack()
+    currentSubprocess = _currentSubprocess
+    if currentSubprocess is not None:
+        p, _ = currentSubprocess
+        if get_os() == 'windows':
+            p.kill()
+        else:
+            _kill_process_group(p.pid)
+    
+    raise SystemExit(codeOrMessage)
+
+def download(path, urls, verbose=False):
+    """
+    Attempts to downloads content for each URL in a list, stopping after the first successful download.
+    If the content cannot be retrieved from any URL, the program is aborted. The downloaded content
+    is written to the file indicated by 'path'.
+    """
+    d = dirname(path)
+    if d != '' and not exists(d):
+        os.makedirs(d)
+        
+    # Try it with the Java tool first since it can show a progress counter
+    myDir = dirname(__file__)
+    
+    javaSource = join(myDir, 'URLConnectionDownload.java')
+    javaClass = join(myDir, 'URLConnectionDownload.class')
+    if not exists(javaClass) or getmtime(javaClass) < getmtime(javaSource):
+        subprocess.check_call([java().javac, '-d', myDir, javaSource])
+    if run([java().java, '-cp', myDir, 'URLConnectionDownload', path] + urls) == 0:
+        return
+        
+    def url_open(url):
+        userAgent = 'Mozilla/5.0 (compatible)'
+        headers = { 'User-Agent' : userAgent }
+        req = urllib2.Request(url, headers=headers)
+        return urllib2.urlopen(req);
+        
+    for url in urls:
+        try:
+            if (verbose):
+                log('Downloading ' + url + ' to ' + path)
+            if url.startswith('zip:') or url.startswith('jar:'):
+                i = url.find('!/')
+                if i == -1:
+                    abort('Zip or jar URL does not contain "!/": ' + url)
+                url, _, entry = url[len('zip:'):].partition('!/')
+                with contextlib.closing(url_open(url)) as f:
+                    data = f.read()
+                    zipdata = StringIO.StringIO(f.read())
+            
+                zf = zipfile.ZipFile(zipdata, 'r')
+                data = zf.read(entry)
+                with open(path, 'wb') as f:
+                    f.write(data)
+            else:
+                with contextlib.closing(url_open(url)) as f:
+                    data = f.read()
+                with open(path, 'wb') as f:
+                    f.write(data)
+            return
+        except IOError as e:
+            log('Error reading from ' + url + ': ' + str(e))
+        except zipfile.BadZipfile as e:
+            log('Error in zip file downloaded from ' + url + ': ' + str(e))
+            
+    abort('Could not download to ' + path + ' from any of the following URLs:\n\n    ' +
+              '\n    '.join(urls) + '\n\nPlease use a web browser to do the download manually')
+            
+def update_file(path, content):
+    """
+    Updates a file with some given content if the content differs from what's in
+    the file already. The return value indicates if the file was updated.
+    """
+    existed = exists(path)
+    try:
+        old = None
+        if existed:
+            with open(path, 'rb') as f:
+                old = f.read()
+        
+        if old == content:
+            return False
+            
+        with open(path, 'wb') as f:
+            f.write(content)
+            
+        log(('modified ' if existed else 'created ') + path)
+        return True;
+    except IOError as e:
+        abort('Error while writing to ' + path + ': ' + str(e));
+
+# Builtin commands
+            
+def build(args, parser=None):
+    """compile the Java and C sources, linking the latter
+
+    Compile all the Java source code using the appropriate compilers
+    and linkers for the various source code types."""
+    
+    suppliedParser = parser is not None
+    if not suppliedParser:
+        parser = ArgumentParser(prog='mx build')
+    
+    parser = parser if parser is not None else ArgumentParser(prog='mx build')
+    parser.add_argument('-f', action='store_true', dest='force', help='force compilation even if class files are up to date')
+    parser.add_argument('-c', action='store_true', dest='clean', help='removes existing build output')
+    parser.add_argument('--source', dest='compliance', help='Java compliance level', default='1.6')
+    parser.add_argument('--Wapi', action='store_true', dest='warnAPI', help='show warnings about using internal APIs')
+    parser.add_argument('--no-java', action='store_false', dest='java', help='do not build Java projects')
+    parser.add_argument('--no-native', action='store_false', dest='native', help='do not build native projects')
+    parser.add_argument('--jdt', help='Eclipse installation or path to ecj.jar for using the Eclipse batch compiler instead of javac', metavar='<path>')
+    
+    if suppliedParser:
+        parser.add_argument('remainder', nargs=REMAINDER, metavar='...')
+
+    args = parser.parse_args(args)
+    
+    jdtJar = None
+    if args.jdt is not None:
+        if args.jdt.endswith('.jar'):
+            jdtJar=args.jdt
+        elif isdir(args.jdt):
+            plugins = join(args.jdt, 'plugins')
+            choices = [f for f in os.listdir(plugins) if fnmatch.fnmatch(f, 'org.eclipse.jdt.core_*.jar')]
+            if len(choices) != 0:
+                jdtJar = join(plugins, sorted(choices, reverse=True)[0])
+
+    built = set()
+    for p in sorted_deps():
+        
+        if p.native:
+            if args.native:
+                log('Calling GNU make {0}...'.format(p.dir))
+    
+                if args.clean:
+                    run([gmake_cmd(), 'clean'], cwd=p.dir)
+                    
+                run([gmake_cmd()], cwd=p.dir)
+                built.add(p.name)
+            continue
+        else:
+            if not args.java:
+                continue
+
+        
+        outputDir = p.output_dir()
+        if exists(outputDir):
+            if args.clean:
+                log('Cleaning {0}...'.format(outputDir))
+                shutil.rmtree(outputDir)
+                os.mkdir(outputDir)
+        else:
+            os.mkdir(outputDir)
+
+        cp = classpath(p.name, includeSelf=True)
+        sourceDirs = p.source_dirs()
+        mustBuild = args.force
+        if not mustBuild:
+            for dep in p.all_deps([], False):
+                if dep.name in built:
+                    mustBuild = True
+            
+        javafilelist = []
+        for sourceDir in sourceDirs:
+            for root, _, files in os.walk(sourceDir):
+                javafiles = [join(root, name) for name in files if name.endswith('.java') and name != 'package-info.java']
+                javafilelist += javafiles
+                
+                # Copy all non Java resources
+                nonjavafilelist = [join(root, name) for name in files if not name.endswith('.java')]
+                for src in nonjavafilelist:
+                    dst = join(outputDir, src[len(sourceDir) + 1:])
+                    if exists(dirname(dst)) and (not exists(dst) or os.path.getmtime(dst) != os.path.getmtime(src)):
+                        shutil.copyfile(src, dst)
+                
+                if not mustBuild:
+                    for javafile in javafiles:
+                        classfile = outputDir + javafile[len(sourceDir):-len('java')] + 'class'
+                        if not exists(classfile) or os.path.getmtime(javafile) > os.path.getmtime(classfile):
+                            mustBuild = True
+                            break
+                
+        if not mustBuild:
+            log('[all class files for {0} are up to date - skipping]'.format(p.name))
+            continue
+            
+        if len(javafilelist) == 0:
+            log('[no Java sources for {0} - skipping]'.format(p.name))
+            continue
+
+        built.add(p.name)
+
+        argfileName = join(p.dir, 'javafilelist.txt')
+        argfile = open(argfileName, 'wb')
+        argfile.write('\n'.join(javafilelist))
+        argfile.close()
+        
+        try:
+            if jdtJar is None:
+                log('Compiling Java sources for {0} with javac...'.format(p.name))
+                errFilt = None
+                if not args.warnAPI:
+                    class Filter:
+                        """
+                        Class to errFilt the 'is Sun proprietary API and may be removed in a future release'
+                        warning when compiling the VM classes.
+                        
+                        """
+                        def __init__(self):
+                            self.c = 0
+                        
+                        def eat(self, line):
+                            if 'proprietary API' in line:
+                                self.c = 2
+                            elif self.c != 0:
+                                self.c -= 1
+                            else:
+                                log(line.rstrip())
+                    errFilt=Filter().eat
+                    
+                run([java().javac, '-g', '-J-Xmx1g', '-source', args.compliance, '-classpath', cp, '-d', outputDir, '@' + argfile.name], err=errFilt)
+            else:
+                log('Compiling Java sources for {0} with JDT...'.format(p.name))
+                jdtProperties = join(p.dir, '.settings', 'org.eclipse.jdt.core.prefs')
+                if not exists(jdtProperties):
+                    raise SystemError('JDT properties file {0} not found'.format(jdtProperties))
+                run([java().java, '-Xmx1g', '-jar', jdtJar,
+                         '-properties', jdtProperties,
+                         '-' + args.compliance,
+                         '-cp', cp, '-g',
+                         '-warn:-unusedImport,-unchecked',
+                         '-d', outputDir, '@' + argfile.name])
+        finally:
+            os.remove(argfileName)
+                    
+    if suppliedParser:
+        return args
+    return None
+
+def canonicalizeprojects(args):
+    """process all project files to canonicalize the dependencies
+
+    The exit code of this command reflects how many files were updated."""
+    
+    changedFiles = 0
+    for s in suites():
+        projectsFile = join(s.dir, 'mx', 'projects')
+        if not exists(projectsFile):
+            continue
+        with open(projectsFile) as f:
+            out = StringIO.StringIO()
+            pattern = re.compile('project@([^@]+)@dependencies=.*')
+            for line in f:
+                line = line.strip()
+                m = pattern.match(line)
+                if m is None:
+                    out.write(line + '\n')
+                else:
+                    p = project(m.group(1))
+                    out.write('project@' + m.group(1) + '@dependencies=' + ','.join(p.canonical_deps()) + '\n')
+            content = out.getvalue()
+        if update_file(projectsFile, content):
+            changedFiles += 1
+    return changedFiles;
+    
+def checkstyle(args):
+    """run Checkstyle on the Java sources
+
+   Run Checkstyle over the Java sources. Any errors or warnings
+   produced by Checkstyle result in a non-zero exit code.
+
+If no projects are given, then all Java projects are checked."""
+    
+    for p in sorted_deps():
+        if p.native:
+            continue
+        sourceDirs = p.source_dirs()
+        dotCheckstyle = join(p.dir, '.checkstyle')
+        
+        if not exists(dotCheckstyle):
+            continue
+        
+        for sourceDir in sourceDirs:
+            javafilelist = []
+            for root, _, files in os.walk(sourceDir):
+                javafilelist += [join(root, name) for name in files if name.endswith('.java') and name != 'package-info.java']
+            if len(javafilelist) == 0:
+                log('[no Java sources in {0} - skipping]'.format(sourceDir))
+                continue
+
+            timestampFile = join(p.suite.dir, 'mx', '.checkstyle' + sourceDir[len(p.suite.dir):].replace(os.sep, '_') + '.timestamp')
+            mustCheck = False
+            if exists(timestampFile):
+                timestamp = os.path.getmtime(timestampFile)
+                for f in javafilelist:
+                    if os.path.getmtime(f) > timestamp:
+                        mustCheck = True
+                        break
+            else:
+                mustCheck = True
+            
+            if not mustCheck:
+                log('[all Java sources in {0} already checked - skipping]'.format(sourceDir))
+                continue
+
+            if exists(timestampFile):                
+                os.utime(timestampFile, None)
+            else:
+                file(timestampFile, 'a')
+            
+            dotCheckstyleXML = xml.dom.minidom.parse(dotCheckstyle)
+            localCheckConfig = dotCheckstyleXML.getElementsByTagName('local-check-config')[0]
+            configLocation = localCheckConfig.getAttribute('location')
+            configType = localCheckConfig.getAttribute('type')
+            if configType == 'project':
+                # Eclipse plugin "Project Relative Configuration" format:
+                #
+                #  '/<project_name>/<suffix>'
+                #
+                if configLocation.startswith('/'):
+                    name, _, suffix = configLocation.lstrip('/').partition('/')
+                    config = join(project(name).dir, suffix)
+                else:
+                    config = join(p.dir, configLocation)
+            else:
+                log('[unknown Checkstyle configuration type "' + configType + '" in {0} - skipping]'.format(sourceDir))
+                continue
+                
+            exclude = join(p.dir, '.checkstyle.exclude')
+            
+            if exists(exclude):
+                with open(exclude) as f:
+                    # Convert patterns to OS separators
+                    patterns = [name.rstrip().replace('/', os.sep) for name in f.readlines()]
+                def match(name):
+                    for p in patterns:
+                        if p in name:
+                            log('excluding: ' + name)
+                            return True
+                    return False
+                    
+                javafilelist = [name for name in javafilelist if not match(name)]
+            
+            auditfileName = join(p.dir, 'checkstyleOutput.txt')
+            log('Running Checkstyle on {0} using {1}...'.format(sourceDir, config))
+            
+            try:
+
+                # Checkstyle is unable to read the filenames to process from a file, and the
+                # CreateProcess function on Windows limits the length of a command line to
+                # 32,768 characters (http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx)
+                # so calling Checkstyle must be done in batches.
+                while len(javafilelist) != 0:
+                    i = 0
+                    size = 0
+                    while i < len(javafilelist):
+                        s = len(javafilelist[i]) + 1
+                        if (size + s < 30000):
+                            size += s
+                            i += 1
+                        else:
+                            break
+                    
+                    batch = javafilelist[:i]
+                    javafilelist = javafilelist[i:]
+                    try:
+                        run_java(['-Xmx1g', '-jar', library('CHECKSTYLE').get_path(True), '-c', config, '-o', auditfileName] + batch)
+                    finally:
+                        if exists(auditfileName):
+                            with open(auditfileName) as f:
+                                warnings = [line.strip() for line in f if 'warning:' in line]
+                                if len(warnings) != 0:
+                                    map(log, warnings)
+                                    return 1
+            finally:
+                if exists(auditfileName):
+                    os.unlink(auditfileName)
+    return 0
+
+def clean(args, parser=None):
+    """remove all class files, images, and executables
+
+    Removes all files created by a build, including Java class files, executables, and
+    generated images.
+    """
+
+    suppliedParser = parser is not None
+    
+    parser = parser if suppliedParser else ArgumentParser(prog='mx build');
+    parser.add_argument('--no-native', action='store_false', dest='native', help='do not clean native projects')
+    parser.add_argument('--no-java', action='store_false', dest='java', help='do not clean Java projects')
+
+    args = parser.parse_args(args)
+    
+    for p in projects():
+        if p.native:
+            if args.native:
+                run([gmake_cmd(), '-C', p.dir, 'clean'])
+        else:
+            if args.java:
+                outputDir = p.output_dir()
+                if outputDir != '' and exists(outputDir):
+                    log('Removing {0}...'.format(outputDir))
+                    shutil.rmtree(outputDir)
+                    
+    if suppliedParser:
+        return args
+    
+def help_(args):
+    """show help for a given command
+
+With no arguments, print a list of commands and short help for each command.
+
+Given a command name, print help for that command."""
+    if len(args) == 0:
+        _argParser.print_help()
+        return
+    
+    name = args[0]
+    if not commands.has_key(name):
+        _argParser.error('unknown command: ' + name)
+    
+    value = commands[name]
+    (func, usage) = value[:2]
+    doc = func.__doc__
+    if len(value) > 2:
+        docArgs = value[2:]
+        fmtArgs = []
+        for d in docArgs:
+            if isinstance(d, Callable):
+                fmtArgs += [d()]
+            else:
+                fmtArgs += [str(d)]
+        doc = doc.format(*fmtArgs)
+    print 'mx {0} {1}\n\n{2}\n'.format(name, usage, doc)
+
+def projectgraph(args, suite=None):
+    """create dot graph for project structure ("mx projectgraph | dot -Tpdf -oprojects.pdf")"""
+    
+    print 'digraph projects {'
+    print 'rankdir=BT;'
+    print 'node [shape=rect];'
+    for p in projects():
+        for dep in p.canonical_deps():
+            print '"' + p.name + '"->"' + dep + '"'
+    print '}'
+
+def eclipseinit(args, suite=None):
+    """(re)generate Eclipse project configurations"""
+
+    if suite is None:
+        suite = _mainSuite
+        
+    def println(out, obj):
+        out.write(str(obj) + '\n')
+        
+    for p in projects():
+        if p.native:
+            continue
+        
+        if not exists(p.dir):
+            os.makedirs(p.dir)
+
+        out = StringIO.StringIO()
+        
+        println(out, '<?xml version="1.0" encoding="UTF-8"?>')
+        println(out, '<classpath>')
+        for src in p.srcDirs:
+            srcDir = join(p.dir, src)
+            if not exists(srcDir):
+                os.mkdir(srcDir)
+            println(out, '\t<classpathentry kind="src" path="' + src + '"/>')
+    
+        # Every Java program depends on the JRE
+        println(out, '\t<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>')
+        
+        for dep in p.all_deps([], True):
+            if dep == p:
+                continue;
+            
+            if dep.isLibrary():
+                if hasattr(dep, 'eclipse.container'):
+                    println(out, '\t<classpathentry exported="true" kind="con" path="' + getattr(dep, 'eclipse.container') + '"/>')
+                elif hasattr(dep, 'eclipse.project'):
+                    println(out, '\t<classpathentry combineaccessrules="false" exported="true" kind="src" path="/' + getattr(dep, 'eclipse.project') + '"/>')
+                else:
+                    path = dep.path
+                    if dep.mustExist:
+                        dep.get_path(resolve=True)
+                        if isabs(path):
+                            println(out, '\t<classpathentry exported="true" kind="lib" path="' + path + '"/>')
+                        else:
+                            println(out, '\t<classpathentry exported="true" kind="lib" path="' + join(suite.dir, path) + '"/>')
+            else:
+                println(out, '\t<classpathentry combineaccessrules="false" exported="true" kind="src" path="/' + dep.name + '"/>')
+                        
+        println(out, '\t<classpathentry kind="output" path="' + getattr(p, 'eclipse.output', 'bin') + '"/>')
+        println(out, '</classpath>')
+        update_file(join(p.dir, '.classpath'), out.getvalue())
+        out.close()
+
+        csConfig = join(project(p.checkstyleProj).dir, '.checkstyle_checks.xml')
+        if exists(csConfig):
+            out = StringIO.StringIO()
+            
+            dotCheckstyle = join(p.dir, ".checkstyle")
+            checkstyleConfigPath = '/' + p.checkstyleProj + '/.checkstyle_checks.xml'
+            println(out, '<?xml version="1.0" encoding="UTF-8"?>')
+            println(out, '<fileset-config file-format-version="1.2.0" simple-config="true">')
+            println(out, '\t<local-check-config name="Checks" location="' + checkstyleConfigPath + '" type="project" description="">')
+            println(out, '\t\t<additional-data name="protect-config-file" value="false"/>')
+            println(out, '\t</local-check-config>')
+            println(out, '\t<fileset name="all" enabled="true" check-config-name="Checks" local="true">')
+            println(out, '\t\t<file-match-pattern match-pattern="." include-pattern="true"/>')
+            println(out, '\t</fileset>')
+            println(out, '\t<filter name="FileTypesFilter" enabled="true">')
+            println(out, '\t\t<filter-data value="java"/>')
+            println(out, '\t</filter>')
+
+            exclude = join(p.dir, '.checkstyle.exclude')
+            if exists(exclude):
+                println(out, '\t<filter name="FilesFromPackage" enabled="true">')
+                with open(exclude) as f:
+                    for line in f:
+                        if not line.startswith('#'):
+                            line = line.strip()
+                            exclDir = join(p.dir, line)
+                            assert isdir(exclDir), 'excluded source directory listed in ' + exclude + ' does not exist or is not a directory: ' + exclDir
+                        println(out, '\t\t<filter-data value="' + line + '"/>')
+                println(out, '\t</filter>')
+                        
+            println(out, '</fileset-config>')
+            update_file(dotCheckstyle, out.getvalue())
+            out.close()
+        
+
+        out = StringIO.StringIO()
+        
+        println(out, '<?xml version="1.0" encoding="UTF-8"?>')
+        println(out, '<projectDescription>')
+        println(out, '\t<name>' + p.name + '</name>')
+        println(out, '\t<comment></comment>')
+        println(out, '\t<projects>')
+        println(out, '\t</projects>')
+        println(out, '\t<buildSpec>')
+        println(out, '\t\t<buildCommand>')
+        println(out, '\t\t\t<name>org.eclipse.jdt.core.javabuilder</name>')
+        println(out, '\t\t\t<arguments>')
+        println(out, '\t\t\t</arguments>')
+        println(out, '\t\t</buildCommand>')
+        if exists(csConfig):
+            println(out, '\t\t<buildCommand>')
+            println(out, '\t\t\t<name>net.sf.eclipsecs.core.CheckstyleBuilder</name>')
+            println(out, '\t\t\t<arguments>')
+            println(out, '\t\t\t</arguments>')
+            println(out, '\t\t</buildCommand>')
+        println(out, '\t</buildSpec>')
+        println(out, '\t<natures>')
+        println(out, '\t\t<nature>org.eclipse.jdt.core.javanature</nature>')
+        if exists(csConfig):
+            println(out, '\t\t<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>')
+        println(out, '\t</natures>')
+        println(out, '</projectDescription>')
+        update_file(join(p.dir, '.project'), out.getvalue())
+        out.close()
+
+        out = StringIO.StringIO()
+        settingsDir = join(p.dir, ".settings")
+        if not exists(settingsDir):
+            os.mkdir(settingsDir)
+
+        eclipseSettingsDir = join(suite.dir, 'mx', 'eclipse-settings')
+        if exists(eclipseSettingsDir):
+            for name in os.listdir(eclipseSettingsDir):
+                path = join(eclipseSettingsDir, name)
+                if isfile(path):
+                    with open(join(eclipseSettingsDir, name)) as f:
+                        content = f.read()
+                    update_file(join(settingsDir, name), content)
+
+def netbeansinit(args, suite=None):
+    """(re)generate NetBeans project configurations"""
+
+    if suite is None:
+        suite = _mainSuite
+
+    def println(out, obj):
+        out.write(str(obj) + '\n')
+        
+    updated = False
+    for p in projects():
+        if p.native:
+            continue
+        
+        if not exists(join(p.dir, 'nbproject')):
+            os.makedirs(join(p.dir, 'nbproject'))
+
+        out = StringIO.StringIO()
+        
+        println(out, '<?xml version="1.0" encoding="UTF-8"?>')
+        println(out, '<project name="' + p.name + '" default="default" basedir=".">')
+        println(out, '\t<description>Builds, tests, and runs the project ' + p.name + '.</description>')
+        println(out, '\t<import file="nbproject/build-impl.xml"/>')
+        println(out, '</project>')
+        updated = update_file(join(p.dir, 'build.xml'), out.getvalue()) or updated
+        out.close()
+        
+        out = StringIO.StringIO()
+        println(out, '<?xml version="1.0" encoding="UTF-8"?>')
+        println(out, '<project xmlns="http://www.netbeans.org/ns/project/1">')
+        println(out, '    <type>org.netbeans.modules.java.j2seproject</type>')
+        println(out, '    <configuration>')
+        println(out, '        <data xmlns="http://www.netbeans.org/ns/j2se-project/3">')
+        println(out, '            <name>' + p.name+ '</name>')
+        println(out, '            <explicit-platform explicit-source-supported="true"/>')
+        println(out, '            <source-roots>')
+        println(out, '                <root id="src.dir"/>')
+        println(out, '            </source-roots>')
+        println(out, '            <test-roots>')
+        println(out, '                <root id="test.src.dir"/>')
+        println(out, '            </test-roots>')
+        println(out, '        </data>')
+        
+        firstDep = True
+        for dep in p.all_deps([], True):
+            if dep == p:
+                continue;
+            
+            if not dep.isLibrary():
+                n = dep.name.replace('.', '_')
+                if firstDep:
+                    println(out, '        <references xmlns="http://www.netbeans.org/ns/ant-project-references/1">')
+                    firstDep = False
+                    
+                println(out, '            <reference>')
+                println(out, '                <foreign-project>' + n + '</foreign-project>')
+                println(out, '                <artifact-type>jar</artifact-type>')
+                println(out, '                <script>build.xml</script>')
+                println(out, '                <target>jar</target>')
+                println(out, '                <clean-target>clean</clean-target>')
+                println(out, '                <id>jar</id>')
+                println(out, '            </reference>')
+            
+        if not firstDep:
+            println(out, '        </references>')
+            
+        println(out, '    </configuration>')
+        println(out, '</project>')
+        updated = update_file(join(p.dir, 'nbproject', 'project.xml'), out.getvalue()) or updated
+        out.close()
+        
+        out = StringIO.StringIO()
+        
+        jdkPlatform = 'JDK_' + java().version
+        
+        content = """
+annotation.processing.enabled=false
+annotation.processing.enabled.in.editor=false
+annotation.processing.processors.list=
+annotation.processing.run.all.processors=true
+annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
+application.title=""" + p.name + """
+application.vendor=mx
+build.classes.dir=${build.dir}
+build.classes.excludes=**/*.java,**/*.form
+# This directory is removed when the project is cleaned:
+build.dir=bin
+build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
+# Only compile against the classpath explicitly listed here:
+build.sysclasspath=ignore
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+# Uncomment to specify the preferred debugger connection transport:
+#debug.transport=dt_socket
+debug.classpath=\\
+    ${run.classpath}
+debug.test.classpath=\\
+    ${run.test.classpath}
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/""" + p.name + """.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+endorsed.classpath=
+excludes=
+includes=**
+jar.compress=false
+# Space-separated list of extra javac options
+javac.compilerargs=
+javac.deprecation=false
+javac.processorpath=\\
+    ${javac.classpath}
+javac.source=1.7
+javac.target=1.7
+javac.test.classpath=\\
+    ${javac.classpath}:\\
+    ${build.classes.dir}
+javac.test.processorpath=\\
+    ${javac.test.classpath}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+main.class=
+manifest.file=manifest.mf
+meta.inf.dir=${src.dir}/META-INF
+mkdist.disabled=false
+platforms.""" + jdkPlatform + """.home=""" + java().jdk + """
+platform.active=""" + jdkPlatform + """
+run.classpath=\\
+    ${javac.classpath}:\\
+    ${build.classes.dir}
+# Space-separated list of JVM arguments used when running the project
+# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
+# or test-sys-prop.name=value to set system properties for unit tests):
+run.jvmargs=
+run.test.classpath=\\
+    ${javac.test.classpath}:\\
+    ${build.test.classes.dir}
+test.src.dir=
+source.encoding=UTF-8""".replace(':', os.pathsep).replace('/', os.sep)
+        println(out, content)
+
+        mainSrc = True
+        for src in p.srcDirs:
+            srcDir = join(p.dir, src)
+            if not exists(srcDir):
+                os.mkdir(srcDir)
+            ref = 'file.reference.' + p.name + '-' + src
+            println(out, ref + '=' + src)
+            if mainSrc:
+                println(out, 'src.dir=${' + ref + '}')
+                mainSrc = False
+            else:
+                println(out, 'src.' + src + '.dir=${' + ref + '}')
+            
+        javacClasspath = []    
+        for dep in p.all_deps([], True):
+            if dep == p:
+                continue;
+            
+            if dep.isLibrary():
+                if not dep.mustExist:
+                    continue
+                path = dep.get_path(resolve=True)
+                if os.sep == '\\':
+                    path = path.replace('\\', '\\\\')
+                ref = 'file.reference.' + dep.name + '-bin'
+                println(out, ref + '=' + path)
+                    
+            else:
+                n = dep.name.replace('.', '_')
+                relDepPath = os.path.relpath(dep.dir, p.dir).replace(os.sep, '/')
+                ref = 'reference.' + n + '.jar'
+                println(out, 'project.' + n + '=' + relDepPath)
+                println(out, ref + '=${project.' + n + '}/dist/' + dep.name + '.jar')
+                
+            javacClasspath.append('${' + ref + '}')
+            
+        println(out, 'javac.classpath=\\\n    ' + (os.pathsep + '\\\n    ').join(javacClasspath))
+        
+
+        updated = update_file(join(p.dir, 'nbproject', 'project.properties'), out.getvalue()) or updated
+        out.close()
+    
+    if updated:
+        log('If using NetBeans:')
+        log('  1. Ensure that a platform named "JDK ' + java().version + '" is defined (Tools -> Java Platforms)')
+        log('  2. Open/create a Project Group for the directory containing the projects (File -> Project Group -> New Group... -> Folder of Projects)')
+
+def ideclean(args, suite=None):
+    """remove all Eclipse and NetBeans project configurations"""
+    
+    def rm(path):
+        if exists(path):
+            os.remove(path)
+    
+    for p in projects():
+        if p.native:
+            continue
+        
+        shutil.rmtree(join(p.dir, '.settings'), ignore_errors=True)
+        shutil.rmtree(join(p.dir, 'nbproject'), ignore_errors=True)
+        rm(join(p.dir, '.classpath'))
+        rm(join(p.dir, '.project'))
+        rm(join(p.dir, 'build.xml'))
+        
+def ideinit(args, suite=None):
+    """(re)generate Eclipse and NetBeans project configurations"""
+    eclipseinit(args, suite)
+    netbeansinit(args, suite)
+
+def javap(args):
+    """launch javap with a -classpath option denoting all available classes
+
+    Run the JDK javap class file disassembler with the following prepended options:
+
+        -private -verbose -classpath <path to project classes>"""
+        
+    javap = java().javap
+    if not exists(javap):
+        abort('The javap executable does not exists: ' + javap)
+    else:
+        run([javap, '-private', '-verbose', '-classpath', classpath()] + args)
+
+def show_projects(args):
+    """show all loaded projects"""
+    for s in suites():
+        projectsFile = join(s.dir, 'mx', 'projects')
+        if exists(projectsFile):
+            log(projectsFile)
+            for p in s.projects:
+                log('\t' + p.name)
+
+def add_argument(*args, **kwargs):
+    """
+    Define how a single command-line argument.
+    """
+    assert _argParser is not None
+    _argParser.add_argument(*args, **kwargs)
+    
+# Table of commands in alphabetical order.
+# Keys are command names, value are lists: [<function>, <usage msg>, <format args to doc string of function>...]
+# If any of the format args are instances of Callable, then they are called with an 'env' are before being
+# used in the call to str.format().  
+# Extensions should update this table directly
+commands = {
+    'build': [build, '[options]'],
+    'checkstyle': [checkstyle, ''],
+    'canonicalizeprojects': [canonicalizeprojects, ''],
+    'clean': [clean, ''],
+    'eclipseinit': [eclipseinit, ''],
+    'help': [help_, '[command]'],
+    'ideclean': [ideclean, ''],
+    'ideinit': [ideinit, ''],
+    'projectgraph': [projectgraph, ''],
+    'javap': [javap, ''],
+    'netbeansinit': [netbeansinit, ''],
+    'projects': [show_projects, ''],
+}
+
+_argParser = ArgParser()
+
+def main():
+    cwdMxDir = join(os.getcwd(), 'mx')
+    if exists(cwdMxDir) and isdir(cwdMxDir):
+        global _mainSuite
+        _mainSuite = _loadSuite(os.getcwd(), True)
+            
+    opts, commandAndArgs = _argParser._parse_cmd_line()
+    
+    global _opts, _java
+    _opts = opts
+    _java = JavaConfig(opts)
+    
+    for s in suites():
+        s._post_init(opts)
+    
+    if len(commandAndArgs) == 0:
+        _argParser.print_help()
+        return
+    
+    command = commandAndArgs[0]
+    command_args = commandAndArgs[1:]
+    
+    if not commands.has_key(command):
+        abort('mx: unknown command \'{0}\'\n{1}use "mx help" for more options'.format(command, _format_commands()))
+        
+    c, _ = commands[command][:2]
+    def term_handler(signum, frame):
+        abort(1)
+    signal.signal(signal.SIGTERM, term_handler)
+    try:
+        if opts.timeout != 0:
+            def alarm_handler(signum, frame):
+                abort('Command timed out after ' + str(opts.timeout) + ' seconds: ' + ' '.join(commandAndArgs))
+            signal.signal(signal.SIGALRM, alarm_handler)
+            signal.alarm(opts.timeout)
+        retcode = c(command_args)
+        if retcode is not None and retcode != 0:
+            abort(retcode)
+    except KeyboardInterrupt:
+        # no need to show the stack trace when the user presses CTRL-C
+        abort(1)
+
+if __name__ == '__main__':
+    # rename this module as 'mx' so it is not imported twice by the commands.py modules
+    sys.modules['mx'] = sys.modules.pop('__main__')
+
+    main()
--- a/src/cpu/sparc/vm/methodHandles_sparc.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -876,14 +876,7 @@
   }
 #endif
   __ cmp_and_brx_short(bottom_reg, top_reg, Assembler::greaterEqualUnsigned, Assembler::pn, L_break);
-  // work top down to bottom, copying contiguous data upwards
-  // In pseudo-code:
-  //   while (--top >= bottom) *(top + distance) = *(top + 0);
-  RegisterOrConstant offset = __ argument_offset(positive_distance_in_slots, positive_distance_in_slots.register_or_noreg());
-  __ BIND(L_loop);
-  __ sub(top_reg, wordSize, top_reg);
-  __ ld_ptr(           Address(top_reg, 0     ), temp2_reg);
-  __ st_ptr(temp2_reg, Address(top_reg, offset)           );
+>>
   __ cmp_and_brx_short(top_reg, bottom_reg, Assembler::greaterUnsigned, Assembler::pt, L_loop);
   assert(Interpreter::stackElementSize == wordSize, "else change loop");
   __ BIND(L_break);
--- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -436,7 +436,7 @@
 #undef __
 #define __ masm->
 
-  address generate_throw_exception(const char* name, address runtime_entry,
+  address generate_throw_exception(const char* name, address runtime_entry, bool restore_saved_exception_pc,
                                    Register arg1 = noreg, Register arg2 = noreg) {
 #ifdef ASSERT
     int insts_size = VerifyThread ? 1 * K : 600;
--- a/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -35,7 +35,7 @@
 #include "runtime/os.hpp"
 #include "runtime/stubRoutines.hpp"
 
-int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register scratch, Label& slow_case) {
+int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register scratch, Label& slow_case, bool use_basic_object_lock) {
   const int aligned_mask = BytesPerWord -1;
   const int hdr_offset = oopDesc::mark_offset_in_bytes();
   assert(hdr == rax, "hdr must be rax, for the cmpxchg instruction");
@@ -45,8 +45,10 @@
 
   verify_oop(obj);
 
-  // save object being locked into the BasicObjectLock
-  movptr(Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()), obj);
+  if (use_basic_object_lock) {
+    // save object being locked into the BasicObjectLock
+    movptr(Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()), obj);
+  }
 
   if (UseBiasedLocking) {
     assert(scratch != noreg, "should have scratch register at this point");
@@ -98,7 +100,7 @@
 }
 
 
-void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
+void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case, bool use_basic_object_lock) {
   const int aligned_mask = BytesPerWord -1;
   const int hdr_offset = oopDesc::mark_offset_in_bytes();
   assert(disp_hdr == rax, "disp_hdr must be rax, for the cmpxchg instruction");
@@ -106,8 +108,10 @@
   Label done;
 
   if (UseBiasedLocking) {
-    // load object
-    movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
+    if (use_basic_object_lock) {
+      // load object
+      movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
+    }
     biased_locking_exit(obj, hdr, done);
   }
 
@@ -118,8 +122,10 @@
   // if we had recursive locking, we are done
   jcc(Assembler::zero, done);
   if (!UseBiasedLocking) {
-    // load object
-    movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
+    if (use_basic_object_lock) {
+      // load object
+      movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
+    }
   }
   verify_oop(obj);
   // test if object header is pointing to the displaced header, and if so, restore
@@ -283,11 +289,12 @@
       jcc(Assembler::notZero, loop);
     }
   }
-
-  if (CURRENT_ENV->dtrace_alloc_probes()) {
-    assert(obj == rax, "must be");
-    call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
-  }
+  
+  // (tw) fix me
+//  if (CURRENT_ENV->dtrace_alloc_probes()) {
+//    assert(obj == rax, "must be");
+//    call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
+//  }
 
   verify_oop(obj);
 }
@@ -317,10 +324,11 @@
   const Register len_zero = len;
   initialize_body(obj, arr_size, header_size * BytesPerWord, len_zero);
 
-  if (CURRENT_ENV->dtrace_alloc_probes()) {
-    assert(obj == rax, "must be");
-    call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
-  }
+  // TODO(tw): Re-enable this code once Graal no longer uses this method.
+//  if (CURRENT_ENV->dtrace_alloc_probes()) {
+//    assert(obj == rax, "must be");
+//    call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
+//  }
 
   verify_oop(obj);
 }
--- a/src/cpu/x86/vm/c1_MacroAssembler_x86.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/cpu/x86/vm/c1_MacroAssembler_x86.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -51,13 +51,13 @@
   // disp_hdr: must point to the displaced header location, contents preserved
   // scratch : scratch register, contents destroyed
   // returns code offset at which to add null check debug information
-  int lock_object  (Register swap, Register obj, Register disp_hdr, Register scratch, Label& slow_case);
+  int lock_object  (Register swap, Register obj, Register disp_hdr, Register scratch, Label& slow_case, bool use_basic_object_lock = true);
 
   // unlocking
   // hdr     : contents destroyed
   // obj     : must point to the object to lock, contents preserved
   // disp_hdr: must be eax & must point to the displaced header location, contents destroyed
-  void unlock_object(Register swap, Register obj, Register lock, Label& slow_case);
+  void unlock_object(Register swap, Register obj, Register lock, Label& slow_case, bool use_basic_object_lock = true);
 
   void initialize_object(
     Register obj,                      // result: pointer to object after successful allocation
--- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -38,6 +38,7 @@
 #include "runtime/vframeArray.hpp"
 #include "vmreg_x86.inline.hpp"
 
+static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true);
 
 // Implementation of StubAssembler
 
@@ -96,14 +97,12 @@
     if (oop_result2->is_valid()) {
       movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD);
     }
-    if (frame_size() == no_frame_size) {
-      leave();
-      jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
-    } else if (_stub_id == Runtime1::forward_exception_id) {
-      should_not_reach_here();
-    } else {
-      jump(RuntimeAddress(Runtime1::entry_for(Runtime1::forward_exception_id)));
-    }
+    // (tw) Deoptimize in case of an exception.
+    restore_live_registers(this, false);
+    movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD);
+    leave();
+    movl(rscratch1, 2); // InvalidateRecompile
+    jump(RuntimeAddress(SharedRuntime::deopt_blob()->uncommon_trap()));
     bind(L);
   }
   // get oop results if there are any and reset the values in the thread
@@ -539,7 +538,7 @@
 }
 
 
-static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true) {
+static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers/* = true*/) {
   __ block_comment("restore_live_registers");
 
   restore_fpu(sasm, restore_fpu_registers);
@@ -593,30 +592,50 @@
 // has_argument: true if the exception needs an argument (passed on stack because registers must be preserved)
 
 OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address target, bool has_argument) {
-  // preserve all registers
-  int num_rt_args = has_argument ? 2 : 1;
-  OopMap* oop_map = save_live_registers(sasm, num_rt_args);
+  OopMapSet* oop_maps = new OopMapSet();
+#ifdef GRAAL
+    // graal passes the argument in r10
+    OopMap* oop_map = save_live_registers(sasm, 1);
+
+    // now all registers are saved and can be used freely
+    // verify that no old value is used accidentally
+    __ invalidate_registers(true, true, true, true, true, true);
 
-  // now all registers are saved and can be used freely
-  // verify that no old value is used accidentally
-  __ invalidate_registers(true, true, true, true, true, true);
+    // registers used by this stub
+    const Register temp_reg = rbx;
 
-  // registers used by this stub
-  const Register temp_reg = rbx;
+    // load argument for exception that is passed as an argument into the stub
+    if (has_argument) {
+      __ movptr(c_rarg1, r10);
+    }
+    int call_offset = __ call_RT(noreg, noreg, target, has_argument ? 1 : 0);
 
-  // load argument for exception that is passed as an argument into the stub
-  if (has_argument) {
-#ifdef _LP64
-    __ movptr(c_rarg1, Address(rbp, 2*BytesPerWord));
+    oop_maps->add_gc_map(call_offset, oop_map);
 #else
-    __ movptr(temp_reg, Address(rbp, 2*BytesPerWord));
-    __ push(temp_reg);
-#endif // _LP64
-  }
-  int call_offset = __ call_RT(noreg, noreg, target, num_rt_args - 1);
+    // preserve all registers
+    int num_rt_args = has_argument ? 2 : 1;
+    OopMap* oop_map = save_live_registers(sasm, num_rt_args);
+
+    // now all registers are saved and can be used freely
+    // verify that no old value is used accidentally
+    __ invalidate_registers(true, true, true, true, true, true);
+
+    // registers used by this stub
+    const Register temp_reg = rbx;
 
-  OopMapSet* oop_maps = new OopMapSet();
-  oop_maps->add_gc_map(call_offset, oop_map);
+    // load argument for exception that is passed as an argument into the stub
+    if (has_argument) {
+  #ifdef _LP64
+      __ movptr(c_rarg1, Address(rbp, 2*BytesPerWord));
+  #else
+      __ movptr(temp_reg, Address(rbp, 2*BytesPerWord));
+      __ push(temp_reg);
+  #endif // _LP64
+    }
+    int call_offset = __ call_RT(noreg, noreg, target, num_rt_args - 1);
+
+    oop_maps->add_gc_map(call_offset, oop_map);
+#endif
 
   __ stop("should not reach here");
 
@@ -961,6 +980,37 @@
   return oop_maps;
 }
 
+JRT_ENTRY(void, graal_create_null_exception(JavaThread* thread))
+  thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_NullPointerException(), NULL)());
+JRT_END
+
+JRT_ENTRY(void, graal_create_out_of_bounds_exception(JavaThread* thread, jint index))
+  char message[jintAsStringSize];
+  sprintf(message, "%d", index);
+  thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message)());
+JRT_END
+
+JRT_ENTRY(void, graal_generic_callback(JavaThread* thread, oop _callback, oop _argument))
+  HandleMark hm;
+  Handle callback(_callback);
+  Handle argument(_argument);
+
+  KlassHandle klass = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_max_cri_ci_CiGenericCallback(), SystemDictionary::java_system_loader(), NULL, thread);
+  if (klass.is_null()) {
+    tty->print_cr("couldn't resolve com_oracle_max_cri_ci_CiGenericCallback");
+  }
+
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args;
+  args.push_oop(Handle(callback));
+  args.push_oop(Handle(argument));
+  JavaCalls::call_virtual(&result, klass, vmSymbols::callbackInternal_name(), vmSymbols::callback_signature(), &args, thread);
+
+  thread->set_vm_result((oop) result.get_jobject());
+JRT_END
+
+
+
 
 OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
 
@@ -1254,8 +1304,13 @@
         // will be place in C abi locations
 
 #ifdef _LP64
+#ifdef GRAAL
+        __ verify_oop(j_rarg0);
+        __ mov(rax, j_rarg0);
+#else
         __ verify_oop(c_rarg0);
         __ mov(rax, c_rarg0);
+#endif
 #else
         // The object is passed on the stack and we haven't pushed a
         // frame yet so it's one work away from top of stack.
@@ -1326,7 +1381,8 @@
       break;
 
     case unwind_exception_id:
-      { __ set_info("unwind_exception", dont_gc_arguments);
+      {
+        __ set_info("unwind_exception", dont_gc_arguments);
         // note: no stubframe since we are about to leave the current
         //       activation and we are calling a leaf VM function only.
         generate_unwind_exception(sasm);
@@ -1385,10 +1441,17 @@
         __ movptr(rsi, Address(rsp, (klass_off) * VMRegImpl::stack_slot_size)); // subclass
         __ movptr(rax, Address(rsp, (sup_k_off) * VMRegImpl::stack_slot_size)); // superclass
 
+        Label success;
         Label miss;
+#ifdef GRAAL
+          // TODO this should really be within the XirSnippets
+          __ check_klass_subtype_fast_path(rsi, rax, rcx, &success, &miss, NULL);
+#endif
+
         __ check_klass_subtype_slow_path(rsi, rax, rcx, rdi, NULL, &miss);
 
         // fallthrough on success:
+        __ bind(success);
         __ movptr(Address(rsp, (result_off) * VMRegImpl::stack_slot_size), 1); // result
         __ pop(rax);
         __ pop(rcx);
@@ -1788,6 +1851,212 @@
       break;
 #endif // !SERIALGC
 
+    case graal_unwind_exception_call_id: {
+      // remove the frame from the stack
+      __ movptr(rsp, rbp);
+      __ pop(rbp);
+      // exception_oop is passed using ordinary java calling conventions
+      __ movptr(rax, j_rarg0);
+
+      Label nonNullExceptionOop;
+      __ testptr(rax, rax);
+      __ jcc(Assembler::notZero, nonNullExceptionOop);
+      {
+        __ enter();
+        oop_maps = new OopMapSet();
+        OopMap* oop_map = save_live_registers(sasm, 0);
+        int call_offset = __ call_RT(rax, noreg, (address)graal_create_null_exception, 0);
+        oop_maps->add_gc_map(call_offset, oop_map);
+        __ leave();
+      }
+      __ bind(nonNullExceptionOop);
+
+      __ set_info("unwind_exception", dont_gc_arguments);
+      // note: no stubframe since we are about to leave the current
+      //       activation and we are calling a leaf VM function only.
+      generate_unwind_exception(sasm);
+      __ should_not_reach_here();
+      break;
+    }
+
+    case graal_set_deopt_info_id: {
+    __ movptr(Address(r15_thread, JavaThread::graal_deopt_info_offset()), rscratch1);
+    __ ret(0);
+      break;
+    }
+
+    case graal_create_null_pointer_exception_id: {
+		__ enter();
+		oop_maps = new OopMapSet();
+		OopMap* oop_map = save_live_registers(sasm, 0);
+		int call_offset = __ call_RT(rax, noreg, (address)graal_create_null_exception, 0);
+		oop_maps->add_gc_map(call_offset, oop_map);
+		__ leave();
+		__ ret(0);
+      break;
+    }
+
+    case graal_create_out_of_bounds_exception_id: {
+		__ enter();
+		oop_maps = new OopMapSet();
+		OopMap* oop_map = save_live_registers(sasm, 0);
+		int call_offset = __ call_RT(rax, noreg, (address)graal_create_out_of_bounds_exception, c_rarg0);
+		oop_maps->add_gc_map(call_offset, oop_map);
+		__ leave();
+		__ ret(0);
+      break;
+    }
+
+    case graal_generic_callback_id: {
+    __ enter();
+    oop_maps = new OopMapSet();
+    OopMap* oop_map = save_live_registers(sasm, 0);
+    int call_offset = __ call_RT(rax, noreg, (address)graal_generic_callback, j_rarg0, j_rarg1);
+    oop_maps->add_gc_map(call_offset, oop_map);
+    __ leave();
+    __ ret(0);
+      break;
+    }
+
+    case graal_slow_subtype_check_id: {
+      Label success;
+      Label miss;
+
+      // TODO this should really be within the XirSnippets
+      __ check_klass_subtype_fast_path(j_rarg0, j_rarg1, j_rarg2, &success, &miss, NULL);
+      __ check_klass_subtype_slow_path(j_rarg0, j_rarg1, j_rarg2, j_rarg3, NULL, &miss);
+
+      // fallthrough on success:
+      __ bind(success);
+      __ movptr(rax, 1);
+      __ ret(0);
+
+      __ bind(miss);
+      __ movptr(rax, NULL_WORD);
+      __ ret(0);
+      break;
+    }
+
+    case graal_verify_pointer_id: {
+      __ verify_oop(r13, "graal verify pointer");
+      __ ret(0);
+      break;
+    }
+
+    case graal_arithmetic_frem_id: {
+      __ subptr(rsp, 8);
+      __ movflt(Address(rsp, 0), xmm1);
+      __ fld_s(Address(rsp, 0));
+      __ movflt(Address(rsp, 0), xmm0);
+      __ fld_s(Address(rsp, 0));
+      Label L;
+      __ bind(L);
+      __ fprem();
+      __ fwait();
+      __ fnstsw_ax();
+      __ testl(rax, 0x400);
+      __ jcc(Assembler::notZero, L);
+      __ fxch(1);
+      __ fpop();
+      __ fstp_s(Address(rsp, 0));
+      __ movflt(xmm0, Address(rsp, 0));
+      __ addptr(rsp, 8);
+      __ ret(0);
+      break;
+    }
+    case graal_arithmetic_drem_id: {
+      __ subptr(rsp, 8);
+      __ movdbl(Address(rsp, 0), xmm1);
+      __ fld_d(Address(rsp, 0));
+      __ movdbl(Address(rsp, 0), xmm0);
+      __ fld_d(Address(rsp, 0));
+      Label L;
+      __ bind(L);
+      __ fprem();
+      __ fwait();
+      __ fnstsw_ax();
+      __ testl(rax, 0x400);
+      __ jcc(Assembler::notZero, L);
+      __ fxch(1);
+      __ fpop();
+      __ fstp_d(Address(rsp, 0));
+      __ movdbl(xmm0, Address(rsp, 0));
+      __ addptr(rsp, 8);
+      __ ret(0);
+      break;
+    }
+    case graal_monitorenter_id: {
+      Label slow_case;
+
+      Register obj = j_rarg0;
+      Register lock = j_rarg1;
+
+      Register scratch1 = rax;
+      Register scratch2 = rbx;
+      assert_different_registers(obj, lock, scratch1, scratch2);
+
+      // copied from LIR_Assembler::emit_lock
+      if (UseFastLocking) {
+        assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
+        __ lock_object(scratch1, obj, lock, scratch2, slow_case, false);
+      __ ret(0);
+      }
+
+      __ bind(slow_case);
+      {
+        StubFrame f(sasm, "graal_monitorenter", dont_gc_arguments);
+        OopMap* map = save_live_registers(sasm, 2, save_fpu_registers);
+
+        // Called with store_parameter and not C abi
+        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, graal_monitorenter), obj, lock);
+
+        oop_maps = new OopMapSet();
+        oop_maps->add_gc_map(call_offset, map);
+        restore_live_registers(sasm, save_fpu_registers);
+      }
+      __ ret(0);
+      break;
+    }
+    case graal_monitorexit_id: {
+      Label slow_case;
+
+      Register obj = j_rarg0;
+      Register lock = j_rarg1;
+
+      // needed in rax later on...
+      Register lock2 = rax;
+      __ mov(lock2, lock);
+      Register scratch1 = rbx;
+      assert_different_registers(obj, lock, scratch1, lock2);
+
+      // copied from LIR_Assembler::emit_lock
+      if (UseFastLocking) {
+        assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
+        __ unlock_object(scratch1, obj, lock2, slow_case, false);
+      __ ret(0);
+      }
+
+      __ bind(slow_case);
+      {
+        StubFrame f(sasm, "graal_monitorexit", dont_gc_arguments);
+        OopMap* map = save_live_registers(sasm, 2, save_fpu_registers);
+
+        // note: really a leaf routine but must setup last java sp
+        //       => use call_RT for now (speed can be improved by
+        //       doing last java sp setup manually)
+        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, graal_monitorexit), obj, lock);
+
+        oop_maps = new OopMapSet();
+        oop_maps->add_gc_map(call_offset, map);
+        restore_live_registers(sasm, save_fpu_registers);
+      }
+      __ ret(0);
+      break;
+    }
+
+
+
+
     default:
       { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments);
         __ movptr(rax, (int)id);
--- a/src/cpu/x86/vm/c1_globals_x86.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/cpu/x86/vm/c1_globals_x86.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -37,27 +37,27 @@
 define_pd_global(bool, ResizeTLAB,                   true );
 define_pd_global(bool, InlineIntrinsics,             true );
 define_pd_global(bool, PreferInterpreterNativeStubs, false);
-define_pd_global(bool, ProfileTraps,                 false);
+define_pd_global(bool, ProfileTraps,                 true );   // changed for GRAAL
 define_pd_global(bool, UseOnStackReplacement,        true );
 define_pd_global(bool, TieredCompilation,            false);
-define_pd_global(intx, CompileThreshold,             1500 );
+define_pd_global(intx, CompileThreshold,             4500 );   // changed for GRAAL
 define_pd_global(intx, BackEdgeThreshold,            100000);
 
 define_pd_global(intx, OnStackReplacePercentage,     933  );
 define_pd_global(intx, FreqInlineSize,               325  );
 define_pd_global(intx, NewSizeThreadIncrease,        4*K  );
-define_pd_global(intx, InitialCodeCacheSize,         160*K);
-define_pd_global(intx, ReservedCodeCacheSize,        32*M );
-define_pd_global(bool, ProfileInterpreter,           false);
-define_pd_global(intx, CodeCacheExpansionSize,       32*K );
-define_pd_global(uintx,CodeCacheMinBlockLength,      1);
+define_pd_global(intx, InitialCodeCacheSize,         4*M);      // changed for GRAAL
+define_pd_global(intx, ReservedCodeCacheSize,        48*M );    // changed for GRAAL
+define_pd_global(bool, ProfileInterpreter,           true );    // changed for GRAAL
+define_pd_global(intx, CodeCacheExpansionSize,       64*K );    // changed for GRAAL
+define_pd_global(uintx,CodeCacheMinBlockLength,      4);        // changed for GRAAL
 define_pd_global(uintx,PermSize,                     12*M );
 define_pd_global(uintx,MaxPermSize,                  64*M );
 define_pd_global(bool, NeverActAsServerClassMachine, true );
 define_pd_global(uint64_t,MaxRAM,                    1ULL*G);
 define_pd_global(bool, CICompileOSR,                 true );
+define_pd_global(intx, TypeProfileWidth,             8    );    // changed for GRAAL
 #endif // !TIERED
-define_pd_global(bool, UseTypeProfile,               false);
 define_pd_global(bool, RoundFPResults,               true );
 
 define_pd_global(bool, LIRFillDelaySlots,            false);
--- a/src/cpu/x86/vm/c2_globals_x86.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/cpu/x86/vm/c2_globals_x86.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -39,6 +39,7 @@
 define_pd_global(bool, PreferInterpreterNativeStubs, false);
 define_pd_global(bool, ProfileTraps,                 true);
 define_pd_global(bool, UseOnStackReplacement,        true);
+define_pd_global(intx, TypeProfileWidth,             2   );
 #ifdef CC_INTERP
 define_pd_global(bool, ProfileInterpreter,           false);
 #else
--- a/src/cpu/x86/vm/frame_x86.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/cpu/x86/vm/frame_x86.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -302,6 +302,11 @@
   ptr_at_put(interpreter_frame_sender_sp_offset, (intptr_t) sender_sp);
 }
 
+intptr_t** frame::interpreter_frame_sender_sp_addr() const {
+  assert(is_interpreted_frame(), "interpreted frame expected");
+  return (intptr_t**) addr_at(interpreter_frame_sender_sp_offset);
+}
+
 
 // monitor elements
 
--- a/src/cpu/x86/vm/frame_x86.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/cpu/x86/vm/frame_x86.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -198,6 +198,7 @@
 
   // expression stack tos if we are nested in a java call
   intptr_t* interpreter_frame_last_sp() const;
+  intptr_t** interpreter_frame_last_sp_addr() const;
 
   // helper to update a map with callee-saved RBP
   static void update_map_with_saved_link(RegisterMap* map, intptr_t** link_addr);
--- a/src/cpu/x86/vm/frame_x86.inline.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/cpu/x86/vm/frame_x86.inline.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -131,8 +131,9 @@
 
 
 
-inline intptr_t* frame::link() const              { return (intptr_t*) *(intptr_t **)addr_at(link_offset); }
-inline void      frame::set_link(intptr_t* addr)  { *(intptr_t **)addr_at(link_offset) = addr; }
+inline intptr_t*  frame::link() const              { return (intptr_t*) *(intptr_t **)addr_at(link_offset); }
+inline intptr_t** frame::link_addr() const         { return (intptr_t **)addr_at(link_offset); }
+inline void       frame::set_link(intptr_t* addr)  { *(intptr_t **)addr_at(link_offset) = addr; }
 
 
 inline intptr_t* frame::unextended_sp() const     { return _unextended_sp; }
@@ -208,6 +209,10 @@
   return *(intptr_t**)addr_at(interpreter_frame_last_sp_offset);
 }
 
+inline intptr_t** frame::interpreter_frame_last_sp_addr() const {
+  return (intptr_t**)addr_at(interpreter_frame_last_sp_offset);
+}
+
 inline intptr_t* frame::interpreter_frame_bcx_addr() const {
   return (intptr_t*)addr_at(interpreter_frame_bcx_offset);
 }
--- a/src/cpu/x86/vm/interp_masm_x86_64.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -1126,8 +1126,15 @@
                                         Register receiver, Register mdp,
                                         Register reg2, int start_row,
                                         Label& done, bool is_virtual_call) {
+#ifdef GRAAL
+  // change for GRAAL (use counter to indicate polymorphic case instead of failed typechecks)
+  bool use_counter_for_polymorphic_case = true;
+#else
+  bool use_counter_for_polymorphic_case = is_virtual_call;
+#endif
+
   if (TypeProfileWidth == 0) {
-    if (is_virtual_call) {
+    if (use_counter_for_polymorphic_case) {
       increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
     }
     return;
@@ -1164,7 +1171,7 @@
       testptr(reg2, reg2);
       if (start_row == last_row) {
         // The only thing left to do is handle the null case.
-        if (is_virtual_call) {
+        if (use_counter_for_polymorphic_case) {
           jccb(Assembler::zero, found_null);
           // Receiver did not match any saved receiver and there is no empty row for it.
           // Increment total counter to indicate polymorphic case.
@@ -1297,6 +1304,8 @@
 
 
 void InterpreterMacroAssembler::profile_typecheck_failed(Register mdp) {
+// changed for GRAAL (use counter to indicate polymorphism instead of failed typechecks)
+#ifndef GRAAL
   if (ProfileInterpreter && TypeProfileCasts) {
     Label profile_continue;
 
@@ -1312,6 +1321,7 @@
 
     bind (profile_continue);
   }
+#endif
 }
 
 
--- a/src/cpu/x86/vm/nativeInst_x86.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/cpu/x86/vm/nativeInst_x86.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -552,8 +552,10 @@
       return false;
     }
   } else {
-    if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
-        ubyte_at(1) == 0x05) { // 00 rax 101
+    if (ubyte_at(0) == Assembler::REX_WR && ubyte_at(1) == NativeMovRegMem::instruction_code_mem2reg && ubyte_at(2) == 0x15) { // mov r10, rip[...]
+      address fault = addr_at(7) + int_at(3);
+      return os::is_poll_address(fault);
+    } else if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl && ubyte_at(1) == 0x05) { // 00 rax 101
       address fault = addr_at(6) + int_at(2);
       return os::is_poll_address(fault);
     } else {
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -126,6 +126,7 @@
   static int rax_offset_in_bytes(void)    { return BytesPerInt * rax_off; }
   static int rdx_offset_in_bytes(void)    { return BytesPerInt * rdx_off; }
   static int rbx_offset_in_bytes(void)    { return BytesPerInt * rbx_off; }
+  static int r10_offset_in_bytes(void)    { return BytesPerInt * r10_off; }
   static int xmm0_offset_in_bytes(void)   { return BytesPerInt * xmm0_off; }
   static int return_offset_in_bytes(void) { return BytesPerInt * return_off; }
 
@@ -2973,7 +2974,7 @@
   __ push(0);
 
   // Save everything in sight.
-  map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
+  RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
 
   // Now it is safe to overwrite any register
 
@@ -3001,6 +3002,51 @@
   __ bind(no_pending_exception);
 #endif
 
+  // (tw) Start of graal uncommon trap code.
+  __ jmp(cont);
+
+  int jmp_uncommon_trap_offset = __ pc() - start;
+  __ pushptr(Address(r15_thread, in_bytes(JavaThread::ScratchA_offset())));
+  __ movptr(rscratch1, 2); // InvalidateRecompile
+
+  int uncommon_trap_offset = __ pc() - start;
+
+  // Warning: Duplicate code
+
+  // Save everything in sight.
+  RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
+
+  // Normal deoptimization
+
+
+  // fetch_unroll_info needs to call last_java_frame()
+  __ set_last_Java_frame(noreg, noreg, NULL);
+
+
+  //  __ movl(c_rarg1, (int32_t)Deoptimization::Unpack_reexecute);
+  //  __ movl(r14, c_rarg1); // save into r14 for later call to unpack_frames
+
+  assert(r10 == rscratch1, "scratch register should be r10");
+  __ movl(c_rarg1, Address(rsp, RegisterSaver::r10_offset_in_bytes()));
+  __ orq(c_rarg1, ~(int32_t)Deoptimization::make_trap_request(Deoptimization::Reason_unreached, Deoptimization::Action_none));
+  __ notq(c_rarg1);
+  __ movl(r14, (int32_t)Deoptimization::Unpack_reexecute);
+  __ mov(c_rarg0, r15_thread);
+  __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)));
+
+  // Need to have an oopmap that tells fetch_unroll_info where to
+  // find any register it might need.
+
+  oop_maps->add_gc_map( __ pc()-start, map->deep_copy());
+
+  __ reset_last_Java_frame(false, false);
+
+  Label after_fetch_unroll_info_call;
+  __ jmp(after_fetch_unroll_info_call);
+
+
+  // (tw) End of graal uncommon trap code.
+
   __ bind(cont);
 
   // Call C code.  Need thread and this frame, but NOT official VM entry
@@ -3021,6 +3067,7 @@
     __ bind(L);
   }
 #endif // ASSERT
+  
   __ mov(c_rarg0, r15_thread);
   __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::fetch_unroll_info)));
 
@@ -3030,6 +3077,8 @@
 
   __ reset_last_Java_frame(false, false);
 
+  __ bind(after_fetch_unroll_info_call);
+
   // Load UnrollBlock* into rdi
   __ mov(rdi, rax);
 
@@ -3199,6 +3248,8 @@
 
   _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words);
   _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
+  _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset);
+  _deopt_blob->set_jmp_uncommon_trap_offset(jmp_uncommon_trap_offset);
 }
 
 #ifdef COMPILER2
--- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -2186,7 +2186,7 @@
   // either at call sites or otherwise assume that stack unwinding will be initiated,
   // so caller saved registers were assumed volatile in the compiler.
   address generate_throw_exception(const char* name, address runtime_entry,
-                                   Register arg1 = noreg, Register arg2 = noreg) {
+                                   bool restore_saved_exception_pc, Register arg1 = noreg, Register arg2 = noreg) {
 
     int insts_size = 256;
     int locs_size  = 32;
--- a/src/os/linux/vm/os_linux.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/os/linux/vm/os_linux.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -3696,7 +3696,14 @@
 
 void signalHandler(int sig, siginfo_t* info, void* uc) {
   assert(info != NULL && uc != NULL, "it must be old kernel");
+  ResourceMark rm;
+  if (TraceSignals) {
+    tty->print_cr(err_msg("signal received: code=%d errno=%d signo=%d thread=%s address=%x", info->si_code, info->si_errno, info->si_signo, Thread::current()->name(), info->si_addr));
+  }
   JVM_handle_linux_signal(sig, info, uc, true);
+  if (TraceSignals) {
+    tty->print_cr("signal handled");
+  }
 }
 
 
--- a/src/os/windows/vm/os_windows.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/os/windows/vm/os_windows.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -407,7 +407,6 @@
     }
   }
 
-
   if (UseVectoredExceptions) {
     // If we are using vectored exception we don't need to set a SEH
     thread->run();
@@ -2088,9 +2087,9 @@
 #elif _M_AMD64
   PCONTEXT ctx = exceptionInfo->ContextRecord;
   address pc = (address)ctx->Rip;
-  assert(pc[0] == 0xF7, "not an idiv opcode");
-  assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
-  assert(ctx->Rax == min_jint, "unexpected idiv exception");
+  //assert(pc[0] == 0xF7 || (pc[1] == 0xF7 && (pc[0] == 0x41 || pc[0] == 0x49)), "not an idiv opcode");
+  //assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
+  //assert((long)ctx->Rax == (long)min_jint || pc[0] == 0x49, "unexpected idiv exception");
   // set correct result values and continue after idiv instruction
   ctx->Rip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
   ctx->Rax = (DWORD)min_jint;      // result
--- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -289,6 +289,17 @@
     }
 #endif // AMD64
 
+    if (TraceSignals) {
+    CodeBlob* cb = CodeCache::find_blob(pc);
+      if (cb != NULL && cb->is_nmethod()) {
+        nmethod* nm = (nmethod*)cb;
+        int rel = pc - nm->code_begin();
+        tty->print_cr(err_msg("Implicit exception at %d of method %s", rel, nm->method()->name()->as_C_string()));
+      } else {
+        tty->print_cr("No code blob found for %x", pc);
+      }
+    }
+
     // Handle ALL stack overflow variations here
     if (sig == SIGSEGV) {
       address addr = (address) info->si_addr;
@@ -302,6 +313,7 @@
           if (thread->thread_state() == _thread_in_Java) {
             // Throw a stack overflow exception.  Guard pages will be reenabled
             // while unwinding the stack.
+            if (WizardMode) tty->print("implicit: %08x%08x\n", ((long)pc) >> 32, pc);
             stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
           } else {
             // Thread was in the vm or native code.  Return and try to finish.
@@ -387,8 +399,15 @@
 #endif // AMD64
       } else if (sig == SIGSEGV &&
                !MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) {
+          if (TraceSignals) {
+            tty->print_cr("Implicit exception continuation");
+          }
           // Determination of interpreter/vtable stub/compiled code null exception
           stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
+      } else if (sig == SIGSEGV) {
+        if (TraceSignals) {
+          tty->print_cr("would have needed explicit null check %d", (intptr_t)info->si_addr);
+        }
       }
     } else if (thread->thread_state() == _thread_in_vm &&
                sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
--- a/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/build-impl.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -4,6 +4,13 @@
 ***         EDIT ../build.xml INSTEAD         ***
 -->
 <project name="com.sun.hotspot.igv.svg-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
     <property file="nbproject/private/suite-private.properties"/>
     <property file="nbproject/suite.properties"/>
     <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
@@ -16,13 +23,21 @@
             <property name="@{name}" value="${@{value}}"/>
         </sequential>
     </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
     <property file="${user.properties.file}"/>
     <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
-    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
-    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
         <condition>
             <not>
-                <available file="${harness.dir}" type="dir"/>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
             </not>
         </condition>
     </fail>
--- a/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/genfiles.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,8 +1,5 @@
-build.xml.data.CRC32=ebcf0422
-build.xml.script.CRC32=d7a2678d
-build.xml.stylesheet.CRC32=79c3b980
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
 nbproject/build-impl.xml.data.CRC32=ebcf0422
-nbproject/build-impl.xml.script.CRC32=57997f94
-nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
+nbproject/build-impl.xml.script.CRC32=42ef3ff6
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.47.1
--- a/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/project.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/BatikSVG.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/BatikSVG.java	Mon Feb 27 13:10:13 2012 +0100
@@ -31,34 +31,42 @@
 import org.w3c.dom.DOMImplementation;
 
 /**
- *
+ * Utility class
  * @author Thomas Wuerthinger
  */
 public class BatikSVG {
 
+    private BatikSVG() {
+    }
+
     private static Constructor SVGGraphics2DConstructor;
-    private static Method Method_stream;
-    private static Method Method_createDefault;
-    private static Method Method_getDOMImplementation;
-    private static Method Method_setEmbeddedFontsOn;
+    private static Method streamMethod;
+    private static Method createDefaultMethod;
+    private static Method getDOMImplementationMethod;
+    private static Method setEmbeddedFontsOnMethod;
+    private static Class<?> classSVGGraphics2D;
 
+    /**
+     * Creates a graphics object that allows to be exported to SVG data using the {@link #printToStream(Graphics2D, Writer, boolean) printToStream} method.
+     * @return the newly created Graphics2D object or null if the library does not exist
+     */
     public static Graphics2D createGraphicsObject() {
         try {
             if (SVGGraphics2DConstructor == null) {
                 ClassLoader cl = BatikSVG.class.getClassLoader();
-                Class Class_GenericDOMImplementation = cl.loadClass("org.apache.batik.dom.GenericDOMImplementation");
-                Class Class_SVGGeneratorContext = cl.loadClass("org.apache.batik.svggen.SVGGeneratorContext");
-                Class Class_SVGGraphics2D = cl.loadClass("org.apache.batik.svggen.SVGGraphics2D");
-                Method_getDOMImplementation = Class_GenericDOMImplementation.getDeclaredMethod("getDOMImplementation", new Class[0]);
-                Method_createDefault = Class_SVGGeneratorContext.getDeclaredMethod("createDefault", new Class[]{org.w3c.dom.Document.class});
-                Method_setEmbeddedFontsOn = Class_SVGGeneratorContext.getDeclaredMethod("setEmbeddedFontsOn", new Class[]{boolean.class});
-                Method_stream = Class_SVGGraphics2D.getDeclaredMethod("stream", Writer.class, boolean.class);
-                SVGGraphics2DConstructor = Class_SVGGraphics2D.getConstructor(Class_SVGGeneratorContext, boolean.class);
+                Class<?> classGenericDOMImplementation = cl.loadClass("org.apache.batik.dom.GenericDOMImplementation");
+                Class<?> classSVGGeneratorContext = cl.loadClass("org.apache.batik.svggen.SVGGeneratorContext");
+                classSVGGraphics2D = cl.loadClass("org.apache.batik.svggen.SVGGraphics2D");
+                getDOMImplementationMethod = classGenericDOMImplementation.getDeclaredMethod("getDOMImplementation", new Class[0]);
+                createDefaultMethod = classSVGGeneratorContext.getDeclaredMethod("createDefault", new Class[]{org.w3c.dom.Document.class});
+                setEmbeddedFontsOnMethod = classSVGGeneratorContext.getDeclaredMethod("setEmbeddedFontsOn", new Class[]{boolean.class});
+                streamMethod = classSVGGraphics2D.getDeclaredMethod("stream", Writer.class, boolean.class);
+                SVGGraphics2DConstructor = classSVGGraphics2D.getConstructor(classSVGGeneratorContext, boolean.class);
             }
-            DOMImplementation dom = (DOMImplementation) Method_getDOMImplementation.invoke(null);
+            DOMImplementation dom = (DOMImplementation) getDOMImplementationMethod.invoke(null);
             org.w3c.dom.Document document = dom.createDocument("http://www.w3.org/2000/svg", "svg", null);
-            Object ctx = Method_createDefault.invoke(null, document);
-            Method_setEmbeddedFontsOn.invoke(ctx, true);
+            Object ctx = createDefaultMethod.invoke(null, document);
+            setEmbeddedFontsOnMethod.invoke(ctx, true);
             Graphics2D svgGenerator = (Graphics2D) SVGGraphics2DConstructor.newInstance(ctx, true);
             return svgGenerator;
         } catch (ClassNotFoundException e) {
@@ -74,9 +82,17 @@
         }
     }
 
+    /**
+     * Serializes a graphics object to a stream in SVG format.
+     * @param svgGenerator the graphics object. Only graphics objects created by the {@link #createGraphicsObject() createGraphicsObject} method are valid.
+     * @param stream the stream to which the data is written
+     * @param useCSS whether to use CSS styles in the SVG output
+     */
     public static void printToStream(Graphics2D svgGenerator, Writer stream, boolean useCSS) {
+        assert classSVGGraphics2D != null;
+        assert classSVGGraphics2D.isInstance(svgGenerator);
         try {
-            Method_stream.invoke(svgGenerator, stream, useCSS);
+            streamMethod.invoke(svgGenerator, stream, useCSS);
         } catch (IllegalAccessException e) {
             assert false;
         } catch (InvocationTargetException e) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/package-info.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2008, 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.
+ *
+ */
+/**
+ * This package is used to proxy the SVG export functionality of the BatikSVG library. Reflection is used such that the
+ * library is optional and need not be present at build time.
+ */
+package com.sun.hotspot.igv.svg;
+
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/manifest.mf	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -1,6 +1,6 @@
-Manifest-Version: 1.0
-OpenIDE-Module: com.sun.hotspot.igv.bytecodes
-OpenIDE-Module-Layer: com/sun/hotspot/igv/bytecodes/layer.xml
-OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/bytecodes/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.0
-
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.bytecodes
+OpenIDE-Module-Layer: com/sun/hotspot/igv/bytecodes/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/bytecodes/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/project.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/project.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -15,12 +15,28 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
                     <code-name-base>org.jdesktop.layout</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
                         <release-version>1</release-version>
-                        <specification-version>1.4</specification-version>
+                        <specification-version>1.16.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -28,7 +44,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.11</specification-version>
+                        <specification-version>6.34.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -36,7 +52,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.2.0.1</specification-version>
+                        <specification-version>7.20.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -44,7 +60,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.9.0.1</specification-version>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -52,7 +76,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.16</specification-version>
+                        <specification-version>6.39.1</specification-version>
                     </run-dependency>
                 </dependency>
             </module-dependencies>
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/Bundle.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,5 +1,5 @@
-CTL_BytecodeViewAction=Open BytecodeView Window
-CTL_BytecodeViewTopComponent=BytecodeView Window
+CTL_BytecodeViewAction=Bytecode
+CTL_BytecodeViewTopComponent=Bytecode
 CTL_SelectBytecodesAction=Select nodes
-HINT_BytecodeViewTopComponent=This is a BytecodeView window
+HINT_BytecodeViewTopComponent=Shows the bytecode associated with the displayed graph.
 OpenIDE-Module-Name=Bytecodes
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeNode.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -29,14 +29,14 @@
 import com.sun.hotspot.igv.data.Properties;
 import com.sun.hotspot.igv.data.Properties.StringPropertyMatcher;
 import java.awt.Image;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 import javax.swing.Action;
 import org.openide.nodes.AbstractNode;
 import org.openide.nodes.Children;
 import org.openide.nodes.Node;
-import org.openide.util.Utilities;
+import org.openide.util.ImageUtilities;
 
 /**
  *
@@ -54,11 +54,11 @@
         bciValue = bytecode.getBci() + " " + bciValue;
         bciValue = bciValue.trim();
 
-        Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<InputNode>(graph.getNodes());
+        Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<>(graph.getNodes());
         StringPropertyMatcher matcher = new StringPropertyMatcher("bci", bciValue);
         List<InputNode> nodeList = selector.selectMultiple(matcher);
         if (nodeList.size() > 0) {
-            nodes = new HashSet<InputNode>();
+            nodes = new LinkedHashSet<>();
             for (InputNode n : nodeList) {
                 nodes.add(n);
             }
@@ -69,9 +69,9 @@
     @Override
     public Image getIcon(int i) {
         if (nodes != null) {
-            return Utilities.loadImage("com/sun/hotspot/igv/bytecodes/images/link.gif");
+            return ImageUtilities.loadImage("com/sun/hotspot/igv/bytecodes/images/link.png");
         } else {
-            return Utilities.loadImage("com/sun/hotspot/igv/bytecodes/images/bytecode.gif");
+            return ImageUtilities.loadImage("com/sun/hotspot/igv/bytecodes/images/bytecode.png");
         }
     }
 
@@ -91,6 +91,7 @@
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public <T extends Node.Cookie> T getCookie(Class<T> aClass) {
         if (aClass == SelectBytecodesCookie.class && nodes != null) {
             return (T) (new SelectBytecodesCookie(nodes));
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -37,6 +37,7 @@
         super(NbBundle.getMessage(BytecodeViewAction.class, "CTL_BytecodeViewAction"));
     }
 
+    @Override
     public void actionPerformed(ActionEvent evt) {
         TopComponent win = BytecodeViewTopComponent.findInstance();
         win.open();
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.form	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.form	Mon Feb 27 13:10:13 2012 +0100
@@ -3,6 +3,8 @@
 <Form version="1.3" maxVersion="1.3" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
   <AuxValues>
     <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
     <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java	Mon Feb 27 13:10:13 2012 +0100
@@ -26,6 +26,7 @@
 import com.sun.hotspot.igv.data.Group;
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import com.sun.hotspot.igv.util.LookupHistory;
 import java.awt.BorderLayout;
 import java.io.Serializable;
 import javax.swing.SwingUtilities;
@@ -33,11 +34,7 @@
 import org.openide.explorer.ExplorerManager;
 import org.openide.explorer.ExplorerUtils;
 import org.openide.explorer.view.BeanTreeView;
-import org.openide.util.Lookup;
-import org.openide.util.LookupEvent;
-import org.openide.util.LookupListener;
-import org.openide.util.NbBundle;
-import org.openide.util.Utilities;
+import org.openide.util.*;
 import org.openide.windows.TopComponent;
 import org.openide.windows.WindowManager;
 
@@ -91,6 +88,7 @@
     }// </editor-fold>//GEN-END:initComponents
     // Variables declaration - do not modify//GEN-BEGIN:variables
     // End of variables declaration//GEN-END:variables
+
     /**
      * Gets default instance. Do not use directly: reserved for *.settings files only,
      * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
@@ -126,7 +124,7 @@
 
     @Override
     public void componentOpened() {
-        Lookup.Template tpl = new Lookup.Template(Object.class);
+        Lookup.Template<InputGraphProvider> tpl = new Lookup.Template<>(InputGraphProvider.class);
         result = Utilities.actionsGlobalContext().lookup(tpl);
         result.addLookupListener(this);
     }
@@ -147,21 +145,42 @@
         return PREFERRED_ID;
     }
 
+    @Override
     public ExplorerManager getExplorerManager() {
         return manager;
     }
 
+    @Override
+    public void requestActive() {
+        super.requestActive();
+        this.treeView.requestFocus();
+    }
+
+    @Override
+    public boolean requestFocus(boolean temporary) {
+        this.treeView.requestFocus();
+        return super.requestFocus(temporary);
+    }
+
+    @Override
+    protected boolean requestFocusInWindow(boolean temporary) {
+        this.treeView.requestFocus();
+        return super.requestFocusInWindow(temporary);
+    }
+
+    @Override
     public void resultChanged(LookupEvent lookupEvent) {
-        final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+        final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//)Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
         if (p != null) {
             SwingUtilities.invokeLater(new Runnable() {
+                @Override
                 public void run() {
-            InputGraph graph = p.getGraph();
-            if (graph != null) {
-                Group g = graph.getGroup();
-                rootNode.update(graph, g.getMethod());
-            }
-        }
+                    InputGraph graph = p.getGraph();
+                    if (graph != null) {
+                        Group g = graph.getGroup();
+                        rootNode.update(graph, g.getMethod());
+                    }
+                }
             });
         }
     }
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/MethodNode.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/MethodNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -30,7 +30,7 @@
 import org.openide.nodes.AbstractNode;
 import org.openide.nodes.Children;
 import org.openide.nodes.Node;
-import org.openide.util.Utilities;
+import org.openide.util.ImageUtilities;
 
 /**
  *
@@ -38,7 +38,7 @@
  */
 public class MethodNode extends AbstractNode {
 
-    private static class MethodNodeChildren extends Children.Keys {
+    private static class MethodNodeChildren extends Children.Keys<InputBytecode> {
 
         private InputMethod method;
         private InputGraph graph;
@@ -50,9 +50,8 @@
             this.graph = graph;
         }
 
-        protected Node[] createNodes(Object object) {
-            assert object instanceof InputBytecode;
-            InputBytecode bc = (InputBytecode) object;
+        @Override
+        protected Node[] createNodes(InputBytecode bc) {
             if (bc.getInlined() == null) {
                 return new Node[]{new BytecodeNode(bc, graph, bciString)};
             } else {
@@ -84,7 +83,7 @@
 
     @Override
     public Image getIcon(int i) {
-        return Utilities.loadImage("com/sun/hotspot/igv/bytecodes/images/method.gif");
+        return ImageUtilities.loadImage("com/sun/hotspot/igv/bytecodes/images/method.png");
     }
 
     @Override
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -24,9 +24,9 @@
 package com.sun.hotspot.igv.bytecodes;
 
 import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import com.sun.hotspot.igv.util.LookupHistory;
 import org.openide.nodes.Node;
 import org.openide.util.HelpCtx;
-import org.openide.util.Lookup;
 import org.openide.util.NbBundle;
 import org.openide.util.actions.CookieAction;
 
@@ -36,22 +36,26 @@
  */
 public final class SelectBytecodesAction extends CookieAction {
 
+    @Override
     protected void performAction(Node[] activatedNodes) {
         SelectBytecodesCookie c = activatedNodes[0].getCookie(SelectBytecodesCookie.class);
-        InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+        InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
         if (p != null) {
             p.setSelectedNodes(c.getNodes());
         }
     }
 
+    @Override
     protected int mode() {
         return CookieAction.MODE_EXACTLY_ONE;
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(SelectBytecodesAction.class, "CTL_SelectBytecodesAction");
     }
 
+    @Override
     protected Class[] cookieClasses() {
         return new Class[]{
             SelectBytecodesCookie.class
@@ -64,6 +68,7 @@
         putValue("noIconInMenu", Boolean.TRUE);
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -73,3 +78,4 @@
         return false;
     }
 }
+
Binary file src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/bytecode.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/bytecode.png has changed
Binary file src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/link.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/link.png has changed
Binary file src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/method.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/method.png has changed
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/build.xml	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
-<!-- for some information on what you could do (e.g. targets to override). -->
-<!-- If you delete this file and reopen the project it will be recreated. -->
-<project name="com.sun.hotspot.igv.controlflow" default="netbeans" basedir=".">
-    <description>Builds, tests, and runs the project com.sun.hotspot.igv.controlflow.</description>
-    <import file="nbproject/build-impl.xml"/>
-</project>
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/manifest.mf	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-Manifest-Version: 1.0
-OpenIDE-Module: com.sun.hotspot.igv.controlflow
-OpenIDE-Module-Layer: com/sun/hotspot/igv/controlflow/layer.xml
-OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/controlflow/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.0
-
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/build-impl.xml	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-*** GENERATED FROM project.xml - DO NOT EDIT  ***
-***         EDIT ../build.xml INSTEAD         ***
--->
-<project name="com.sun.hotspot.igv.controlflow-impl" basedir="..">
-    <property file="nbproject/private/suite-private.properties"/>
-    <property file="nbproject/suite.properties"/>
-    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
-    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
-    <property file="${suite.dir}/nbproject/platform.properties"/>
-    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
-        <attribute name="name"/>
-        <attribute name="value"/>
-        <sequential>
-            <property name="@{name}" value="${@{value}}"/>
-        </sequential>
-    </macrodef>
-    <property file="${user.properties.file}"/>
-    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
-    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
-    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
-        <condition>
-            <not>
-                <available file="${harness.dir}" type="dir"/>
-            </not>
-        </condition>
-    </fail>
-    <import file="${harness.dir}/build.xml"/>
-</project>
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/genfiles.properties	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-build.xml.data.CRC32=b524efb3
-build.xml.script.CRC32=79a27be9
-build.xml.stylesheet.CRC32=79c3b980
-# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
-# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=b524efb3
-nbproject/build-impl.xml.script.CRC32=582bdab7
-nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/platform.properties	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-# Deprecated since 5.0u1; for compatibility with 5.0:
-disabled.clusters=\
-    apisupport1,\
-    harness,\
-    ide8,\
-    java1,\
-    nb6.0,\
-    profiler2
-disabled.modules=\
-    org.netbeans.core.execution,\
-    org.netbeans.core.multiview,\
-    org.netbeans.core.output2,\
-    org.netbeans.modules.applemenu,\
-    org.netbeans.modules.autoupdate.services,\
-    org.netbeans.modules.autoupdate.ui,\
-    org.netbeans.modules.core.kit,\
-    org.netbeans.modules.favorites,\
-    org.netbeans.modules.javahelp,\
-    org.netbeans.modules.masterfs,\
-    org.netbeans.modules.options.keymap,\
-    org.netbeans.modules.sendopts,\
-    org.netbeans.modules.templates,\
-    org.openide.compat,\
-    org.openide.execution,\
-    org.openide.util.enumerations
-enabled.clusters=\
-    platform7
-nbjdk.active=JDK_1.6
-nbplatform.active=default
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/project.properties	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/project.xml	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://www.netbeans.org/ns/project/1">
-    <type>org.netbeans.modules.apisupport.project</type>
-    <configuration>
-        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
-            <code-name-base>com.sun.hotspot.igv.controlflow</code-name-base>
-            <suite-component/>
-            <module-dependencies>
-                <dependency>
-                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.0</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>com.sun.hotspot.igv.hierarchicallayout</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.0</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>com.sun.hotspot.igv.layout</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.0</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.jdesktop.layout</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <release-version>1</release-version>
-                        <specification-version>1.4</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.netbeans.api.visual</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>2.9</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.util</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>7.9.0.1</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.windows</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>6.16</specification-version>
-                    </run-dependency>
-                </dependency>
-            </module-dependencies>
-            <public-packages/>
-        </data>
-    </configuration>
-</project>
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/suite.properties	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-suite.dir=${basedir}/..
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/BlockConnectionWidget.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.controlflow;
-
-import com.sun.hotspot.igv.data.InputBlockEdge;
-import com.sun.hotspot.igv.layout.Link;
-import com.sun.hotspot.igv.layout.Port;
-import java.awt.Point;
-import java.util.ArrayList;
-import java.util.List;
-import org.netbeans.api.visual.widget.ConnectionWidget;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class BlockConnectionWidget extends ConnectionWidget implements Link {
-
-    private BlockWidget from;
-    private BlockWidget to;
-    private Port inputSlot;
-    private Port outputSlot;
-    private List<Point> points;
-    private InputBlockEdge edge;
-
-    public BlockConnectionWidget(ControlFlowScene scene, InputBlockEdge edge) {
-        super(scene);
-
-        this.edge = edge;
-        this.from = (BlockWidget) scene.findWidget(edge.getFrom());
-        this.to = (BlockWidget) scene.findWidget(edge.getTo());
-        inputSlot = to.getInputSlot();
-        outputSlot = from.getOutputSlot();
-        points = new ArrayList<Point>();
-    }
-
-    public InputBlockEdge getEdge() {
-        return edge;
-    }
-
-    public Port getTo() {
-        return inputSlot;
-    }
-
-    public Port getFrom() {
-        return outputSlot;
-    }
-
-    public void setControlPoints(List<Point> p) {
-        this.points = p;
-    }
-
-    @Override
-    public List<Point> getControlPoints() {
-        return points;
-    }
-
-    @Override
-    public String toString() {
-        return "Connection[ " + from.toString() + " - " + to.toString() + "]";
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/BlockWidget.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.controlflow;
-
-import com.sun.hotspot.igv.data.InputBlock;
-import com.sun.hotspot.igv.layout.Cluster;
-import com.sun.hotspot.igv.layout.Port;
-import com.sun.hotspot.igv.layout.Vertex;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.Point;
-import org.netbeans.api.visual.border.BorderFactory;
-import org.netbeans.api.visual.model.ObjectState;
-import org.netbeans.api.visual.widget.LabelWidget;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class BlockWidget extends LabelWidget implements Vertex {
-
-    public static final Dimension SIZE = new Dimension(20, 20);
-    private InputBlock block;
-    private Port inputSlot;
-    private Port outputSlot;
-    private Cluster cluster;
-    private boolean root;
-    private static final Font font = new Font(Font.SERIF, Font.PLAIN, 12);
-    private static final Font boldFont = font.deriveFont(Font.BOLD);
-    public static final Color NORMAL_FOREGROUND_COLOR = Color.BLACK;
-    public static final Color HOVER_FOREGROUND_COLOR = Color.BLUE;
-
-    /** Creates a new instance of BlockWidget */
-    public BlockWidget(ControlFlowScene scene, InputBlock block) {
-        super(scene);
-        this.block = block;
-        this.setLabel(block.getName());
-        this.setForeground(NORMAL_FOREGROUND_COLOR);
-        this.setBorder(BorderFactory.createLineBorder(1, NORMAL_FOREGROUND_COLOR));
-        this.setMinimumSize(SIZE);
-        this.setMaximumSize(SIZE);
-
-        this.setFont(font);
-
-        final BlockWidget widget = this;
-        inputSlot = new Port() {
-
-            public Point getRelativePosition() {
-                return new Point((int) (SIZE.getWidth() / 2), (int) (SIZE.getHeight() / 2));
-            }
-
-            public Vertex getVertex() {
-                return widget;
-            }
-        };
-
-        outputSlot = new Port() {
-
-            public Point getRelativePosition() {
-                return new Point((int) (SIZE.getWidth() / 2), (int) (SIZE.getHeight() / 2));
-            }
-
-            public Vertex getVertex() {
-                return widget;
-            }
-        };
-    }
-
-    public Port getInputSlot() {
-        return inputSlot;
-    }
-
-    public Port getOutputSlot() {
-        return outputSlot;
-    }
-
-    public InputBlock getBlock() {
-        return block;
-    }
-
-    public Dimension getSize() {
-        return SIZE;
-    }
-
-    public void setPosition(Point p) {
-        this.setPreferredLocation(p);
-    }
-
-    @Override
-    public String toString() {
-        return block.getName();
-    }
-
-    public Point getPosition() {
-        return this.getPreferredLocation();
-    }
-
-    public Cluster getCluster() {
-        return cluster;
-    }
-
-    public boolean isRoot() {
-        return root;
-    }
-
-    public void setCluster(Cluster c) {
-        cluster = c;
-    }
-
-    public void setRoot(boolean b) {
-        root = b;
-    }
-
-    public int compareTo(Vertex o) {
-        return toString().compareTo(o.toString());
-    }
-
-    @Override
-    protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
-        super.notifyStateChanged(previousState, state);
-
-        if (previousState.isHovered() != state.isHovered()) {
-            if (state.isHovered()) {
-                this.setBorder(BorderFactory.createLineBorder(1, HOVER_FOREGROUND_COLOR));
-            } else {
-                this.setBorder(BorderFactory.createLineBorder(1, NORMAL_FOREGROUND_COLOR));
-            }
-        }
-
-        if (previousState.isSelected() != state.isSelected()) {
-            if (state.isSelected()) {
-                this.setFont(boldFont);
-            } else {
-                this.setFont(font);
-            }
-        }
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/Bundle.properties	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-CTL_ControlFlowAction=Open ControlFlow Window
-CTL_ControlFlowTopComponent=ControlFlow Window
-HINT_ControlFlowTopComponent=This is a ControlFlow window
-OpenIDE-Module-Name=ControlFlow
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.controlflow;
-
-import java.awt.event.ActionEvent;
-import javax.swing.AbstractAction;
-import org.openide.util.NbBundle;
-import org.openide.windows.TopComponent;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class ControlFlowAction extends AbstractAction {
-
-    public ControlFlowAction() {
-        super(NbBundle.getMessage(ControlFlowAction.class, "CTL_ControlFlowAction"));
-    }
-
-    public void actionPerformed(ActionEvent evt) {
-        TopComponent win = ControlFlowTopComponent.findInstance();
-        win.open();
-        win.requestActive();
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowScene.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,295 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.controlflow;
-
-import com.sun.hotspot.igv.data.InputBlock;
-import com.sun.hotspot.igv.data.InputBlockEdge;
-import com.sun.hotspot.igv.data.InputGraph;
-import com.sun.hotspot.igv.data.services.InputGraphProvider;
-import com.sun.hotspot.igv.data.InputNode;
-import java.awt.Color;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Set;
-import javax.swing.BorderFactory;
-import org.netbeans.api.visual.action.ActionFactory;
-import org.netbeans.api.visual.action.MoveProvider;
-import org.netbeans.api.visual.action.RectangularSelectDecorator;
-import org.netbeans.api.visual.action.RectangularSelectProvider;
-import org.netbeans.api.visual.action.SelectProvider;
-import org.netbeans.api.visual.action.WidgetAction;
-import org.netbeans.api.visual.anchor.AnchorFactory;
-import org.netbeans.api.visual.anchor.AnchorShape;
-import org.netbeans.api.visual.layout.LayoutFactory;
-import org.netbeans.api.visual.router.RouterFactory;
-import org.netbeans.api.visual.widget.LayerWidget;
-import org.netbeans.api.visual.widget.Widget;
-import org.netbeans.api.visual.graph.GraphScene;
-import org.netbeans.api.visual.graph.layout.GraphLayout;
-import org.netbeans.api.visual.layout.SceneLayout;
-import org.netbeans.api.visual.widget.ConnectionWidget;
-import org.openide.util.Lookup;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class ControlFlowScene extends GraphScene<InputBlock, InputBlockEdge> implements SelectProvider, MoveProvider, RectangularSelectDecorator, RectangularSelectProvider {
-
-    private HashSet<BlockWidget> selection;
-    private HashMap<InputBlock, BlockWidget> blockMap;
-    private InputGraph oldGraph;
-    private LayerWidget edgeLayer;
-    private LayerWidget mainLayer;
-    private LayerWidget selectLayer;
-    private WidgetAction hoverAction = this.createWidgetHoverAction();
-    private WidgetAction selectAction = ActionFactory.createSelectAction(this);
-    private WidgetAction moveAction = ActionFactory.createMoveAction(null, this);
-
-    public ControlFlowScene() {
-        selection = new HashSet<BlockWidget>();
-
-        this.getInputBindings().setZoomActionModifiers(0);
-        this.setLayout(LayoutFactory.createAbsoluteLayout());
-
-        mainLayer = new LayerWidget(this);
-        this.addChild(mainLayer);
-
-        edgeLayer = new LayerWidget(this);
-        this.addChild(edgeLayer);
-
-        selectLayer = new LayerWidget(this);
-        this.addChild(selectLayer);
-
-        this.getActions().addAction(hoverAction);
-        this.getActions().addAction(selectAction);
-        this.getActions().addAction(ActionFactory.createRectangularSelectAction(this, selectLayer, this));
-        this.getActions().addAction(ActionFactory.createMouseCenteredZoomAction(1.1));
-    }
-
-    public void setGraph(InputGraph g) {
-        if (g == oldGraph) {
-            return;
-        }
-        oldGraph = g;
-
-        ArrayList<InputBlock> blocks = new ArrayList<InputBlock>(this.getNodes());
-        for (InputBlock b : blocks) {
-            removeNode(b);
-        }
-
-        ArrayList<InputBlockEdge> edges = new ArrayList<InputBlockEdge>(this.getEdges());
-        for (InputBlockEdge e : edges) {
-            removeEdge(e);
-        }
-
-        for (InputBlock b : g.getBlocks()) {
-            addNode(b);
-        }
-
-        for (InputBlock b : g.getBlocks()) {
-            for (InputBlockEdge e : b.getOutputs()) {
-                addEdge(e);
-                assert g.getBlocks().contains(e.getFrom());
-                assert g.getBlocks().contains(e.getTo());
-                this.setEdgeSource(e, e.getFrom());
-                this.setEdgeTarget(e, e.getTo());
-            }
-        }
-
-        GraphLayout layout = new HierarchicalGraphLayout();//GridGraphLayout();
-        SceneLayout sceneLayout = LayoutFactory.createSceneGraphLayout(this, layout);
-        sceneLayout.invokeLayout();
-
-        this.validate();
-    }
-
-    public BlockWidget getBlockWidget(InputBlock b) {
-        return blockMap.get(b);
-    }
-
-    public void clearSelection() {
-        for (BlockWidget w : selection) {
-            w.setState(w.getState().deriveSelected(false));
-        }
-        selection.clear();
-        selectionChanged();
-    }
-
-    public void selectionChanged() {
-        InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
-        if (p != null) {
-            Set<InputNode> inputNodes = new HashSet<InputNode>();
-            for (BlockWidget w : selection) {
-                inputNodes.addAll(w.getBlock().getNodes());
-            }
-            p.setSelectedNodes(inputNodes);
-        }
-    }
-
-    public void addToSelection(BlockWidget widget) {
-        widget.setState(widget.getState().deriveSelected(true));
-        selection.add(widget);
-        selectionChanged();
-    }
-
-    public void removeFromSelection(BlockWidget widget) {
-        widget.setState(widget.getState().deriveSelected(false));
-        selection.remove(widget);
-        selectionChanged();
-    }
-
-    public boolean isAimingAllowed(Widget widget, Point point, boolean b) {
-        return false;
-    }
-
-    public boolean isSelectionAllowed(Widget widget, Point point, boolean b) {
-        return true;
-    }
-
-    public void select(Widget widget, Point point, boolean change) {
-        if (widget == this) {
-            clearSelection();
-        } else {
-
-            assert widget instanceof BlockWidget;
-            BlockWidget bw = (BlockWidget) widget;
-            if (change) {
-                if (selection.contains(bw)) {
-                    removeFromSelection(bw);
-                } else {
-                    addToSelection(bw);
-                }
-            } else {
-                if (!selection.contains(bw)) {
-                    clearSelection();
-                    addToSelection(bw);
-                }
-            }
-        }
-    }
-
-    public void movementStarted(Widget widget) {
-    }
-
-    public void movementFinished(Widget widget) {
-    }
-
-    public Point getOriginalLocation(Widget widget) {
-        return widget.getPreferredLocation();
-    }
-
-    public void setNewLocation(Widget widget, Point location) {
-        Point originalLocation = getOriginalLocation(widget);
-        int xOffset = location.x - originalLocation.x;
-        int yOffset = location.y - originalLocation.y;
-        for (Widget w : this.selection) {
-            Point p = new Point(w.getPreferredLocation());
-            p.translate(xOffset, yOffset);
-            w.setPreferredLocation(p);
-        }
-
-    }
-
-    public Widget createSelectionWidget() {
-        Widget widget = new Widget(this);
-        widget.setOpaque(false);
-        widget.setBorder(BorderFactory.createLineBorder(Color.black, 2));
-        widget.setForeground(Color.red);
-        return widget;
-    }
-
-    public void performSelection(Rectangle rectangle) {
-
-        if (rectangle.width < 0) {
-            rectangle.x += rectangle.width;
-            rectangle.width *= -1;
-        }
-
-        if (rectangle.height < 0) {
-            rectangle.y += rectangle.height;
-            rectangle.height *= -1;
-        }
-
-        boolean changed = false;
-        for (InputBlock b : this.getNodes()) {
-            BlockWidget w = (BlockWidget) findWidget(b);
-            Rectangle r = new Rectangle(w.getBounds());
-            r.setLocation(w.getLocation());
-            if (r.intersects(rectangle)) {
-                if (!selection.contains(w)) {
-                    changed = true;
-                    selection.add(w);
-                    w.setState(w.getState().deriveSelected(true));
-                }
-            } else {
-                if (selection.contains(w)) {
-                    changed = true;
-                    selection.remove(w);
-                    w.setState(w.getState().deriveSelected(false));
-                }
-            }
-        }
-
-        if (changed) {
-            selectionChanged();
-        }
-
-    }
-
-    protected Widget attachNodeWidget(InputBlock node) {
-        BlockWidget w = new BlockWidget(this, node);
-        mainLayer.addChild(w);
-        w.getActions().addAction(hoverAction);
-        w.getActions().addAction(selectAction);
-        w.getActions().addAction(moveAction);
-        return w;
-    }
-
-    protected Widget attachEdgeWidget(InputBlockEdge edge) {
-        ConnectionWidget w = new BlockConnectionWidget(this, edge);
-        w.setRouter(RouterFactory.createDirectRouter());
-        w.setTargetAnchorShape(AnchorShape.TRIANGLE_FILLED);
-        edgeLayer.addChild(w);
-        return w;
-    }
-
-    protected void attachEdgeSourceAnchor(InputBlockEdge edge, InputBlock oldSourceNode, InputBlock sourceNode) {
-        Widget w = this.findWidget(edge);
-        assert w instanceof ConnectionWidget;
-        ConnectionWidget cw = (ConnectionWidget) w;
-        cw.setSourceAnchor(AnchorFactory.createRectangularAnchor(findWidget(sourceNode)));
-
-    }
-
-    protected void attachEdgeTargetAnchor(InputBlockEdge edge, InputBlock oldTargetNode, InputBlock targetNode) {
-        Widget w = this.findWidget(edge);
-        assert w instanceof ConnectionWidget;
-        ConnectionWidget cw = (ConnectionWidget) w;
-        cw.setTargetAnchor(AnchorFactory.createRectangularAnchor(findWidget(targetNode)));
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.form	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-
-<Form version="1.3" maxVersion="1.3" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
-  <AuxValues>
-    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
-    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
-    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
-    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
-    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
-    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
-    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
-  </AuxValues>
-
-  <Layout>
-    <DimensionLayout dim="0">
-      <Group type="103" groupAlignment="0" attributes="0">
-          <EmptySpace min="0" pref="400" max="32767" attributes="0"/>
-      </Group>
-    </DimensionLayout>
-    <DimensionLayout dim="1">
-      <Group type="103" groupAlignment="0" attributes="0">
-          <EmptySpace min="0" pref="300" max="32767" attributes="0"/>
-      </Group>
-    </DimensionLayout>
-  </Layout>
-</Form>
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,184 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.controlflow;
-
-import com.sun.hotspot.igv.data.InputGraph;
-import com.sun.hotspot.igv.data.services.InputGraphProvider;
-import java.awt.BorderLayout;
-import java.io.Serializable;
-import javax.swing.JScrollPane;
-import javax.swing.SwingUtilities;
-import org.openide.ErrorManager;
-import org.openide.util.Lookup;
-import org.openide.util.LookupEvent;
-import org.openide.util.LookupListener;
-import org.openide.util.NbBundle;
-import org.openide.util.Utilities;
-import org.openide.windows.TopComponent;
-import org.openide.windows.WindowManager;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-final class ControlFlowTopComponent extends TopComponent implements LookupListener {
-
-    private static ControlFlowTopComponent instance;
-    private Lookup.Result result = null;
-    private static final String PREFERRED_ID = "ControlFlowTopComponent";
-    private ControlFlowScene scene;
-
-    private ControlFlowTopComponent() {
-        initComponents();
-        setName(NbBundle.getMessage(ControlFlowTopComponent.class, "CTL_ControlFlowTopComponent"));
-        setToolTipText(NbBundle.getMessage(ControlFlowTopComponent.class, "HINT_ControlFlowTopComponent"));
-
-        scene = new ControlFlowScene();
-        this.setLayout(new BorderLayout());
-        this.associateLookup(scene.getLookup());
-
-
-        JScrollPane panel = new JScrollPane(scene.createView());
-        this.add(panel, BorderLayout.CENTER);
-    }
-
-    @Override
-    public void requestFocus() {
-        super.requestFocus();
-        scene.getView().requestFocus();
-    }
-
-    @Override
-    public boolean requestFocusInWindow() {
-        super.requestFocusInWindow();
-        return scene.getView().requestFocusInWindow();
-    }
-
-    /** This method is called from within the constructor to
-     * initialize the form.
-     * WARNING: Do NOT modify this code. The content of this method is
-     * always regenerated by the Form Editor.
-     */
-    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
-    private void initComponents() {
-
-        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
-        this.setLayout(layout);
-        layout.setHorizontalGroup(
-            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
-            .add(0, 400, Short.MAX_VALUE)
-        );
-        layout.setVerticalGroup(
-            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
-            .add(0, 300, Short.MAX_VALUE)
-        );
-    }// </editor-fold>//GEN-END:initComponents
-    // Variables declaration - do not modify//GEN-BEGIN:variables
-    // End of variables declaration//GEN-END:variables
-    /**
-     * Gets default instance. Do not use directly: reserved for *.settings files only,
-     * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
-     * To obtain the singleton instance, use {@link findInstance}.
-     */
-    public static synchronized ControlFlowTopComponent getDefault() {
-        if (instance == null) {
-            instance = new ControlFlowTopComponent();
-        }
-        return instance;
-    }
-
-    /**
-     * Obtain the ControlFlowTopComponent instance. Never call {@link #getDefault} directly!
-     */
-    public static synchronized ControlFlowTopComponent findInstance() {
-        TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
-        if (win == null) {
-            ErrorManager.getDefault().log(ErrorManager.WARNING, "Cannot find ControlFlow component. It will not be located properly in the window system.");
-            return getDefault();
-        }
-        if (win instanceof ControlFlowTopComponent) {
-            return (ControlFlowTopComponent) win;
-        }
-        ErrorManager.getDefault().log(ErrorManager.WARNING, "There seem to be multiple components with the '" + PREFERRED_ID + "' ID. That is a potential source of errors and unexpected behavior.");
-        return getDefault();
-    }
-
-    @Override
-    public int getPersistenceType() {
-        return TopComponent.PERSISTENCE_ALWAYS;
-    }
-
-    @Override
-    public void componentOpened() {
-        Lookup.Template tpl = new Lookup.Template(Object.class);
-        result = Utilities.actionsGlobalContext().lookup(tpl);
-        result.addLookupListener(this);
-    }
-
-    @Override
-    public void componentClosed() {
-        result.removeLookupListener(this);
-        result = null;
-    }
-
-    public void resultChanged(LookupEvent lookupEvent) {
-
-        final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
-        if (p != null) {
-            SwingUtilities.invokeLater(new Runnable() {
-                public void run() {
-            InputGraph g = p.getGraph();
-            if (g != null) {
-                scene.setGraph(g);
-            }
-        }
-            });
-        }
-    }
-
-    @Override
-    public Object writeReplace() {
-        return new ResolvableHelper();
-    }
-
-    @Override
-    protected String preferredID() {
-        return PREFERRED_ID;
-    }
-
-    @Override
-    public void requestActive() {
-        scene.getView().requestFocusInWindow();
-        super.requestActive();
-    }
-
-    final static class ResolvableHelper implements Serializable {
-
-        private static final long serialVersionUID = 1L;
-
-        public Object readResolve() {
-            return ControlFlowTopComponent.getDefault();
-        }
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponentSettings.xml	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd">
-<settings version="1.0">
-    <module name="com.sun.hotspot.igv.controlflow" spec="1.0"/>
-    <instanceof class="org.openide.windows.TopComponent"/>
-    <instanceof class="com.sun.hotspot.igv.controlflow.ControlFlowTopComponent"/>
-    <instance class="com.sun.hotspot.igv.controlflow.ControlFlowTopComponent" method="getDefault"/>
-</settings>
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponentWstcref.xml	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE tc-ref PUBLIC "-//NetBeans//DTD Top Component in Mode Properties 2.0//EN" "http://www.netbeans.org/dtds/tc-ref2_0.dtd">
-<tc-ref version="2.0" >
-    <module name="com.sun.hotspot.igv.controlflow" spec="1.0"/>
-    <tc-id id="ControlFlowTopComponent"/>
-    <state opened="true"/>
-</tc-ref>
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/HierarchicalGraphLayout.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.controlflow;
-
-import com.sun.hotspot.igv.hierarchicallayout.HierarchicalLayoutManager;
-import com.sun.hotspot.igv.layout.Cluster;
-import com.sun.hotspot.igv.layout.LayoutGraph;
-import com.sun.hotspot.igv.layout.Link;
-import com.sun.hotspot.igv.layout.Port;
-import com.sun.hotspot.igv.layout.Vertex;
-import java.awt.Dimension;
-import java.awt.Point;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.netbeans.api.visual.graph.layout.GraphLayout;
-import org.netbeans.api.visual.graph.layout.UniversalGraph;
-import org.netbeans.api.visual.widget.Widget;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class HierarchicalGraphLayout<N, E> extends GraphLayout<N, E> {
-
-    public HierarchicalGraphLayout() {
-    }
-
-    private class LinkWrapper implements Link {
-
-        private VertexWrapper from;
-        private VertexWrapper to;
-
-        public LinkWrapper(VertexWrapper from, VertexWrapper to) {
-            this.from = from;
-            this.to = to;
-        }
-
-        public Port getFrom() {
-            return from.getSlot();
-        }
-
-        public Port getTo() {
-            return to.getSlot();
-        }
-
-        public List<Point> getControlPoints() {
-            return new ArrayList<Point>();
-        }
-
-        public void setControlPoints(List<Point> list) {
-        // Do nothing for now
-        }
-    }
-
-    private class VertexWrapper implements Vertex {
-
-        private N node;
-        private UniversalGraph<N, E> graph;
-        private Port slot;
-        private Point position;
-
-        public VertexWrapper(N node, UniversalGraph<N, E> graph) {
-            this.node = node;
-            this.graph = graph;
-            final VertexWrapper vertex = this;
-            this.slot = new Port() {
-
-                public Vertex getVertex() {
-                    return vertex;
-                }
-
-                public Point getRelativePosition() {
-                    return new Point((int) (vertex.getSize().getWidth() / 2), (int) (vertex.getSize().getHeight() / 2));
-                }
-            };
-
-            Widget w = graph.getScene().findWidget(node);
-            this.position = w.getPreferredLocation();
-        }
-
-        public Cluster getCluster() {
-            return null;
-        }
-
-        public Dimension getSize() {
-            Widget w = graph.getScene().findWidget(node);
-            return w.getBounds().getSize();
-        }
-
-        public Point getPosition() {
-            return position;
-        }
-
-        public void setPosition(Point p) {
-            HierarchicalGraphLayout.this.setResolvedNodeLocation(graph, node, p);
-            position = p;
-        }
-
-        public boolean isRoot() {
-            return false;
-        }
-
-        public int compareTo(Vertex o) {
-            VertexWrapper vw = (VertexWrapper) o;
-            return node.toString().compareTo(vw.node.toString());
-        }
-
-        public Port getSlot() {
-            return slot;
-        }
-    }
-
-    protected void performGraphLayout(UniversalGraph<N, E> graph) {
-
-        Set<LinkWrapper> links = new HashSet<LinkWrapper>();
-        Set<VertexWrapper> vertices = new HashSet<VertexWrapper>();
-        Map<N, VertexWrapper> vertexMap = new HashMap<N, VertexWrapper>();
-
-        for (N node : graph.getNodes()) {
-            VertexWrapper v = new VertexWrapper(node, graph);
-            vertexMap.put(node, v);
-            vertices.add(v);
-        }
-
-        for (E edge : graph.getEdges()) {
-            N source = graph.getEdgeSource(edge);
-            N target = graph.getEdgeTarget(edge);
-            LinkWrapper l = new LinkWrapper(vertexMap.get(source), vertexMap.get(target));
-            links.add(l);
-        }
-
-        HierarchicalLayoutManager m = new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.NONE);
-
-        LayoutGraph layoutGraph = new LayoutGraph(links, vertices);
-        m.doLayout(layoutGraph);
-    }
-
-    protected void performNodesLayout(UniversalGraph<N, E> graph, Collection<N> nodes) {
-        throw new UnsupportedOperationException();
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/layer.xml	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
-<filesystem>
-    <folder name="Actions">
-        <folder name="Window">
-            <file name="com-sun-hotspot-igv-controlflow-ControlFlowAction.instance"/>
-        </folder>
-    </folder>
-    <folder name="Menu">
-        <folder name="Window">
-            <file name="ControlFlowAction.shadow">
-                <attr name="originalFile" stringvalue="Actions/Window/com-sun-hotspot-igv-controlflow-ControlFlowAction.instance"/>
-            </file>
-        </folder>
-    </folder>
-    <folder name="Windows2">
-        <folder name="Components">
-            <file name="ControlFlowTopComponent.settings" url="ControlFlowTopComponentSettings.xml"/>
-        </folder>
-        <folder name="Modes">
-            <folder name="customRightTopMode">
-                <file name="ControlFlowTopComponent.wstcref" url="ControlFlowTopComponentWstcref.xml"/>
-            </folder>
-        </folder>
-    </folder>
-</filesystem>
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/project.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/project.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -1,126 +1,142 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://www.netbeans.org/ns/project/1">
-    <type>org.netbeans.modules.apisupport.project</type>
-    <configuration>
-        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
-            <code-name-base>com.sun.hotspot.igv.coordinator</code-name-base>
-            <suite-component/>
-            <module-dependencies>
-                <dependency>
-                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.0</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>com.sun.hotspot.igv.difference</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.0</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>com.sun.hotspot.igv.settings</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.0</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>com.sun.hotspot.igv.util</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.0</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.netbeans.api.progress</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <release-version>1</release-version>
-                        <specification-version>1.10.0.1</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.actions</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>6.6.1.1</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.awt</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>6.11.0.1</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.dialogs</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>7.5.1</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.explorer</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>6.11</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.filesystems</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>7.3</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.loaders</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>6.7</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.nodes</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>7.2.0.1</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.util</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>7.9.0.1</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.windows</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>6.16</specification-version>
-                    </run-dependency>
-                </dependency>
-            </module-dependencies>
-            <public-packages/>
-        </data>
-    </configuration>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.coordinator</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.connection</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.difference</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.settings</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.api.progress</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.23.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.actions</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.21.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.30.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.dialogs</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.18.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.explorer</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.34.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.filesystems</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.46.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.loaders</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.20.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.nodes</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.20.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.39.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages/>
+        </data>
+    </configuration>
+</project>
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/META-INF/services/com.sun.hotspot.igv.data.services.GroupOrganizer	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-com.sun.hotspot.igv.coordinator.StandardGroupOrganizer
-com.sun.hotspot.igv.coordinator.GraphCountGroupOrganizer
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/Bundle.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,7 +1,6 @@
-
-AdvancedOption_DisplayName_Coordinator=Settings
-AdvancedOption_Tooltip_Coordinator=Visualization Tool Settings
-CTL_OutlineTopComponent=Outline Window
-CTL_SomeAction=test
-HINT_OutlineTopComponent=This is a Outline window
-OpenIDE-Module-Name=Coordinator
+AdvancedOption_DisplayName_Coordinator=Settings
+AdvancedOption_Tooltip_Coordinator=Visualization Tool Settings
+CTL_OutlineTopComponent=Outline
+CTL_SomeAction=test
+HINT_OutlineTopComponent=Displays loaded groups of graphs.
+OpenIDE-Module-Name=Coordinator
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -24,18 +24,13 @@
 package com.sun.hotspot.igv.coordinator;
 
 import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
-import com.sun.hotspot.igv.data.ChangedListener;
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.services.GroupOrganizer;
-import com.sun.hotspot.igv.data.InputGraph;
-import com.sun.hotspot.igv.data.Pair;
+import com.sun.hotspot.igv.data.*;
 import java.awt.Image;
-import java.util.ArrayList;
 import java.util.List;
 import org.openide.nodes.AbstractNode;
 import org.openide.nodes.Children;
 import org.openide.nodes.Node;
-import org.openide.util.Utilities;
+import org.openide.util.ImageUtilities;
 import org.openide.util.lookup.AbstractLookup;
 import org.openide.util.lookup.InstanceContent;
 
@@ -45,107 +40,72 @@
  */
 public class FolderNode extends AbstractNode {
 
-    private GroupOrganizer organizer;
     private InstanceContent content;
-    private List<Pair<String, List<Group>>> structure;
-    private List<String> subFolders;
     private FolderChildren children;
 
-    private static class FolderChildren extends Children.Keys implements ChangedListener<Group> {
+    private static class FolderChildren extends Children.Keys<FolderElement> implements ChangedListener {
+
+        private final Folder folder;
 
-        private FolderNode parent;
-        private List<Group> registeredGroups;
-
-        public void setParent(FolderNode parent) {
-            this.parent = parent;
-            this.registeredGroups = new ArrayList<Group>();
+        public FolderChildren(Folder folder) {
+            this.folder = folder;
+            folder.getChangedEvent().addListener(this);
         }
 
         @Override
-        protected Node[] createNodes(Object arg0) {
-
-            for(Group g : registeredGroups) {
-                g.getChangedEvent().removeListener(this);
-            }
-            registeredGroups.clear();
-
-            Pair<String, List<Group>> p = (Pair<String, List<Group>>) arg0;
-            if (p.getLeft().length() == 0) {
-
-                List<Node> curNodes = new ArrayList<Node>();
-                for (Group g : p.getRight()) {
-                    for (InputGraph graph : g.getGraphs()) {
-                        curNodes.add(new GraphNode(graph));
-                    }
-                    g.getChangedEvent().addListener(this);
-                    registeredGroups.add(g);
-                }
-
-                Node[] result = new Node[curNodes.size()];
-                for (int i = 0; i < curNodes.size(); i++) {
-                    result[i] = curNodes.get(i);
-                }
-                return result;
-
-            } else {
-                return new Node[]{new FolderNode(p.getLeft(), parent.organizer, parent.subFolders, p.getRight())};
+        protected Node[] createNodes(FolderElement e) {
+             if (e instanceof InputGraph) {
+                return new Node[]{new GraphNode((InputGraph) e)};
+            } else if (e instanceof Folder) {
+                 return new Node[]{new FolderNode((Folder) e)};
+             } else {
+                return null;
             }
         }
 
         @Override
         public void addNotify() {
-            this.setKeys(parent.structure);
+            this.setKeys(folder.getElements());
         }
-
-        public void changed(Group source) {
-            List<Pair<String, List<Group>>> newStructure = new ArrayList<Pair<String, List<Group>>>();
-            for(Pair<String, List<Group>> p : parent.structure) {
-                refreshKey(p);
-            }
-        }
-    }
-
-    protected InstanceContent getContent() {
-        return content;
+        
+        @Override
+        public void changed(Object source) {
+            addNotify();
+         }
     }
 
     @Override
     public Image getIcon(int i) {
-        return Utilities.loadImage("com/sun/hotspot/igv/coordinator/images/folder.gif");
+        return ImageUtilities.loadImage("com/sun/hotspot/igv/coordinator/images/folder.png");
     }
 
-    protected FolderNode(String name, GroupOrganizer organizer, List<String> subFolders, List<Group> groups) {
-        this(name, organizer, subFolders, groups, new FolderChildren(), new InstanceContent());
+    protected FolderNode(Folder folder) {
+        this(folder, new FolderChildren(folder), new InstanceContent());
     }
 
-    private FolderNode(String name, GroupOrganizer organizer, List<String> oldSubFolders, final List<Group> groups, FolderChildren children, InstanceContent content) {
+    private FolderNode(final Folder folder, FolderChildren children, InstanceContent content) {
         super(children, new AbstractLookup(content));
-        children.setParent(this);
         this.content = content;
         this.children = children;
-        content.add(new RemoveCookie() {
-
-            public void remove() {
-                for (Group g : groups) {
-                    if (g.getDocument() != null) {
-                        g.getDocument().removeGroup(g);
-                    }
+        if (folder instanceof FolderElement) {
+            final FolderElement folderElement = (FolderElement) folder;
+            this.setDisplayName(folderElement.getName());
+            content.add(new RemoveCookie() {
+                @Override
+                public void remove() {
+                    folderElement.getParent().removeElement(folderElement);
                 }
-            }
-        });
-        init(name, organizer, oldSubFolders, groups);
+            });
+        }
     }
 
-    public void init(String name, GroupOrganizer organizer, List<String> oldSubFolders, List<Group> groups) {
+    public void init(String name, List<Group> groups) {
         this.setDisplayName(name);
-        this.organizer = organizer;
-        this.subFolders = new ArrayList<String>(oldSubFolders);
-        if (name.length() > 0) {
-            this.subFolders.add(name);
+        children.addNotify();
+
+        for (Group g : groups) {
+            content.add(g);
         }
-        structure = organizer.organize(subFolders, groups);
-        assert structure != null;
-        children.addNotify();
     }
 
     @Override
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphCountGroupOrganizer.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.sun.hotspot.igv.coordinator;
-
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.Pair;
-import com.sun.hotspot.igv.data.services.GroupOrganizer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class GraphCountGroupOrganizer implements GroupOrganizer {
-
-    public String getName() {
-        return "Graph count structure";
-    }
-
-    public List<Pair<String, List<Group>>> organize(List<String> subFolders, List<Group> groups) {
-
-        List<Pair<String, List<Group>>> result = new ArrayList<Pair<String, List<Group>>>();
-
-        if (subFolders.size() == 0) {
-            Map<Integer, List<Group>> map = new HashMap<Integer, List<Group>>();
-            for (Group g : groups) {
-                Integer cur = g.getGraphs().size();
-                if (!map.containsKey(cur)) {
-                    map.put(cur, new ArrayList<Group>());
-                }
-                map.get(cur).add(g);
-            }
-
-            SortedSet<Integer> keys = new TreeSet<Integer>(map.keySet());
-            for (Integer i : keys) {
-                result.add(new Pair<String, List<Group>>("Graph count " + i, map.get(i)));
-            }
-
-        } else if (subFolders.size() == 1) {
-            for (Group g : groups) {
-                List<Group> children = new ArrayList<Group>();
-                children.add(g);
-                Pair<String, List<Group>> p = new Pair<String, List<Group>>();
-                p.setLeft(g.getName());
-                p.setRight(children);
-                result.add(p);
-            }
-        } else if (subFolders.size() == 2) {
-            result.add(new Pair<String, List<Group>>("", groups));
-        }
-
-        return result;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphNode.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -25,21 +25,20 @@
 
 import com.sun.hotspot.igv.coordinator.actions.DiffGraphAction;
 import com.sun.hotspot.igv.coordinator.actions.DiffGraphCookie;
-import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
+import com.sun.hotspot.igv.coordinator.actions.GraphOpenCookie;
+import com.sun.hotspot.igv.coordinator.actions.GraphRemoveCookie;
 import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.Properties;
 import com.sun.hotspot.igv.data.services.GraphViewer;
-import com.sun.hotspot.igv.data.services.InputGraphProvider;
 import com.sun.hotspot.igv.util.PropertiesSheet;
 import java.awt.Image;
 import javax.swing.Action;
 import org.openide.actions.OpenAction;
-import org.openide.cookies.OpenCookie;
 import org.openide.nodes.AbstractNode;
 import org.openide.nodes.Children;
-import org.openide.nodes.Node;
 import org.openide.nodes.Sheet;
+import org.openide.util.ImageUtilities;
 import org.openide.util.Lookup;
-import org.openide.util.Utilities;
 import org.openide.util.lookup.AbstractLookup;
 import org.openide.util.lookup.InstanceContent;
 
@@ -48,15 +47,14 @@
  * @author Thomas Wuerthinger
  */
 public class GraphNode extends AbstractNode {
-
-    private InputGraph graph;
+    private final InputGraph graph;
 
     /** Creates a new instance of GraphNode */
     public GraphNode(InputGraph graph) {
         this(graph, new InstanceContent());
     }
 
-    private GraphNode(final InputGraph graph, InstanceContent content) {
+    private GraphNode(InputGraph graph, InstanceContent content) {
         super(Children.LEAF, new AbstractLookup(content));
         this.graph = graph;
         this.setDisplayName(graph.getName());
@@ -66,33 +64,30 @@
 
         if (viewer != null) {
             // Action for opening the graph
-            content.add(new OpenCookie() {
-
-                public void open() {
-                    viewer.view(graph);
-                }
-            });
+            content.add(new GraphOpenCookie(viewer, graph));
         }
 
         // Action for removing a graph
-        content.add(new RemoveCookie() {
+        content.add(new GraphRemoveCookie(graph));
 
-            public void remove() {
-                graph.getGroup().removeGraph(graph);
-            }
-        });
+        // Action for diffing to the current graph
+        content.add(new DiffGraphCookie(graph));
     }
 
     @Override
     protected Sheet createSheet() {
         Sheet s = super.createSheet();
-        PropertiesSheet.initializeSheet(graph.getProperties(), s);
+        Properties p = new Properties();
+        p.add(graph.getProperties());
+        p.setProperty("nodeCount", Integer.toString(graph.getNodes().size()));
+        p.setProperty("edgeCount", Integer.toString(graph.getEdges().size()));
+        PropertiesSheet.initializeSheet(p, s);
         return s;
     }
 
     @Override
     public Image getIcon(int i) {
-        return Utilities.loadImage("com/sun/hotspot/igv/coordinator/images/graph.gif");
+        return ImageUtilities.loadImage("com/sun/hotspot/igv/coordinator/images/graph.png");
     }
 
     @Override
@@ -101,24 +96,6 @@
     }
 
     @Override
-    public <T extends Node.Cookie> T getCookie(Class<T> aClass) {
-        if (aClass == DiffGraphCookie.class) {
-            InputGraphProvider graphProvider = Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
-
-            InputGraph graphA = null;
-            if (graphProvider != null) {
-                graphA = graphProvider.getGraph();
-            }
-
-            if (graphA != null && !graphA.isDifferenceGraph()) {
-                return (T) new DiffGraphCookie(graphA, graph);
-            }
-        }
-
-        return super.getCookie(aClass);
-    }
-
-    @Override
     public Action[] getActions(boolean b) {
         return new Action[]{(Action) DiffGraphAction.findObject(DiffGraphAction.class, true), (Action) OpenAction.findObject(OpenAction.class, true)};
     }
@@ -127,4 +104,20 @@
     public Action getPreferredAction() {
         return (Action) OpenAction.findObject(OpenAction.class, true);
     }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof GraphNode) {
+            return (graph == ((GraphNode) obj).graph);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return graph.hashCode();
+    }
 }
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.form	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.form	Mon Feb 27 13:10:13 2012 +0100
@@ -3,6 +3,8 @@
 <Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
   <AuxValues>
     <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
     <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
@@ -14,28 +16,17 @@
 
   <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
   <SubComponents>
-    <Container class="javax.swing.JPanel" name="jPanel2">
+    <Container class="javax.swing.JScrollPane" name="treeView">
+      <AuxValues>
+        <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new BeanTreeView();"/>
+      </AuxValues>
       <Constraints>
         <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
           <BorderConstraints direction="Center"/>
         </Constraint>
       </Constraints>
 
-      <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
-      <SubComponents>
-        <Container class="javax.swing.JScrollPane" name="jScrollPane1">
-          <AuxValues>
-            <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new BeanTreeView();"/>
-          </AuxValues>
-          <Constraints>
-            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
-              <BorderConstraints direction="Center"/>
-            </Constraint>
-          </Constraints>
-
-          <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
-        </Container>
-      </SubComponents>
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
     </Container>
   </SubComponents>
 </Form>
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,37 +23,25 @@
  */
 package com.sun.hotspot.igv.coordinator;
 
-import com.sun.hotspot.igv.coordinator.actions.ImportAction;
-import com.sun.hotspot.igv.coordinator.actions.RemoveAction;
-import com.sun.hotspot.igv.coordinator.actions.RemoveAllAction;
-import com.sun.hotspot.igv.coordinator.actions.SaveAllAction;
-import com.sun.hotspot.igv.coordinator.actions.SaveAsAction;
-import com.sun.hotspot.igv.coordinator.actions.StructuredViewAction;
+import com.sun.hotspot.igv.connection.Server;
+import com.sun.hotspot.igv.coordinator.actions.*;
 import com.sun.hotspot.igv.data.GraphDocument;
-import com.sun.hotspot.igv.data.ChangedListener;
 import com.sun.hotspot.igv.data.Group;
 import com.sun.hotspot.igv.data.services.GroupCallback;
-import com.sun.hotspot.igv.data.services.GroupOrganizer;
-import com.sun.hotspot.igv.data.services.GroupReceiver;
 import java.awt.BorderLayout;
-import java.awt.Component;
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
 import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import javax.swing.BoxLayout;
-import javax.swing.JPanel;
 import javax.swing.UIManager;
 import javax.swing.border.Border;
 import org.openide.ErrorManager;
+import org.openide.actions.GarbageCollectAction;
 import org.openide.awt.Toolbar;
 import org.openide.awt.ToolbarPool;
 import org.openide.explorer.ExplorerManager;
 import org.openide.explorer.ExplorerUtils;
 import org.openide.explorer.view.BeanTreeView;
-import org.openide.util.Lookup;
 import org.openide.util.LookupEvent;
 import org.openide.util.LookupListener;
 import org.openide.util.NbBundle;
@@ -62,7 +50,7 @@
 import org.openide.windows.WindowManager;
 
 /**
- *
+ * 
  * @author Thomas Wuerthinger
  */
 public final class OutlineTopComponent extends TopComponent implements ExplorerManager.Provider, LookupListener {
@@ -72,7 +60,7 @@
     private ExplorerManager manager;
     private GraphDocument document;
     private FolderNode root;
-    private GroupOrganizer organizer;
+    private Server server;
 
     private OutlineTopComponent() {
         initComponents();
@@ -88,17 +76,9 @@
 
     private void initListView() {
         manager = new ExplorerManager();
-        organizer = new StandardGroupOrganizer();
-        root = new FolderNode("", organizer, new ArrayList<String>(), document.getGroups());
+        root = new FolderNode(document);
         manager.setRootContext(root);
-        ((BeanTreeView) this.jScrollPane1).setRootVisible(false);
-
-        document.getChangedEvent().addListener(new ChangedListener<GraphDocument>() {
-
-            public void changed(GraphDocument document) {
-                updateStructure();
-            }
-        });
+        ((BeanTreeView) this.treeView).setRootVisible(false);
 
         associateLookup(ExplorerUtils.createLookup(manager, getActionMap()));
     }
@@ -111,61 +91,38 @@
         this.add(toolbar, BorderLayout.NORTH);
 
         toolbar.add(ImportAction.get(ImportAction.class));
-        toolbar.add(((NodeAction) RemoveAction.get(RemoveAction.class)).createContextAwareInstance(this.getLookup()));
-        toolbar.add(RemoveAllAction.get(RemoveAllAction.class));
 
         toolbar.add(((NodeAction) SaveAsAction.get(SaveAsAction.class)).createContextAwareInstance(this.getLookup()));
         toolbar.add(SaveAllAction.get(SaveAllAction.class));
 
-        toolbar.add(StructuredViewAction.get(StructuredViewAction.class).getToolbarPresenter());
+        toolbar.add(((NodeAction) RemoveAction.get(RemoveAction.class)).createContextAwareInstance(this.getLookup()));
+        toolbar.add(RemoveAllAction.get(RemoveAllAction.class));
+        
+        toolbar.add(GarbageCollectAction.get(GarbageCollectAction.class).getToolbarPresenter());
 
         for (Toolbar tb : ToolbarPool.getDefault().getToolbars()) {
             tb.setVisible(false);
         }
-
-        initOrganizers();
-    }
-
-    public void setOrganizer(GroupOrganizer organizer) {
-        this.organizer = organizer;
-        updateStructure();
-    }
-
-    private void initOrganizers() {
-
     }
 
     private void initReceivers() {
 
         final GroupCallback callback = new GroupCallback() {
 
+            @Override
             public void started(Group g) {
-                getDocument().addGroup(g);
+                getDocument().addElement(g);
             }
         };
-
-        Collection<? extends GroupReceiver> receivers = Lookup.getDefault().lookupAll(GroupReceiver.class);
-        if (receivers.size() > 0) {
-            JPanel panel = new JPanel();
-            panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
-
-            for (GroupReceiver r : receivers) {
-                Component c = r.init(callback);
-                panel.add(c);
-            }
-
-            jPanel2.add(panel, BorderLayout.PAGE_START);
-        }
-    }
-
-    private void updateStructure() {
-        root.init("", organizer, new ArrayList<String>(), document.getGroups());
+        
+        server = new Server(callback);
     }
 
     public void clear() {
         document.clear();
     }
 
+    @Override
     public ExplorerManager getExplorerManager() {
         return manager;
     }
@@ -221,6 +178,25 @@
         return PREFERRED_ID;
     }
 
+    @Override
+    public void requestActive() {
+        super.requestActive();
+        treeView.requestFocus();
+    }
+
+    @Override
+    public boolean requestFocus(boolean temporary) {
+        treeView.requestFocus();
+        return super.requestFocus(temporary);
+    }
+
+    @Override
+    protected boolean requestFocusInWindow(boolean temporary) {
+        treeView.requestFocus();
+        return super.requestFocusInWindow(temporary);
+    }
+
+    @Override
     public void resultChanged(LookupEvent lookupEvent) {
     }
 
@@ -228,7 +204,7 @@
     public void readExternal(ObjectInput objectInput) throws IOException, ClassNotFoundException {
         // Not called when user starts application for the first time
         super.readExternal(objectInput);
-        ((BeanTreeView) this.jScrollPane1).setRootVisible(false);
+        ((BeanTreeView) this.treeView).setRootVisible(false);
     }
 
     @Override
@@ -253,19 +229,13 @@
     // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
     private void initComponents() {
 
-        jPanel2 = new javax.swing.JPanel();
-        jScrollPane1 = new BeanTreeView();
+        treeView = new BeanTreeView();
 
         setLayout(new java.awt.BorderLayout());
-
-        jPanel2.setLayout(new java.awt.BorderLayout());
-        jPanel2.add(jScrollPane1, java.awt.BorderLayout.CENTER);
-
-        add(jPanel2, java.awt.BorderLayout.CENTER);
+        add(treeView, java.awt.BorderLayout.CENTER);
     }// </editor-fold>//GEN-END:initComponents
 
     // Variables declaration - do not modify//GEN-BEGIN:variables
-    private javax.swing.JPanel jPanel2;
-    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JScrollPane treeView;
     // End of variables declaration//GEN-END:variables
 }
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/StandardConfiguration.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/StandardConfiguration.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -4,7 +4,7 @@
     <Row>
         <Toolbar name="Edit" position="1" visible="false"/>
         <Toolbar name="File" position="1" visible="false" />
-        <Toolbar name="Memory" position="1" visible="false" />
+        <Toolbar name="Memory" position="1" visible="true" />
     </Row>
     <Row>
         <Toolbar name="WorkspaceSwitcher" />
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/StandardGroupOrganizer.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.sun.hotspot.igv.coordinator;
-
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.services.GroupOrganizer;
-import com.sun.hotspot.igv.data.Pair;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class StandardGroupOrganizer implements GroupOrganizer {
-
-    public String getName() {
-        return "-- None --";
-    }
-
-    public List<Pair<String, List<Group>>> organize(List<String> subFolders, List<Group> groups) {
-
-        List<Pair<String, List<Group>>> result = new ArrayList<Pair<String, List<Group>>>();
-
-        if (groups.size() == 1 && subFolders.size() > 0) {
-            result.add(new Pair<String, List<Group>>("", groups));
-        } else {
-            for (Group g : groups) {
-                List<Group> children = new ArrayList<Group>();
-                children.add(g);
-                Pair<String, List<Group>> p = new Pair<String, List<Group>>();
-                p.setLeft(g.getName());
-                p.setRight(children);
-                result.add(p);
-            }
-        }
-
-        return result;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/Bundle.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,18 +1,10 @@
-CTL_EditFilterAction=Edit...
 CTL_ImportAction=Open...
 CTL_OpenGraphAction=View graph
 CTL_DiffGraphAction=Difference to current graph
-CTL_RemoveAction=Remove methods
-CTL_ApplyFilterAction=Apply
-CTL_FilterAction=Open Filter Window
-CTL_AppliedFilterAction=Open AppliedFilter Window
-CTL_OutlineAction=Open Outline Window
-CTL_MoveFilterUpAction=Move upwards
-CTL_MoveFilterDownAction=Move downwards
-CTL_RemoveFilterAction=Remove
-CTL_RemoveFilterSettingsAction=Remove filter setting
-CTL_SaveAsAction=Save selected methods...
-CTL_SaveAllAction=Save all...
-CTL_SaveFilterSettingsAction=Save filter settings...
-CTL_PropertiesAction=Open Properties Window
+CTL_RemoveAction=Remove selected graphs and groups
+CTL_RemoveAllAction=Remove all graphs and groups
+CTL_OutlineAction=Outline
+CTL_SaveAsAction=Save selected groups...
+CTL_SaveAllAction=Save all groups...
+CTL_PropertiesAction=Open Properties Window 
 CTL_NewFilterAction=New filter...
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/DiffGraphAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/DiffGraphAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -35,30 +35,49 @@
  */
 public final class DiffGraphAction extends CookieAction {
 
+    @Override
     protected void performAction(Node[] activatedNodes) {
         DiffGraphCookie c = activatedNodes[0].getCookie(DiffGraphCookie.class);
+        assert c != null;
         c.openDiff();
     }
 
+    @Override
     protected int mode() {
         return CookieAction.MODE_EXACTLY_ONE;
     }
 
+    @Override
+    protected boolean enable(Node[] activatedNodes) {
+        boolean b = super.enable(activatedNodes);
+        if (b) {
+            assert activatedNodes.length == 1;
+            DiffGraphCookie c = activatedNodes[0].getCookie(DiffGraphCookie.class);
+            assert c != null;
+            return c.isPossible();
+        }
+
+        return false;
+    }
+
+    @Override
     public String getName() {
         return NbBundle.getMessage(DiffGraphAction.class, "CTL_DiffGraphAction");
     }
 
-    protected Class[] cookieClasses() {
-        return new Class[]{
+    @Override
+    protected Class<?>[] cookieClasses() {
+        return new Class<?>[]{
             DiffGraphCookie.class
         };
     }
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/coordinator/images/diff.gif";
+        return "com/sun/hotspot/igv/coordinator/images/diff.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -68,3 +87,4 @@
         return false;
     }
 }
+
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/DiffGraphCookie.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/DiffGraphCookie.java	Mon Feb 27 13:10:13 2012 +0100
@@ -21,12 +21,13 @@
  * questions.
  *
  */
-
 package com.sun.hotspot.igv.coordinator.actions;
 
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.services.GraphViewer;
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
 import com.sun.hotspot.igv.difference.Difference;
+import com.sun.hotspot.igv.util.LookupHistory;
 import org.openide.nodes.Node;
 import org.openide.util.Lookup;
 
@@ -36,20 +37,29 @@
  */
 public class DiffGraphCookie implements Node.Cookie {
 
-    private InputGraph a;
-    private InputGraph b;
+    private InputGraph graph;
+
+    public DiffGraphCookie(InputGraph graph) {
+        this.graph = graph;
+    }
 
-    public DiffGraphCookie(InputGraph a, InputGraph b) {
-        this.a = a;
-        this.b = b;
+    private InputGraph getCurrentGraph() {
+        InputGraphProvider graphProvider = LookupHistory.getLast(InputGraphProvider.class);
+        if (graphProvider != null) {
+            return graphProvider.getGraph();
+        }
+        return null;
+    }
+
+    public boolean isPossible() {
+        return getCurrentGraph() != null;
     }
 
     public void openDiff() {
-
+        InputGraph other = getCurrentGraph();
         final GraphViewer viewer = Lookup.getDefault().lookup(GraphViewer.class);
-
-        if(viewer != null) {
-            InputGraph diffGraph = Difference.createDiffGraph(a, b);
+        if (viewer != null) {
+            InputGraph diffGraph = Difference.createDiffGraph(other, graph);
             viewer.view(diffGraph);
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/GraphOpenCookie.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,44 @@
+/*
+ * 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.sun.hotspot.igv.coordinator.actions;
+
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.services.GraphViewer;
+import org.openide.cookies.OpenCookie;
+
+public class GraphOpenCookie implements OpenCookie {
+
+    private final GraphViewer viewer;
+    private final InputGraph graph;
+
+    public GraphOpenCookie(GraphViewer viewer, InputGraph graph) {
+        this.viewer = viewer;
+        this.graph = graph;
+    }
+
+    @Override
+    public void open() {
+        viewer.view(graph);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/GraphRemoveCookie.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,39 @@
+/*
+ * 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.sun.hotspot.igv.coordinator.actions;
+
+import com.sun.hotspot.igv.data.InputGraph;
+
+public class GraphRemoveCookie implements RemoveCookie {
+    private final InputGraph graph;
+
+    public GraphRemoveCookie(InputGraph graph) {
+        this.graph = graph;
+    }
+
+    @Override
+    public void remove() {
+        graph.getGroup().removeElement(graph);
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/ImportAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/ImportAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -27,8 +27,8 @@
 import com.sun.hotspot.igv.coordinator.OutlineTopComponent;
 import com.sun.hotspot.igv.data.GraphDocument;
 import com.sun.hotspot.igv.data.serialization.Parser;
+import com.sun.hotspot.igv.data.serialization.XMLParser;
 import com.sun.hotspot.igv.settings.Settings;
-import com.sun.hotspot.igv.data.serialization.XMLParser;
 import java.awt.event.InputEvent;
 import java.awt.event.KeyEvent;
 import java.io.File;
@@ -38,6 +38,7 @@
 import javax.swing.Action;
 import javax.swing.JFileChooser;
 import javax.swing.KeyStroke;
+import javax.swing.SwingUtilities;
 import javax.swing.filechooser.FileFilter;
 import org.netbeans.api.progress.ProgressHandle;
 import org.netbeans.api.progress.ProgressHandleFactory;
@@ -47,10 +48,8 @@
 import org.openide.util.NbBundle;
 import org.openide.util.RequestProcessor;
 import org.openide.util.actions.CallableSystemAction;
-import org.openide.xml.XMLUtil;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
 
 /**
  *
@@ -61,16 +60,19 @@
     public static FileFilter getFileFilter() {
         return new FileFilter() {
 
+            @Override
             public boolean accept(File f) {
                 return f.getName().toLowerCase().endsWith(".xml") || f.isDirectory();
             }
 
+            @Override
             public String getDescription() {
                 return "XML files (*.xml)";
             }
         };
     }
 
+    @Override
     public void performAction() {
 
         JFileChooser fc = new JFileChooser();
@@ -88,7 +90,6 @@
             Settings.get().put(Settings.DIRECTORY, dir.getAbsolutePath());
 
             try {
-                final XMLReader reader = XMLUtil.createXMLReader();
                 final FileInputStream inputStream = new FileInputStream(file);
                 final InputSource is = new InputSource(inputStream);
 
@@ -99,6 +100,7 @@
 
                 final XMLParser.ParseMonitor parseMonitor = new XMLParser.ParseMonitor() {
 
+                    @Override
                     public void setProgress(double d) {
                         try {
                             int curAvailable = inputStream.available();
@@ -108,6 +110,7 @@
                         }
                     }
 
+                    @Override
                     public void setState(String state) {
                         setProgress(0.0);
                         handle.progress(state);
@@ -120,12 +123,18 @@
 
                 RequestProcessor.getDefault().post(new Runnable() {
 
+                    @Override
                     public void run() {
-                        GraphDocument document = null;
                         try {
-                            document = parser.parse(reader, is, parseMonitor);
+                            final GraphDocument document = parser.parse(is, parseMonitor);
                             parseMonitor.setState("Finishing");
-                            component.getDocument().addGraphDocument(document);
+                            SwingUtilities.invokeLater(new Runnable(){
+
+                                @Override
+                                public void run() {
+                                    component.getDocument().addGraphDocument(document);
+                                }
+                            });
                         } catch (SAXException ex) {
                             String s = "Exception during parsing the XML file, could not load document!";
                             if (ex instanceof XMLParser.MissingAttributeException) {
@@ -140,8 +149,6 @@
                     }
                 });
 
-            } catch (SAXException ex) {
-                ex.printStackTrace();
             } catch (FileNotFoundException ex) {
                 ex.printStackTrace();
             } catch (IOException ex) {
@@ -150,20 +157,22 @@
         }
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(ImportAction.class, "CTL_ImportAction");
     }
 
     public ImportAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Open an XML graph document");
+        putValue(Action.SHORT_DESCRIPTION, "Open XML graph document...");
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));
     }
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/coordinator/images/import.gif";
+        return "com/sun/hotspot/igv/coordinator/images/import.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/OutlineAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/OutlineAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -24,7 +24,7 @@
 
 package com.sun.hotspot.igv.coordinator.actions;
 
-import com.sun.hotspot.igv.coordinator.*;
+import com.sun.hotspot.igv.coordinator.OutlineTopComponent;
 import java.awt.event.ActionEvent;
 import javax.swing.AbstractAction;
 import org.openide.util.NbBundle;
@@ -40,6 +40,7 @@
         super(NbBundle.getMessage(OutlineAction.class, "CTL_OutlineAction"));
     }
 
+    @Override
     public void actionPerformed(ActionEvent evt) {
         TopComponent win = OutlineTopComponent.findInstance();
         win.open();
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -36,6 +36,7 @@
  */
 public final class RemoveAction extends NodeAction {
 
+    @Override
     protected void performAction(Node[] activatedNodes) {
         for (Node n : activatedNodes) {
             RemoveCookie removeCookie = n.getCookie(RemoveCookie.class);
@@ -46,18 +47,20 @@
     }
 
     public RemoveAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Remove");
+        putValue(Action.SHORT_DESCRIPTION, "Remove selected graphs and groups");
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(RemoveAction.class, "CTL_RemoveAction");
     }
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/coordinator/images/remove.gif";
+        return "com/sun/hotspot/igv/coordinator/images/remove.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -67,6 +70,7 @@
         return false;
     }
 
+    @Override
     protected boolean enable(Node[] nodes) {
         return nodes.length > 0;
     }
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveAllAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveAllAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -40,20 +40,22 @@
 public final class RemoveAllAction extends CallableSystemAction {
 
 
+    @Override
     public String getName() {
-        return NbBundle.getMessage(RemoveAllAction.class, "CTL_ImportAction");
+        return NbBundle.getMessage(RemoveAllAction.class, "CTL_RemoveAllAction");
     }
 
     public RemoveAllAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Remove all methods");
+        putValue(Action.SHORT_DESCRIPTION, "Remove all graphs and groups");
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_SHIFT, InputEvent.CTRL_MASK));
     }
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/coordinator/images/removeall.gif";
+        return "com/sun/hotspot/igv/coordinator/images/removeall.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAllAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAllAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -39,17 +39,19 @@
  */
 public final class SaveAllAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         final OutlineTopComponent component = OutlineTopComponent.findInstance();
         SaveAsAction.save(component.getDocument());
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(SaveAllAction.class, "CTL_SaveAllAction");
     }
 
     public SaveAllAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Save all methods to XML file");
+        putValue(Action.SHORT_DESCRIPTION, "Save all groups to XML file...");
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK));
     }
 
@@ -58,6 +60,7 @@
         return "com/sun/hotspot/igv/coordinator/images/saveall.gif";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAsAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAsAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -28,12 +28,8 @@
 import com.sun.hotspot.igv.data.Group;
 import com.sun.hotspot.igv.data.serialization.Printer;
 import com.sun.hotspot.igv.settings.Settings;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
+import java.io.*;
+import javax.swing.Action;
 import javax.swing.JFileChooser;
 import org.openide.nodes.Node;
 import org.openide.util.HelpCtx;
@@ -47,12 +43,17 @@
  */
 public final class SaveAsAction extends NodeAction {
 
+    public SaveAsAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Save selected groups to XML file...");
+    }
+
+    @Override
     protected void performAction(Node[] activatedNodes) {
 
         GraphDocument doc = new GraphDocument();
         for (Node n : activatedNodes) {
             Group group = n.getLookup().lookup(Group.class);
-            doc.addGroup(group);
+            doc.addElement(group);
         }
 
         save(doc);
@@ -75,10 +76,10 @@
             }
             Settings.get().put(Settings.DIRECTORY, dir.getAbsolutePath());
             try {
-                Writer writer = new OutputStreamWriter(new FileOutputStream(file));
-                Printer p = new Printer();
-                p.export(writer, doc);
-                writer.close();
+                try (Writer writer = new OutputStreamWriter(new FileOutputStream(file))) {
+                    Printer p = new Printer();
+                    p.export(writer, doc);
+                }
             } catch (FileNotFoundException e) {
                 e.printStackTrace();
             } catch (IOException e) {
@@ -92,15 +93,17 @@
         return CookieAction.MODE_SOME;
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(SaveAsAction.class, "CTL_SaveAsAction");
     }
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/coordinator/images/save.gif";
+        return "com/sun/hotspot/igv/coordinator/images/save.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -110,6 +113,7 @@
         return false;
     }
 
+    @Override
     protected boolean enable(Node[] nodes) {
 
         int cnt = 0;
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/StructuredViewAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.sun.hotspot.igv.coordinator.actions;
-
-import com.sun.hotspot.igv.coordinator.OutlineTopComponent;
-import com.sun.hotspot.igv.data.services.GroupOrganizer;
-import java.awt.Component;
-import java.awt.Image;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import javax.swing.Action;
-import javax.swing.ButtonGroup;
-import javax.swing.ImageIcon;
-import javax.swing.JButton;
-import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JMenuItem;
-import javax.swing.JPopupMenu;
-import javax.swing.event.PopupMenuEvent;
-import javax.swing.event.PopupMenuListener;
-import org.openide.awt.DropDownButtonFactory;
-import org.openide.util.HelpCtx;
-import org.openide.util.Lookup;
-import org.openide.util.Utilities;
-import org.openide.util.actions.CallableSystemAction;
-
-public class StructuredViewAction extends CallableSystemAction {
-
-    private static JButton dropDownButton;
-    private static ButtonGroup buttonGroup;
-    private static JPopupMenu popup;
-    private MyMenuItemListener menuItemListener;
-    private Map<JMenuItem, GroupOrganizer> map;
-
-    public StructuredViewAction() {
-
-        putValue(Action.SHORT_DESCRIPTION, "Cluster nodes into blocks");
-    }
-
-    @Override
-    public Component getToolbarPresenter() {
-
-        Image iconImage = Utilities.loadImage("com/sun/hotspot/igv/coordinator/images/structure.gif");
-        ImageIcon icon = new ImageIcon(iconImage);
-
-        popup = new JPopupMenu();
-
-        menuItemListener = new MyMenuItemListener();
-
-        buttonGroup = new ButtonGroup();
-
-        Collection<? extends GroupOrganizer> organizersCollection = Lookup.getDefault().lookupAll(GroupOrganizer.class);
-
-        List<GroupOrganizer> organizers = new ArrayList<GroupOrganizer>(organizersCollection);
-        Collections.sort(organizers, new Comparator<GroupOrganizer>() {
-            public int compare(GroupOrganizer a, GroupOrganizer b) {
-                return a.getName().compareTo(b.getName());
-            }
-        });
-
-        map = new HashMap<JMenuItem, GroupOrganizer>();
-
-        boolean first = true;
-        for(GroupOrganizer organizer : organizers) {
-            JCheckBoxMenuItem item = new JCheckBoxMenuItem(organizer.getName());
-            map.put(item, organizer);
-            item.addActionListener(menuItemListener);
-            buttonGroup.add(item);
-            popup.add(item);
-            if(first) {
-                item.setSelected(true);
-                first = false;
-            }
-        }
-
-        dropDownButton = DropDownButtonFactory.createDropDownButton(
-                new ImageIcon(
-                new BufferedImage(32, 32, BufferedImage.TYPE_BYTE_GRAY)),
-                popup);
-
-        dropDownButton.setIcon(icon);
-
-        dropDownButton.setToolTipText("Insert Layer Registration");
-
-        dropDownButton.addItemListener(new ItemListener() {
-
-            public void itemStateChanged(ItemEvent e) {
-                int state = e.getStateChange();
-                if (state == ItemEvent.SELECTED) {
-                    performAction();
-                }
-            }
-        });
-
-        dropDownButton.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
-                performAction();
-            }
-        });
-
-        popup.addPopupMenuListener(new PopupMenuListener() {
-
-            public void popupMenuCanceled(PopupMenuEvent e) {
-                dropDownButton.setSelected(false);
-            }
-
-            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
-                dropDownButton.setSelected(false);
-            }
-
-            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
-                dropDownButton.setSelected(true);
-            }
-        });
-
-        return dropDownButton;
-
-    }
-
-    private class MyMenuItemListener implements ActionListener {
-
-        public void actionPerformed(ActionEvent ev) {
-            JMenuItem item = (JMenuItem) ev.getSource();
-            GroupOrganizer organizer = map.get(item);
-            assert organizer != null : "Organizer must exist!";
-            OutlineTopComponent.findInstance().setOrganizer(organizer);
-        }
-    }
-
-
-    @Override
-    public void performAction() {
-        popup.show(dropDownButton, 0, dropDownButton.getHeight());
-    }
-
-    public String getName() {
-        return "Structured View";
-    }
-
-    public HelpCtx getHelpCtx() {
-        return HelpCtx.DEFAULT_HELP;
-    }
-
-    @Override
-    protected boolean asynchronous() {
-        return false;
-    }
-
-}
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/customLeftWsmode.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/customLeftWsmode.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -4,12 +4,8 @@
     <kind type="view" />
     <state type="joined" />
     <constraints>
-        <path orientation="horizontal" number="0" weight="0.779245283018868"/>
-        <path orientation="vertical" number="0" weight="0.7511825922421949"/>
-        <path orientation="horizontal" number="0" weight="0.5"/>
-        <path orientation="vertical" number="20" weight="0.7"/>
-        <path orientation="horizontal" number="40" weight="0.55"/>
-        <path orientation="horizontal" number="0" weight="0.2711864406779661"/>
+        <path orientation="horizontal" number="0" weight="0.2"/>
+        <path orientation="vertical" number="0" weight="0.75"/>
     </constraints>
     <bounds x="0" y="0" width="0" height="0" />
     <frame state="0"/>
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/diff.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/diff.png has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/folder.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/folder.png has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/graph.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/graph.png has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/import.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/import.png has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/remove.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/remove.png has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/removeall.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/removeall.png has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/save.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/save.png has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/saveall.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/structure.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/structure.png has changed
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/layer.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/layer.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -1,110 +1,194 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
 <filesystem>
-    <attr name="Actions\Edit\com-sun-hotspot-igv-bytecodes-SelectBytecodesAction.instance\position" intvalue="200"/>
-    <attr name="Actions\Edit\org-netbeans-core-ui-sysopen-SystemOpenAction.instance\position" intvalue="100"/>
-    <attr name="Actions\Edit\org-openide-actions-CopyAction.instance\position" intvalue="1300"/>
-    <attr name="Actions\Edit\org-openide-actions-CutAction.instance\position" intvalue="1400"/>
-    <attr name="Actions\Edit\org-openide-actions-DeleteAction.instance\position" intvalue="1500"/>
-    <attr name="Actions\Edit\org-openide-actions-FindAction.instance\position" intvalue="1600"/>
-    <attr name="Actions\Edit\org-openide-actions-GotoAction.instance\position" intvalue="1700"/>
-    <attr name="Actions\Edit\org-openide-actions-PasteAction.instance\position" intvalue="1800"/>
-    <attr name="Actions\Edit\org-openide-actions-RedoAction.instance\position" intvalue="1900"/>
-    <attr name="Actions\Edit\org-openide-actions-ReplaceAction.instance\position" intvalue="2000"/>
-    <attr name="Actions\Edit\org-openide-actions-UndoAction.instance\position" intvalue="2100"/>
-
     <folder name="Actions">
         <folder name="File">
-            <file name="com-sun-hotspot-igv-coordinator-actions-SaveAsAction.instance">
-                <attr name="position" intvalue="700"/>
-            </file>
-            <file name="com-sun-hotspot-igv-coordinator-actions-SaveAllAction.instance">
-                <attr name="position" intvalue="800"/>
-            </file>
-            <file name="com-sun-hotspot-igv-coordinator-actions-ImportAction.instance">
-                <attr name="position" intvalue="1000"/>
-            </file>
+            <file name="com-sun-hotspot-igv-coordinator-actions-SaveAsAction.instance"/>
+            <file name="com-sun-hotspot-igv-coordinator-actions-SaveAllAction.instance"/>
+            <file name="com-sun-hotspot-igv-coordinator-actions-ImportAction.instance"/>
         </folder>
         <folder name="Edit">
-
-            <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAction.instance">
-                <attr name="position" intvalue="1200"/>
-            </file>
+            <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAction.instance"/>
+            <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAllAction.instance"/>
         </folder>
         <folder name="Window">
             <file name="com-sun-hotspot-igv-coordinator-actions-OutlineAction.instance"/>
         </folder>
     </folder>
+    
     <folder name="Menu">
         <folder name="File">
+            <file name="Separator2.instance_hidden"/>
+            <file name="Separator3.instance_hidden"/>
+            <file name="SeparatorOpen.instance_hidden"/>
             <file name="com-sun-hotspot-igv-coordinator-actions-ImportAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/File/com-sun-hotspot-igv-coordinator-actions-ImportAction.instance"/>
                 <attr name="position" intvalue="100"/>
             </file>
-            <file name="MySeparator2.instance">
+            <file name="SeparatorSave.instance">
                 <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
-                <attr name="position" intvalue="300"/>
+                <attr name="position" intvalue="150"/>
             </file>
             <file name="com-sun-hotspot-igv-coordinator-actions-SaveAsAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/File/com-sun-hotspot-igv-coordinator-actions-SaveAsAction.instance"/>
-                <attr name="position" intvalue="300"/>
+                <attr name="position" intvalue="200"/>
             </file>
             <file name="com-sun-hotspot-igv-coordinator-actions-SaveAllAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/File/com-sun-hotspot-igv-coordinator-actions-SaveAllAction.instance"/>
-                <attr name="position" intvalue="400"/>
-            </file>
-            <file name="MySeparator3.instance">
-                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
-                <attr name="position" intvalue="500"/>
+                <attr name="position" intvalue="300"/>
             </file>
-
-            <file name="org-netbeans-modules-openfile-OpenFileAction.instance_hidden"/>
-            <file name="org-openide-actions-PageSetupAction.instance_hidden"/>
-            <file name="org-openide-actions-PrintAction.instance_hidden"/>
-            <file name="org-openide-actions-SaveAction.instance_hidden"/>
-            <file name="org-openide-actions-SaveAllAction.instance_hidden"/>
-            <file name="org-openide-actions-SaveAsAction.shadow_hidden"/>
-        </folder>
-        <folder name="Edit">
-            <file name="com-sun-hotspot-igv-coordinator-actions-SaveFilterSettingsAction.shadow">
-                <attr name="originalFile" stringvalue="Actions/Edit/com-sun-hotspot-igv-coordinator-actions-SaveFilterSettingsAction.instance"/>
+            <file name="SeparatorRemove.instance">
+                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
+                <attr name="position" intvalue="350"/>
             </file>
             <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/Edit/com-sun-hotspot-igv-coordinator-actions-RemoveAction.instance"/>
+                <attr name="position" intvalue="400" />
             </file>
-            <file name="org-netbeans-core-actions-JumpNextAction.shadow_hidden"/>
-            <file name="org-netbeans-core-actions-JumpPrevAction.shadow_hidden"/>
-            <file name="org-openide-actions-CutAction.instance_hidden"/>
-            <file name="org-openide-actions-CopyAction.instance_hidden"/>
-            <file name="org-openide-actions-PasteAction.instance_hidden"/>
-            <file name="org-openide-actions-DeleteAction.instance_hidden"/>
-            <file name="org-openide-actions-FindAction.instance_hidden"/>
-            <file name="org-openide-actions-ReplaceAction.instance_hidden"/>
-            <file name="org-openide-actions-JumpNextAction.shadow_hidden"/>
-            <file name="org-openide-actions-JumpPrevAction.shadow_hidden"/>
+            <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAllAction.shadow">
+                <attr name="originalFile" stringvalue="Actions/Edit/com-sun-hotspot-igv-coordinator-actions-RemoveAllAction.instance"/>
+                <attr name="position" intvalue="500" />
+            </file>
+            
+            <!-- Hidden menu entries from other modules -->
+            <file name="org-netbeans-modules-editor-ExportHtmlAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-openfile-OpenFileAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-openfile-RecentFileAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-print-action-PageSetupAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-print-action-PrintAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-CloseProject.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-CustomizeProject.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-NewFile.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-NewProject.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-OpenProject.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-RecentProjects.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-groups-GroupsMenu.shadow_hidden"/>
+            <file name="org-openide-actions-SaveAction.shadow_hidden"/>
+            <file name="org-openide-actions-SaveAllAction.shadow_hidden"/>
+            <file name="org-openide-actions-SaveAsAction.shadow_hidden"/>
         </folder>
-        <file name="GoTo_hidden"/>
-        <folder name="View">
+        
+        <folder name="Edit">
+            <!-- Hidden menu entries from other modules -->
             <file name="Separator1.instance_hidden"/>
             <file name="Separator2.instance_hidden"/>
-            <file name="org-netbeans-core-actions-HTMLViewAction.instance_hidden"/>
-            <file name="org-netbeans-core-actions-LogAction.instance_hidden"/>
+            <file name="SeparatorAfterFindPrevious.instance_hidden"/>
+            <file name="SeparatorAfterProjectsSearch.instance_hidden"/>
+            <file name="WhereUsedAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$FindNextAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$FindPreviousAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$FindSelectionAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$PasteFormattedAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$SelectAllAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$SelectIdentifierAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$StartMacroRecordingAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$StopMacroRecordingAction.instance_hidden"/>
+            <file name="org-netbeans-modules-search-FindInFilesAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-search-ReplaceInFilesAction.shadow_hidden"/>
+            <file name="org-openide-actions-CopyAction.shadow_hidden"/>
+            <file name="org-openide-actions-CutAction.shadow_hidden"/>
+            <file name="org-openide-actions-DeleteAction.shadow_hidden"/>
+            <file name="org-openide-actions-FindAction.shadow_hidden"/>
+            <file name="org-openide-actions-PasteAction.shadow_hidden"/>
+            <file name="org-openide-actions-ReplaceAction.shadow_hidden"/>
+            <file name="sep-before-reposearch.instance_hidden"/>
+        </folder>
+        
+        <folder name="View">
+            <!-- Hidden menu entries from other modules -->
+            <file name="Separator1.instance_hidden"/>
+            <file name="Separator2.instance_hidden"/>
+            <file name="org-netbeans-core-actions-HTMLViewAction.shadow_hidden"/>
+            <file name="org-netbeans-core-actions-LogAction.shadow_hidden"/>
+            <file name="org-netbeans-core-multiview-EditorsAction.instance_hidden"/>
             <file name="org-netbeans-core-windows-actions-ToolbarsListAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-NbCodeFoldingAction.instance_hidden"/>
+            <file name="org-netbeans-modules-project-ui-SyncEditorWithViewsAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-versioning-ShowTextAnnotationsAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-versioning-diff-ShowDiffSidebarAction.shadow_hidden"/>
+            <file name="toggle-line-numbers.shadow_hidden"/>
+            <file name="toggle-non-printable-characters.shadow_hidden"/>
+            <file name="toggle-toolbar.shadow_hidden"/>
         </folder>
+        
+        <!-- Hidden menus -->
+        <folder name="GoTo_hidden"/>
+        <folder name="Source_hidden"/>
+        <folder name="Refactoring_hidden"/>
+        <folder name="BuildProject_hidden"/>
+        <folder name="RunProject_hidden"/>
+        <folder name="Versioning_hidden"/>
+        
+        <folder name="Tools">
+            <!-- Hidden menu entries from other modules -->
+            <file name="LibrariesCustomizerAction.shadow_hidden"/>
+            <file name="PaletteManager_hidden"/>
+            <file name="Separator1.instance_hidden"/>
+            <file name="Separator2.instance_hidden"/>
+            <file name="ServerManagerAction3.shadow_hidden"/>
+            <file name="VariablesCustomizerAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-autoupdate-ui-actions-PluginManagerAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-favorites-templates-TemplatesAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-options-OptionsWindowAction-separatorBefore.instance_hidden"/>
+            <file name="org-netbeans-modules-xml-catalog-CatalogAction.shadow_hidden"/>
+            <file name="org-openide-actions-ToolsAction.shadow_hidden"/>
+        </folder>
+        
         <folder name="Window">
             <file name="OutlineAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/Window/com-sun-hotspot-igv-coordinator-actions-OutlineAction.instance"/>
             </file>
+            
+            <!-- Hidden menu entries from other modules -->
+            <file name="Debug_hidden"/>
+            <file name="Navigator_hidden"/>
+            <file name="Other_hidden"/>
+            <file name="Output_hidden"/>
+            <file name="ProgressListAction.shadow_hidden"/>
+            <file name="ShowPaletteAction.shadow_hidden"/>
+            <file name="SwitchToRecentDocumentAction.shadow_hidden"/>
+            <file name="Versioning_hidden"/>
+            <file name="org-netbeans-core-ide-ServicesTabAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-favorites-View.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-logical-tab-action.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-physical-tab-action.shadow_hidden"/>
+            <file name="org-netbeans-modules-tasklist-ui-TaskListAction.shadow_hidden"/>
+            <file name="CloneDocumentAction.shadow_hidden"/>
+        </folder>
+
+        <folder name="Help">
+            <!-- Hidden menu entries from other modules -->
+            <file name="Separator1.instance_hidden"/>
+            <file name="netbeans-kb.url_hidden"/>
+            <file name="org-netbeans-modules-autoupdate-ui-actions-CheckForUpdatesAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-bugzilla-ReportNBIssueAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-usersguide-master.xml_hidden"/>
+            <file name="shortcuts.xml_hidden"/>
         </folder>
     </folder>
-    <folder name="Toolbars">
-        <file name="Standard.xml" url="StandardConfiguration.xml"/>
+
+    <folder name="OptionsDialog">
+        <!-- Hidden option tabs from other modules -->
+        <file name="Editor.instance_hidden"/>
+        <file name="FontsAndColors.instance_hidden"/>
+        <file name="General.instance_hidden"/>
+        <file name="Keymaps.instance_hidden"/>
+        <folder name="Advanced">
+            <file name="Files.instance_hidden"/>
+            <file name="IssueTracking.instance_hidden"/>
+            <file name="JavaScript.instance_hidden"/>
+            <file name="Spellchecker.instance_hidden"/>
+            <file name="TermAdvancedOption.instance_hidden"/>
+            <file name="ToDo.instance_hidden"/>
+            <file name="Versioning.instance_hidden"/>
+        </folder>
     </folder>
+    
     <folder name="Windows2">
         <folder name="Components">
             <file name="OutlineTopComponent.settings" url="OutlineTopComponentSettings.xml"/>
         </folder>
-        <folder name="Modes">
+        <folder name="Modes">  
             <file name="customLeft.wsmode" url="customLeftWsmode.xml"/>
             <folder name="customLeft">
                 <file name="OutlineTopComponent.wstcref" url="OutlineTopComponentWstcref.xml"/>
--- a/src/share/tools/IdealGraphVisualizer/Data/manifest.mf	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -1,5 +1,5 @@
-Manifest-Version: 1.0
-OpenIDE-Module: com.sun.hotspot.igv.data
-OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/data/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.0
-
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.data
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/data/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- a/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,2 +1,8 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
+src.dir=src
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+test.src.dir=test
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
--- a/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -6,6 +6,19 @@
             <code-name-base>com.sun.hotspot.igv.data</code-name-base>
             <suite-component/>
             <module-dependencies/>
+            <test-dependencies>
+                <test-type>
+                    <name>unit</name>
+                    <test-dependency>
+                        <code-name-base>org.netbeans.libs.junit4</code-name-base>
+                        <compile-dependency/>
+                    </test-dependency>
+                    <test-dependency>
+                        <code-name-base>org.openide.util</code-name-base>
+                        <compile-dependency/>
+                    </test-dependency>
+                </test-type>
+            </test-dependencies>
             <public-packages>
                 <package>com.sun.hotspot.igv.data</package>
                 <package>com.sun.hotspot.igv.data.serialization</package>
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEvent.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEvent.java	Mon Feb 27 13:10:13 2012 +0100
@@ -24,20 +24,22 @@
 package com.sun.hotspot.igv.data;
 
 /**
- *
+ * Class representing a generic changed event.
  * @author Thomas Wuerthinger
+ * @param <T>
  */
 public class ChangedEvent<T> extends Event<ChangedListener<T>> {
 
     private T object;
 
-    public ChangedEvent() {
-    }
-
+    /**
+     * Creates a new event with the specific object as the one for which the event gets fired.
+     */
     public ChangedEvent(T object) {
         this.object = object;
     }
 
+    @Override
     protected void fire(ChangedListener<T> l) {
         l.changed(object);
     }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEventProvider.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEventProvider.java	Mon Feb 27 13:10:13 2012 +0100
@@ -25,10 +25,14 @@
 package com.sun.hotspot.igv.data;
 
 /**
- *
+ * Provides a changed event object.
  * @author Thomas Wuerthinger
+ * @param <T> Class for which the changed event fires.
  */
 public interface ChangedEventProvider<T> {
 
-    public ChangedEvent<T> getChangedEvent();
+    /**
+     * Returns the changed event object. Should always return the same instance.
+     */
+    ChangedEvent<T> getChangedEvent();
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedListener.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedListener.java	Mon Feb 27 13:10:13 2012 +0100
@@ -24,10 +24,15 @@
 package com.sun.hotspot.igv.data;
 
 /**
- *
+ * Listens to changed events.
  * @author Thomas Wuerthinger
+ * @param <T> Class for which the changed event fires.
  */
 public interface ChangedListener<T> {
 
-    public void changed(T source);
+    /**
+     * This method is called everytime a changed event is fired.
+     * @param source Object that has changed.
+     */
+    void changed(T source);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ControllableChangedListener.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public abstract class ControllableChangedListener<T> implements ChangedListener<T>{
+
+	private boolean enabled;
+
+	
+	public ControllableChangedListener() {
+		enabled = true;
+	}
+
+	public boolean isEnabled() {
+		return enabled;
+	}
+
+	public void setEnabled(boolean b) {
+		enabled = b;
+	}
+
+    @Override
+	public void changed(T source) {
+		if(enabled) {
+			filteredChanged(source);
+		}
+	}
+
+	public abstract void filteredChanged(T source);
+}
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Event.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Event.java	Mon Feb 27 13:10:13 2012 +0100
@@ -33,25 +33,50 @@
 public abstract class Event<L> {
 
     private List<L> listener;
-
+    private boolean fireEvents;
+    private boolean eventWasFired;
+    
     public Event() {
-        listener = new ArrayList<L>();
+        listener = new ArrayList<>();
+        fireEvents = true;
     }
 
     public void addListener(L l) {
         listener.add(l);
     }
 
-    public void removeListener(L l) {
+    /**
+     * Remove listener
+     * @param l
+     */
+    public void removeListener(final L l) {
         listener.remove(l);
     }
 
     public void fire() {
-        List<L> tmpList = new ArrayList<L>(listener);
-        for (L l : tmpList) {
-            fire(l);
+        if(fireEvents) {
+            List<L> tmpList = new ArrayList<>(listener);
+            for (L l : tmpList) {
+                fire(l);
+            }
+        } else {
+            eventWasFired = true;
         }
     }
 
+    public void beginAtomic() {
+        assert fireEvents : "endAtomic has to be called before another beginAtomic may be called";
+        this.fireEvents = false;
+        this.eventWasFired = false;
+    }
+
+    public void endAtomic() {
+        assert !fireEvents : "beginAtomic has to be called first";
+        this.fireEvents = true;
+        if(eventWasFired) {
+            fire();
+        }
+    }
+    
     protected abstract void fire(L l);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Folder.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.sun.hotspot.igv.data;
+
+import java.util.List;
+
+public interface Folder {
+    List<? extends FolderElement> getElements();
+    void removeElement(FolderElement element);
+    void addElement(FolderElement group);
+    ChangedEvent<? extends Folder> getChangedEvent();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/FolderElement.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,31 @@
+/*
+ * 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.sun.hotspot.igv.data;
+
+public interface FolderElement {
+    
+    Folder getParent();
+    String getName();
+    void setParent(Folder parent);
+}
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java	Mon Feb 27 13:10:13 2012 +0100
@@ -24,53 +24,36 @@
 package com.sun.hotspot.igv.data;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public class GraphDocument extends Properties.Entity implements ChangedEventProvider<GraphDocument> {
+public class GraphDocument extends Properties.Entity implements ChangedEventProvider<GraphDocument>, Folder {
 
-    private List<Group> groups;
+    private List<FolderElement> elements;
     private ChangedEvent<GraphDocument> changedEvent;
 
     public GraphDocument() {
-        groups = new ArrayList<Group>();
-        changedEvent = new ChangedEvent<GraphDocument>(this);
+        elements = new ArrayList<>();
+        changedEvent = new ChangedEvent<>(this);
     }
 
     public void clear() {
-        groups.clear();
+        elements.clear();
         getChangedEvent().fire();
     }
 
+    @Override
     public ChangedEvent<GraphDocument> getChangedEvent() {
         return changedEvent;
     }
 
-    public List<Group> getGroups() {
-        return Collections.unmodifiableList(groups);
-    }
-
-    public void addGroup(Group group) {
-        group.setDocument(this);
-        groups.add(group);
-        getChangedEvent().fire();
-    }
-
-    public void removeGroup(Group group) {
-        if (groups.contains(group)) {
-            group.setDocument(null);
-            groups.remove(group);
-            getChangedEvent().fire();
-        }
-    }
-
     public void addGraphDocument(GraphDocument document) {
-        for (Group g : document.groups) {
-            this.addGroup(g);
+        for (FolderElement e : document.elements) {
+            e.setParent(this);
+            this.addElement(e);
         }
         document.clear();
         getChangedEvent().fire();
@@ -80,12 +63,30 @@
     public String toString() {
         StringBuilder sb = new StringBuilder();
 
-        sb.append("GraphDocument: " + getProperties().toString() + " \n\n");
-        for (Group g : getGroups()) {
+        sb.append("GraphDocument: ").append(getProperties().toString()).append(" \n\n");
+        for (FolderElement g : getElements()) {
             sb.append(g.toString());
             sb.append("\n\n");
         }
 
         return sb.toString();
     }
+
+    @Override
+    public List<? extends FolderElement> getElements() {
+        return elements;
+    }
+
+    @Override
+    public void removeElement(FolderElement element) {
+        if (elements.remove(element)) {
+            getChangedEvent().fire();
+        }
+    }
+
+    @Override
+    public void addElement(FolderElement element) {
+        elements.add(element);
+        getChangedEvent().fire();
+    }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Group.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Group.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,49 +23,36 @@
  */
 package com.sun.hotspot.igv.data;
 
-import com.sun.hotspot.igv.data.ChangedEvent;
-import com.sun.hotspot.igv.data.ChangedEventProvider;
-import com.sun.hotspot.igv.data.Properties;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public class Group extends Properties.Entity implements ChangedEventProvider<Group> {
+public class Group extends Properties.Entity implements ChangedEventProvider<Group>, Folder, FolderElement {
 
-    private List<InputGraph> graphs;
+    private final List<FolderElement> elements;
+    private final List<InputGraph> graphs;
+
+    private InputMethod method;
     private transient ChangedEvent<Group> changedEvent;
-    private GraphDocument document;
-    private InputMethod method;
-    private String assembly;
+    private Folder parent;
 
-    public Group() {
-        graphs = new ArrayList<InputGraph>();
-        init();
-    }
+    public Group(Folder parent) {
+        elements = new ArrayList<>();
+        graphs = new ArrayList<>();
+        changedEvent = new ChangedEvent<>(this);
+        this.parent = parent;
 
-    private void init() {
-        changedEvent = new ChangedEvent<Group>(this);
+        // Ensure that name and type are never null
+        getProperties().setProperty("name", "");
+        getProperties().setProperty("type", "");
     }
 
     public void fireChangedEvent() {
         changedEvent.fire();
     }
 
-    public void setAssembly(String s) {
-        this.assembly = s;
-    }
-
-    public String getAssembly() {
-        return assembly;
-    }
-
     public void setMethod(InputMethod method) {
         this.method = method;
     }
@@ -74,68 +61,120 @@
         return method;
     }
 
-    void setDocument(GraphDocument document) {
-        this.document = document;
-    }
-
-    public GraphDocument getDocument() {
-        return document;
-    }
-
+    @Override
     public ChangedEvent<Group> getChangedEvent() {
         return changedEvent;
     }
 
-    public List<InputGraph> getGraphs() {
-        return Collections.unmodifiableList(graphs);
+    @Override
+    public List<FolderElement> getElements() {
+        return Collections.unmodifiableList(elements);
     }
 
-    public void addGraph(InputGraph g) {
-        assert g != null;
-        assert !graphs.contains(g);
-        graphs.add(g);
+    public int getGraphsCount() {
+        return elements.size();
+    }
+    
+    @Override
+    public void addElement(FolderElement element) {
+        elements.add(element);
+        if (element instanceof InputGraph) {
+            graphs.add((InputGraph) element);
+        } else {
+            
+        }
+        element.setParent(this);
         changedEvent.fire();
     }
 
-    public void removeGraph(InputGraph g) {
-        int index = graphs.indexOf(g);
-        if (index != -1) {
-            graphs.remove(g);
-            changedEvent.fire();
-        }
-    }
-
     public Set<Integer> getAllNodes() {
-        Set<Integer> result = new HashSet<Integer>();
-        for (InputGraph g : graphs) {
-            Set<Integer> ids = g.getNodesAsSet();
-            result.addAll(g.getNodesAsSet());
-            for (Integer i : ids) {
-                result.add(-i);
+        Set<Integer> result = new HashSet<>();
+        for (FolderElement e : elements) {
+            if (e instanceof InputGraph) {
+                InputGraph g = (InputGraph) e;
+                result.addAll(g.getNodesAsSet());
             }
         }
         return result;
     }
 
-    public InputGraph getLastAdded() {
-        if (graphs.size() == 0) {
-            return null;
-        }
-        return graphs.get(graphs.size() - 1);
-    }
-
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
-        sb.append("Group " + getProperties().toString() + "\n");
-        for (InputGraph g : graphs) {
+        sb.append("Group ").append(getProperties()).append("\n");
+        for (FolderElement g : elements) {
             sb.append(g.toString());
-            sb.append("\n");
+            sb.append('\n');
         }
         return sb.toString();
     }
 
+    @Override
     public String getName() {
         return getProperties().get("name");
     }
+
+    public String getType() {
+        return getProperties().get("type");
+        
+    }
+
+    InputGraph getPrev(InputGraph graph) {
+        InputGraph lastGraph = null;
+        for (FolderElement e : elements) {
+            if (e == graph) {
+                return lastGraph;
+            }
+            if (e instanceof InputGraph) {
+                lastGraph = (InputGraph) e;
+            }
+        }
+        return null;
+    }
+
+    InputGraph getNext(InputGraph graph) {
+        boolean found = false;
+        for (FolderElement e : elements) {
+            if (e == graph) {
+                found = true;
+            } else if (found && e instanceof InputGraph) {
+                return (InputGraph) e;
+            }
+        }
+        return null;
+    }
+
+    public InputGraph getLastGraph() {
+        InputGraph lastGraph = null;
+        for (FolderElement e : elements) {
+            if (e instanceof InputGraph) {
+                lastGraph = (InputGraph) e;
+            }
+        }
+        return lastGraph;
+    }
+
+    @Override
+    public Folder getParent() {
+         return parent;
+    }
+
+    @Override
+    public void removeElement(FolderElement element) {
+        if (elements.remove(element)) {
+            if (element instanceof InputGraph) {
+                graphs.remove((InputGraph) element);
+            }
+            changedEvent.fire();
+        }
+    }
+
+    public List<InputGraph> getGraphs() {
+        return graphs;
+    }
+
+    @Override
+    public void setParent(Folder parent) {
+        this.parent = parent;
+    }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlock.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlock.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,12 +23,7 @@
  */
 package com.sun.hotspot.igv.data;
 
-import java.awt.Rectangle;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 /**
  *
@@ -37,46 +32,57 @@
 public class InputBlock {
 
     private List<InputNode> nodes;
-    private List<String> successorNames;
     private String name;
     private InputGraph graph;
-    private Rectangle bounds;
     private Set<InputBlock> successors;
-    private Set<InputBlock> predecessors;
-    private Set<InputBlockEdge> inputs;
-    private Set<InputBlockEdge> outputs;
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+
+        if (o == this) {
+            return true;
+        }
 
-    public InputBlock(InputGraph graph, String name) {
+        if (o == null || (!(o instanceof InputBlock))) {
+            return false;
+        }
+        
+        final InputBlock b = (InputBlock)o;
+        final boolean result = b.nodes.equals(nodes) && b.name.equals(name) && b.successors.size() == successors.size();
+        if (!result) {
+            return false;
+        }
+
+        final HashSet<String> s = new HashSet<>();
+        for (InputBlock succ : successors) {
+            s.add(succ.name);
+        }
+
+        for (InputBlock succ : b.successors) {
+            if (!s.contains(succ.name)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    InputBlock(InputGraph graph, String name) {
         this.graph = graph;
         this.name = name;
-        nodes = new ArrayList<InputNode>();
-        successorNames = new ArrayList<String>();
-        successors = new HashSet<InputBlock>();
-        predecessors = new HashSet<InputBlock>();
-        inputs = new HashSet<InputBlockEdge>();
-        outputs = new HashSet<InputBlockEdge>();
-    }
-
-    public void removeSuccessor(InputBlock b) {
-        if (successors.contains(b)) {
-            successors.remove(b);
-            b.predecessors.remove(this);
-            InputBlockEdge e = new InputBlockEdge(this, b);
-            assert outputs.contains(e);
-            outputs.remove(e);
-            assert b.inputs.contains(e);
-            b.inputs.remove(e);
-        }
+        nodes = new ArrayList<>();
+        successors = new LinkedHashSet<>(2);
     }
 
     public String getName() {
         return name;
     }
 
-    public void setName(String s) {
-        name = s;
-    }
-
     public List<InputNode> getNodes() {
         return Collections.unmodifiableList(nodes);
     }
@@ -85,56 +91,24 @@
         InputNode n = graph.getNode(id);
         assert n != null;
         graph.setBlock(n, this);
-        addNode(graph.getNode(id));
-    }
-
-    public void addNode(InputNode node) {
-        assert !nodes.contains(node);
+        final InputNode node = graph.getNode(id);
+        assert node != null;
+        assert !nodes.contains(node) : "duplicate : " + node;
         nodes.add(node);
     }
 
-    public Set<InputBlock> getPredecessors() {
-        return Collections.unmodifiableSet(predecessors);
-    }
-
     public Set<InputBlock> getSuccessors() {
         return Collections.unmodifiableSet(successors);
     }
 
-    public Set<InputBlockEdge> getInputs() {
-        return Collections.unmodifiableSet(inputs);
-    }
-
-    public Set<InputBlockEdge> getOutputs() {
-        return Collections.unmodifiableSet(outputs);
-    }
-
-    // resolveBlockLinks must be called afterwards
-    public void addSuccessor(String name) {
-        successorNames.add(name);
+    @Override
+    public String toString() {
+        return "Block " + this.getName();
     }
 
-    public void resolveBlockLinks() {
-        for (String s : successorNames) {
-            InputBlock b = graph.getBlock(s);
-            addSuccessor(b);
-        }
-
-        successorNames.clear();
-    }
-
-    public void addSuccessor(InputBlock b) {
+    void addSuccessor(InputBlock b) {
         if (!successors.contains(b)) {
             successors.add(b);
-            b.predecessors.add(this);
-            InputBlockEdge e = new InputBlockEdge(this, b);
-            outputs.add(e);
-            b.inputs.add(e);
         }
     }
-
-    @Override
-    public String toString() {
-        return this.getName();
-    }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlockEdge.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlockEdge.java	Mon Feb 27 13:10:13 2012 +0100
@@ -29,8 +29,15 @@
  */
 public class InputBlockEdge {
 
+    public enum State {
+        SAME,
+        NEW,
+        DELETED
+    }
+
     private InputBlock from;
     private InputBlock to;
+    private State state = State.SAME;
 
     public InputBlockEdge(InputBlock from, InputBlock to) {
         assert from != null;
@@ -47,13 +54,21 @@
         return to;
     }
 
+    public State getState() {
+        return state;
+    }
+
+    public void setState(State state) {
+        this.state = state;
+    }
+
     @Override
     public boolean equals(Object obj) {
-        if (obj instanceof InputBlockEdge && obj != null) {
+        if (obj != null && obj instanceof InputBlockEdge) {
             InputBlockEdge e = (InputBlockEdge) obj;
             return e.from.equals(from) && e.to.equals(to);
         }
-        return super.equals(obj);
+        return false;
     }
 
     @Override
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,6 +23,8 @@
  */
 package com.sun.hotspot.igv.data;
 
+import java.util.Comparator;
+
 /**
  *
  * @author Thomas Wuerthinger
@@ -35,16 +37,52 @@
         NEW,
         DELETED
     }
+    
+    public static final Comparator<InputEdge> OUTGOING_COMPARATOR = new Comparator<InputEdge>(){
+
+        @Override
+            public int compare(InputEdge o1, InputEdge o2) {
+                if(o1.getFromIndex() == o2.getFromIndex()) {
+                    return o1.getTo() - o2.getTo();
+                }
+                return o1.getFromIndex() - o2.getFromIndex();
+            }
+    };
+    
+    
+    public static final Comparator<InputEdge> INGOING_COMPARATOR = new Comparator<InputEdge>(){
+
+        @Override
+            public int compare(InputEdge o1, InputEdge o2) {
+                if(o1.getToIndex() == o2.getToIndex()) {
+                    return o1.getFrom() - o2.getFrom();
+                }
+                return o1.getToIndex() - o2.getToIndex();
+            }
+    };
+
     private char toIndex;
+    private char fromIndex;
     private int from;
     private int to;
     private State state;
+    private String label;
 
     public InputEdge(char toIndex, int from, int to) {
+        this((char) 0, toIndex, from, to, null);
+    }
+
+    public InputEdge(char fromIndex, char toIndex, int from, int to) {
+        this(fromIndex, toIndex, from, to, null);
+    }
+
+    public InputEdge(char fromIndex, char toIndex, int from, int to, String label) {
         this.toIndex = toIndex;
+        this.fromIndex = fromIndex;
         this.from = from;
         this.to = to;
         this.state = State.SAME;
+        this.label = label;
     }
 
     public State getState() {
@@ -58,6 +96,10 @@
     public char getToIndex() {
         return toIndex;
     }
+    
+    public char getFromIndex() {
+        return fromIndex;
+    }
 
     public String getName() {
         return "in" + toIndex;
@@ -71,22 +113,26 @@
         return to;
     }
 
+    public String getLabel() {
+        return label;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (o == null || !(o instanceof InputEdge)) {
             return false;
         }
         InputEdge conn2 = (InputEdge) o;
-        return conn2.toIndex == toIndex && conn2.from == from && conn2.to == to;
+        return conn2.fromIndex == fromIndex && conn2.toIndex == toIndex && conn2.from == from && conn2.to == to;
     }
 
     @Override
     public String toString() {
-        return "Edge from " + from + " to " + to + "(" + (int) toIndex + ") ";
+        return "Edge from " + from + " to " + to + "(" + (int) fromIndex + ", " + (int) toIndex + ") ";
     }
 
     @Override
     public int hashCode() {
-        return (from << 20 | to << 8 | toIndex);
+        return (from << 20 | to << 8 | toIndex << 4 | fromIndex);
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,65 +23,143 @@
  */
 package com.sun.hotspot.igv.data;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public class InputGraph extends Properties.Entity {
+public class InputGraph extends Properties.Entity implements FolderElement {
+
+    private Map<Integer, InputNode> nodes;
+    private Set<InputEdge> edges;
+    private Folder parent;
+    private Group parentGroup;
+    private Map<String, InputBlock> blocks;
+    private Set<InputBlockEdge> blockEdges;
+    private Map<Integer, InputBlock> nodeToBlock;
 
-    private HashMap<Integer, InputNode> nodes;
-    private ArrayList<InputEdge> edges;
-    private Group parent;
-    private HashMap<String, InputBlock> blocks;
-    private HashMap<Integer, InputBlock> nodeToBlock;
-    private boolean isDifferenceGraph;
-
-    public InputGraph(Group parent) {
-        this(parent, null);
+    public InputGraph(String name) {
+        setName(name);
+        nodes = new LinkedHashMap<>();
+        edges = new LinkedHashSet<>();
+        blocks = new LinkedHashMap<>();
+        blockEdges = new LinkedHashSet<>();
+        nodeToBlock = new LinkedHashMap<>();
+    }
+    
+    @Override
+    public void setParent(Folder parent) {
+        this.parent = parent;
+        if (parent instanceof Group) {
+            assert this.parentGroup == null;
+            this.parentGroup = (Group) parent;
+        }
     }
 
-    public InputGraph(Group parent, InputGraph last) {
-        this(parent, last, "");
+    public InputBlockEdge addBlockEdge(InputBlock left, InputBlock right) {
+        InputBlockEdge edge = new InputBlockEdge(left, right);
+        blockEdges.add(edge);
+        left.addSuccessor(right);
+        return edge;
+    }
+    
+    public List<InputNode> findRootNodes() {
+        List<InputNode> result = new ArrayList<>();
+        Set<Integer> nonRoot = new HashSet<>();
+        for(InputEdge curEdges : getEdges()) {
+            nonRoot.add(curEdges.getTo());
+        }
+        
+        for(InputNode node : getNodes()) {
+            if(!nonRoot.contains(node.getId())) {
+                result.add(node);
+            }
+        }
+        
+        return result;
+    }
+    
+    public Map<InputNode, List<InputEdge>> findAllOutgoingEdges() {
+        
+        Map<InputNode, List<InputEdge>> result = new HashMap<>(getNodes().size());
+        for(InputNode n : this.getNodes()) {
+            result.put(n, new ArrayList<InputEdge>());
+        }
+        
+        for(InputEdge e : this.edges) {
+            int from = e.getFrom();
+            InputNode fromNode = this.getNode(from);
+            List<InputEdge> fromList = result.get(fromNode);
+            assert fromList != null;
+            fromList.add(e);
+        }
+        
+        for(InputNode n : this.getNodes()) {
+            List<InputEdge> list = result.get(n);
+            Collections.sort(list, InputEdge.OUTGOING_COMPARATOR);
+        }
+        
+        return result;
+    }
+    
+    public Map<InputNode, List<InputEdge>> findAllIngoingEdges() {
+        
+        Map<InputNode, List<InputEdge>> result = new HashMap<>(getNodes().size());
+        for(InputNode n : this.getNodes()) {
+            result.put(n, new ArrayList<InputEdge>());
+        }
+        
+        for(InputEdge e : this.edges) {
+            int to = e.getTo();
+            InputNode toNode = this.getNode(to);
+            List<InputEdge> toList = result.get(toNode);
+            assert toList != null;
+            toList.add(e);
+        }
+        
+        for(InputNode n : this.getNodes()) {
+            List<InputEdge> list = result.get(n);
+            Collections.sort(list, InputEdge.INGOING_COMPARATOR);
+        }
+        
+        return result;
+    }
+    
+    public List<InputEdge> findOutgoingEdges(InputNode n) {
+        List<InputEdge> result = new ArrayList<>();
+        
+        for(InputEdge e : this.edges) {
+            if(e.getFrom() == n.getId()) {
+                result.add(e);
+            }
+        }
+        
+        Collections.sort(result, InputEdge.OUTGOING_COMPARATOR);
+        
+        return result;
     }
 
-    private void clearBlocks() {
+    public void clearBlocks() {
         blocks.clear();
         nodeToBlock.clear();
     }
-
-    public InputGraph(Group parent, InputGraph last, String name) {
-        this.parent = parent;
-        setName(name);
-        nodes = new HashMap<Integer, InputNode>();
-        edges = new ArrayList<InputEdge>();
-        blocks = new HashMap<String, InputBlock>();
-        nodeToBlock = new HashMap<Integer, InputBlock>();
-        if (last != null) {
-
-            for (InputNode n : last.getNodes()) {
-                addNode(n);
-            }
-
-            for (InputEdge c : last.getEdges()) {
-                addEdge(c);
-            }
+    
+    public void setEdge(int fromIndex, int toIndex, int from, int to) {
+        assert fromIndex == ((char)fromIndex) : "Downcast must be safe";
+        assert toIndex == ((char)toIndex) : "Downcast must be safe";
+        
+        InputEdge edge = new InputEdge((char)fromIndex, (char)toIndex, from, to);
+        if(!this.getEdges().contains(edge)) {
+            this.addEdge(edge);
         }
     }
 
-    public void schedule(Collection<InputBlock> newBlocks) {
-        clearBlocks();
-        InputBlock noBlock = new InputBlock(this, "no block");
-        Set<InputNode> scheduledNodes = new HashSet<InputNode>();
+    public void ensureNodesInBlocks() {
+        InputBlock noBlock = null;
+        Set<InputNode> scheduledNodes = new HashSet<>();
 
-        for (InputBlock b : newBlocks) {
+        for (InputBlock b : getBlocks()) {
             for (InputNode n : b.getNodes()) {
                 assert !scheduledNodes.contains(n);
                 scheduledNodes.add(n);
@@ -91,18 +169,11 @@
         for (InputNode n : this.getNodes()) {
             assert nodes.get(n.getId()) == n;
             if (!scheduledNodes.contains(n)) {
+                if (noBlock == null) {
+                    noBlock = this.addBlock("(no block)");
+                }
                 noBlock.addNode(n.getId());
             }
-        }
-
-        if (noBlock.getNodes().size() != 0) {
-            newBlocks.add(noBlock);
-        }
-        for (InputBlock b : newBlocks) {
-            addBlock(b);
-        }
-
-        for (InputNode n : this.getNodes()) {
             assert this.getBlock(n) != null;
         }
     }
@@ -116,45 +187,26 @@
     }
 
     public InputBlock getBlock(InputNode node) {
+        assert nodes.containsKey(node.getId());
+        assert nodes.get(node.getId()).equals(node);
         return getBlock(node.getId());
     }
 
     public InputGraph getNext() {
-        List<InputGraph> list = parent.getGraphs();
-        if (!list.contains(this)) {
-            return null;
-        }
-        int index = list.indexOf(this);
-        if (index == list.size() - 1) {
-            return null;
-        } else {
-            return list.get(index + 1);
-        }
+        return parentGroup.getNext(this);
     }
 
     public InputGraph getPrev() {
-        List<InputGraph> list = parent.getGraphs();
-        if (!list.contains(this)) {
-            return null;
-        }
-        int index = list.indexOf(this);
-        if (index == 0) {
-            return null;
-        } else {
-            return list.get(index - 1);
-        }
+        return parentGroup.getPrev(this);
     }
 
-    public String getName() {
-        return getProperties().get("name");
+    private void setName(String name) {
+        this.getProperties().setProperty("name", name);
     }
 
-    public String getAbsoluteName() {
-        String result = getName();
-        if (this.parent != null) {
-            result = parent.getName() + ": " + result;
-        }
-        return result;
+    @Override
+    public String getName() {
+        return getProperties().get("name");
     }
 
     public Collection<InputNode> getNodes() {
@@ -182,29 +234,29 @@
     }
 
     public Collection<InputEdge> getEdges() {
-        return Collections.unmodifiableList(edges);
+        return Collections.unmodifiableSet(edges);
     }
 
     public void removeEdge(InputEdge c) {
-        assert edges.contains(c);
-        edges.remove(c);
-        assert !edges.contains(c);
+        boolean removed = edges.remove(c);
+        assert removed;
     }
 
     public void addEdge(InputEdge c) {
-        assert !edges.contains(c);
-        edges.add(c);
-        assert edges.contains(c);
+        // Be tolerant with duplicated edges.
+        if (!edges.contains(c)) {
+            edges.add(c);
+        }
     }
 
     public Group getGroup() {
-        return parent;
+        return parentGroup;
     }
 
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
-        sb.append("Graph " + getName() + " " + getProperties().toString() + "\n");
+        sb.append("Graph ").append(getName()).append(" ").append(getProperties().toString()).append("\n");
         for (InputNode n : nodes.values()) {
             sb.append(n.toString());
             sb.append("\n");
@@ -214,35 +266,31 @@
             sb.append(c.toString());
             sb.append("\n");
         }
+
+        for (InputBlock b : getBlocks()) {
+            sb.append(b.toString());
+            sb.append("\n");
+        }
+
         return sb.toString();
     }
 
-    public void addBlock(InputBlock b) {
+    public InputBlock addBlock(String name) {
+        final InputBlock b = new InputBlock(this, name);
         blocks.put(b.getName(), b);
-        for (InputNode n : b.getNodes()) {
-            this.nodeToBlock.put(n.getId(), b);
-        }
-    }
-
-    public void resolveBlockLinks() {
-        for (InputBlock b : blocks.values()) {
-            b.resolveBlockLinks();
-        }
-    }
-
-    public void setName(String s) {
-        getProperties().setProperty("name", s);
+        return b;
     }
 
     public InputBlock getBlock(String s) {
         return blocks.get(s);
     }
 
-    public boolean isDifferenceGraph() {
-        return this.isDifferenceGraph;
+    public Collection<InputBlockEdge> getBlockEdges() {
+        return Collections.unmodifiableSet(blockEdges);
     }
 
-    public void setIsDifferenceGraph(boolean b) {
-        isDifferenceGraph = b;
+    @Override
+    public Folder getParent() {
+        return parent;
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,7 +23,6 @@
  */
 package com.sun.hotspot.igv.data;
 
-import com.sun.hotspot.igv.data.Properties;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -42,14 +41,37 @@
     private Group group;
     private List<InputBytecode> bytecodes;
 
+    @Override
+    public int hashCode() {
+        int result = name.hashCode();
+        result = result * 31 + bci;
+        result = result * 31 + shortName.hashCode();
+        result = result * 31 + inlined.hashCode();
+        result = result * 31 + bytecodes.hashCode();
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == null || (!(o instanceof InputMethod))) {
+            return false;
+        }
+
+        final InputMethod im = (InputMethod)o;
+        return name.equals(im.name) && bci == im.bci && shortName.equals(im.shortName) &&
+               inlined.equals(im.inlined) && bytecodes.equals(im.bytecodes);
+    }
+
+
+
     /** Creates a new instance of InputMethod */
     public InputMethod(Group parent, String name, String shortName, int bci) {
         this.group = parent;
         this.name = name;
         this.bci = bci;
         this.shortName = shortName;
-        inlined = new ArrayList<InputMethod>();
-        bytecodes = new ArrayList<InputBytecode>();
+        inlined = new ArrayList<>();
+        bytecodes = new ArrayList<>();
     }
 
     public List<InputBytecode> getBytecodes() {
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputNode.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,6 +23,8 @@
  */
 package com.sun.hotspot.igv.data;
 
+import java.util.Comparator;
+
 /**
  *
  * @author Thomas Wuerthinger
@@ -31,6 +33,36 @@
 
     private int id;
 
+    public static final Comparator<InputNode> COMPARATOR = new Comparator<InputNode>() {
+        @Override
+        public int compare(InputNode o1, InputNode o2) {
+            return o1.getId() - o2.getId();
+        }
+    };
+
+    public static Comparator<InputNode> getPropertyComparator(final String propertyName) {
+        return new Comparator<InputNode>() {
+
+            @Override
+            public int compare(InputNode o1, InputNode o2) {
+
+                int i1 = 0;
+                try {
+                    i1 = Integer.parseInt(o1.getProperties().get(propertyName));
+                } catch(NumberFormatException e) {
+                }
+
+                int i2 = 0;
+                try {
+                    i2 = Integer.parseInt(o2.getProperties().get(propertyName));
+                } catch(NumberFormatException e) {
+                }
+
+                return i1 - i2;
+            }
+        };
+    }
+
     public InputNode(InputNode n) {
         super(n);
         setId(n.id);
@@ -55,15 +87,12 @@
             return false;
         }
         InputNode n = (InputNode) o;
-        if (n.id != id) {
-            return false;
-        }
-        return getProperties().equals(n.getProperties());
+        return n.id == id;
     }
 
     @Override
     public int hashCode() {
-        return id;
+        return id * 13;
     }
 
     @Override
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Pair.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Pair.java	Mon Feb 27 13:10:13 2012 +0100
@@ -58,15 +58,30 @@
 
     @Override
     public boolean equals(Object o) {
-        if (!(o instanceof Pair)) {
+        if (o == null || !(o instanceof Pair)) {
             return false;
         }
-        Pair obj = (Pair) o;
-        return l.equals(obj.l) && r.equals(obj.r);
+        Pair<?,?> obj = (Pair<?,?>) o;
+        boolean b1 = (l == obj.l);
+        if (l != null) {
+            b1 = l.equals(obj.l);
+        }
+
+        boolean b2 = (r == obj.r);
+        if (r != null) {
+            b2 = r.equals(obj.r);
+        }
+        
+        return b1 && b2;
     }
 
     @Override
     public int hashCode() {
-        return l.hashCode() * 71 + r.hashCode();
+        return ((l == null) ? 0 : l.hashCode()) * 71 + ((r == null) ? 0 : r.hashCode());
+    }
+
+    @Override
+    public String toString() {
+        return "[" + l + "/" + r + "]";
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java	Mon Feb 27 13:10:13 2012 +0100
@@ -24,13 +24,10 @@
 package com.sun.hotspot.igv.data;
 
 import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-
+import java.util.regex.PatternSyntaxException;
 
 /**
  *
@@ -58,13 +55,30 @@
                 return false;
             }
         }
+
+        for (Property prop : p) {
+            String value = this.get(prop.getName());
+            if (value == null || !value.equals(prop.getValue())) {
+                return false;
+            }
+        }
+
         return true;
     }
 
     @Override
     public int hashCode() {
         int hash = 5;
-        hash = 83 * hash + (this.map != null ? this.map.hashCode() : 0);
+
+        if (map != null) {
+            for (int i = 0; i < this.map.length; i++) {
+                if (map[i] == null) {
+                    i++;
+                } else {
+                    hash = hash * 83 + map[i].hashCode();
+                }
+            }
+        }
         return hash;
     }
 
@@ -85,7 +99,7 @@
 
     public Properties(Properties p) {
         map = new String[p.map.length];
-        System.arraycopy(map, 0, p.map, 0, p.map.length);
+        System.arraycopy(p.map, 0, map, 0, p.map.length);
     }
 
     public static class Entity implements Provider {
@@ -100,19 +114,12 @@
             properties = new Properties(object.getProperties());
         }
 
+        @Override
         public Properties getProperties() {
             return properties;
         }
     }
 
-    private String getProperty(String key) {
-        for (int i = 0; i < map.length; i += 2)
-            if (map[i] != null && map[i].equals(key)) {
-                return map[i + 1];
-            }
-        return null;
-    }
-
     public interface PropertyMatcher {
 
         String getName();
@@ -128,11 +135,16 @@
             this.matcher = matcher;
         }
 
+        @Override
         public String getName() {
             return matcher.getName();
         }
 
+        @Override
         public boolean match(String p) {
+            if (p == null) {
+                return false;
+            }
             return !matcher.match(p);
         }
     }
@@ -143,15 +155,26 @@
         private String value;
 
         public StringPropertyMatcher(String name, String value) {
+            if (name == null) {
+                throw new IllegalArgumentException("Property name must not be null!");
+            }
+            if (value == null) {
+                throw new IllegalArgumentException("Property value must not be null!");
+            }
             this.name = name;
             this.value = value;
         }
 
+        @Override
         public String getName() {
             return name;
         }
 
+        @Override
         public boolean match(String p) {
+            if (p == null) {
+                throw new IllegalArgumentException("Property value must not be null!");
+            }
             return p.equals(value);
         }
     }
@@ -160,32 +183,57 @@
 
         private String name;
         private Pattern valuePattern;
-
+        
         public RegexpPropertyMatcher(String name, String value) {
-            this.name = name;
-            valuePattern = Pattern.compile(value);
+            this(name, value, 0);
         }
 
+        public RegexpPropertyMatcher(String name, String value, int flags) {
+
+            if (name == null) {
+                throw new IllegalArgumentException("Property name must not be null!");
+            }
+
+            if (value == null) {
+                throw new IllegalArgumentException("Property value pattern must not be null!");
+            }
+
+            this.name = name;
+
+            try {
+                valuePattern = Pattern.compile(value, flags);
+            } catch (PatternSyntaxException e) {
+                throw new IllegalArgumentException("Bad pattern: " + value);
+            }
+        }
+
+        @Override
         public String getName() {
             return name;
         }
 
+        @Override
         public boolean match(String p) {
+            if (p == null) {
+                throw new IllegalArgumentException("Property value must not be null!");
+            }
             Matcher m = valuePattern.matcher(p);
             return m.matches();
         }
     }
 
     public Property selectSingle(PropertyMatcher matcher) {
+
+        final String name = matcher.getName();
         String value = null;
         for (int i = 0; i < map.length; i += 2) {
-            if (map[i] != null && matcher.getName().equals(map[i]))  {
+            if (map[i] != null && name.equals(map[i])) {
                 value = map[i + 1];
                 break;
             }
         }
         if (value != null && matcher.match(value)) {
-            return new Property(matcher.getName(), value);
+            return new Property(name, value);
         } else {
             return null;
         }
@@ -198,13 +246,32 @@
 
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("[");
+        List<String[]> pairs = new ArrayList<>();
         for (int i = 0; i < map.length; i += 2) {
             if (map[i + 1] != null) {
-                String p = map[i + 1];
-                sb.append(map[i] + " = " + map[i + 1] + "; ");
+                pairs.add(new String[]{map[i], map[i + 1]});
+            }
+        }
+
+        Collections.sort(pairs, new Comparator<String[]>() {
+            @Override
+            public int compare(String[] o1, String[] o2) {
+                assert o1.length == 2;
+                assert o2.length == 2;
+                return o1[0].compareTo(o2[0]);
             }
+        });
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("[");
+        boolean first = true;
+        for (String[] p : pairs) {
+            if (first) {
+                first = false;
+            } else {
+                sb.append(", ");
+            }
+            sb.append(p[0] + "=" + p[1]);
         }
         return sb.append("]").toString();
     }
@@ -217,10 +284,6 @@
             this.objects = objects;
         }
 
-        public T selectSingle(final String name, final String value) {
-            return selectSingle(new StringPropertyMatcher(name, value));
-        }
-
         public T selectSingle(PropertyMatcher matcher) {
 
             for (T t : objects) {
@@ -233,18 +296,16 @@
             return null;
         }
 
-        public List<T> selectMultiple(final String name, final String value) {
-            return selectMultiple(new StringPropertyMatcher(name, value));
-        }
+        public List<T> selectMultiple(PropertyMatcher matcher) {
+            List<T> result = new ArrayList<>();
 
-        public List<T> selectMultiple(PropertyMatcher matcher) {
-            List<T> result = new ArrayList<T>();
             for (T t : objects) {
                 Property p = t.getProperties().selectSingle(matcher);
                 if (p != null) {
                     result.add(t);
                 }
             }
+
             return result;
         }
     }
@@ -259,6 +320,7 @@
     }
 
     public void setProperty(String name, String value) {
+
         for (int i = 0; i < map.length; i += 2) {
             if (map[i] != null && map[i].equals(name)) {
                 String p = map[i + 1];
@@ -289,34 +351,25 @@
         map = newMap;
     }
 
-    public  Iterator<Property> getProperties() {
-        return iterator();
-    }
-
     public void add(Properties properties) {
         for (Property p : properties) {
-            add(p);
+            setProperty(p.getName(), p.getValue());
         }
     }
 
-    public void add(Property property) {
-        assert property.getName() != null;
-        assert property.getValue() != null;
-        setProperty(property.getName(), property.getValue());
-    }
-    class PropertiesIterator implements Iterator<Property>, Iterable<Property> {
-        public Iterator<Property> iterator() {
-                return this;
-        }
+    private class PropertiesIterator implements Iterator<Property> {
 
         int index;
 
+        @Override
         public boolean hasNext() {
-            while (index < map.length && map[index + 1] == null)
+            while (index < map.length && map[index + 1] == null) {
                 index += 2;
+            }
             return index < map.length;
         }
 
+        @Override
         public Property next() {
             if (index < map.length) {
                 index += 2;
@@ -325,11 +378,13 @@
             return null;
         }
 
+        @Override
         public void remove() {
             throw new UnsupportedOperationException("Not supported yet.");
         }
+    }
 
-    }
+    @Override
     public Iterator<Property> iterator() {
         return new PropertiesIterator();
     }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Property.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Property.java	Mon Feb 27 13:10:13 2012 +0100
@@ -32,25 +32,20 @@
 public class Property implements Serializable {
 
     public static final long serialVersionUID = 1L;
-
     private String name;
     private String value;
 
-    private Property() {
-        this(null, null);
-    }
-
-    private Property(Property p) {
-        this(p.getName(), p.getValue());
-    }
-
-    private Property(String name) {
-        this(name, null);
-    }
-
-    public Property(String name, String value) {
+    Property(String name, String value) {
         this.name = name;
         this.value = value;
+
+        if (value == null) {
+            throw new IllegalArgumentException("Property value must not be null!");
+        }
+
+        if (name == null) {
+            throw new IllegalArgumentException("Property name must not be null!");
+        }
     }
 
     public String getName() {
@@ -63,17 +58,20 @@
 
     @Override
     public String toString() {
-        return name + " = " + value + "; ";
+        return name + "=" + value;
     }
 
     @Override
     public boolean equals(Object o) {
-        if (!(o instanceof Property)) return false;
-        Property p2 = (Property)o;
+        if (!(o instanceof Property)) {
+            return false;
+        }
+        Property p2 = (Property) o;
         return name.equals(p2.name) && value.equals(p2.value);
     }
+
     @Override
     public int hashCode() {
-        return name.hashCode() + value == null ? 0 : value.hashCode();
+        return name.hashCode() * 13 + value.hashCode();
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Source.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import java.util.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Source {
+
+    private List<InputNode> sourceNodes;
+    private Set<Integer> set;
+
+    public Source() {
+        sourceNodes = new ArrayList<>(1);
+        set = new LinkedHashSet<>(1);
+    }
+
+    public List<InputNode> getSourceNodes() {
+        return Collections.unmodifiableList(sourceNodes);
+    }
+
+    public Set<Integer> getSourceNodesAsSet() {
+        return Collections.unmodifiableSet(set);
+    }
+
+    public void addSourceNode(InputNode n) {
+        if (!set.contains(n.getId())) {
+            sourceNodes.add(n);
+            set.add(n.getId());
+        }
+    }
+
+    public interface Provider {
+
+        public Source getSource();
+    }
+
+    public void addSourceNodes(Source s) {
+        for (InputNode n : s.getSourceNodes()) {
+            addSourceNode(n);
+        }
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Parser.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Parser.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,22 +23,23 @@
  */
 package com.sun.hotspot.igv.data.serialization;
 
-import com.sun.hotspot.igv.data.GraphDocument;
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.InputBlock;
-import com.sun.hotspot.igv.data.InputEdge;
-import com.sun.hotspot.igv.data.InputGraph;
-import com.sun.hotspot.igv.data.InputMethod;
-import com.sun.hotspot.igv.data.InputNode;
-import com.sun.hotspot.igv.data.Properties;
-import com.sun.hotspot.igv.data.Property;
-import com.sun.hotspot.igv.data.services.GroupCallback;
+import com.sun.hotspot.igv.data.*;
 import com.sun.hotspot.igv.data.serialization.XMLParser.ElementHandler;
 import com.sun.hotspot.igv.data.serialization.XMLParser.HandoverElementHandler;
 import com.sun.hotspot.igv.data.serialization.XMLParser.ParseMonitor;
 import com.sun.hotspot.igv.data.serialization.XMLParser.TopElementHandler;
+import com.sun.hotspot.igv.data.services.GroupCallback;
 import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Map;
+import javax.swing.SwingUtilities;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.SchemaFactory;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 import org.xml.sax.XMLReader;
@@ -63,6 +64,7 @@
     public static final String REMOVE_EDGE_ELEMENT = "removeEdge";
     public static final String REMOVE_NODE_ELEMENT = "removeNode";
     public static final String METHOD_NAME_PROPERTY = "name";
+    public static final String GROUP_NAME_PROPERTY = "name";
     public static final String METHOD_IS_PUBLIC_PROPERTY = "public";
     public static final String METHOD_IS_STATIC_PROPERTY = "static";
     public static final String TRUE_VALUE = "true";
@@ -73,7 +75,10 @@
     public static final String TO_PROPERTY = "to";
     public static final String PROPERTY_NAME_PROPERTY = "name";
     public static final String GRAPH_NAME_PROPERTY = "name";
-    public static final String TO_INDEX_PROPERTY = "index";
+    public static final String FROM_INDEX_PROPERTY = "fromIndex";
+    public static final String TO_INDEX_PROPERTY = "toIndex";
+    public static final String TO_INDEX_ALT_PROPERTY = "index";
+    public static final String LABEL_PROPERTY = "label";
     public static final String METHOD_ELEMENT = "method";
     public static final String INLINE_ELEMENT = "inline";
     public static final String BYTECODES_ELEMENT = "bytecodes";
@@ -86,13 +91,21 @@
     public static final String SUCCESSOR_ELEMENT = "successor";
     public static final String ASSEMBLY_ELEMENT = "assembly";
     public static final String DIFFERENCE_PROPERTY = "difference";
-    private TopElementHandler xmlDocument = new TopElementHandler();
-    private boolean difference;
+    private TopElementHandler<GraphDocument> xmlDocument = new TopElementHandler<>();
+    private Map<Group, Boolean> differenceEncoding = new HashMap<>();
+    private Map<Group, InputGraph> lastParsedGraph = new HashMap<>();
     private GroupCallback groupCallback;
-    private HashMap<String, Integer> idCache = new HashMap<String, Integer>();
+    private HashMap<String, Integer> idCache = new HashMap<>();
+    private ArrayList<Pair<String, String>> blockConnections = new ArrayList<>();
     private int maxId = 0;
+    private GraphDocument graphDocument;
 
     private int lookupID(String i) {
+        try {
+            return Integer.parseInt(i);
+        } catch (NumberFormatException nfe) {
+            // ignore
+        }
         Integer id = idCache.get(i);
         if (id == null) {
             id = maxId++;
@@ -106,41 +119,40 @@
 
         @Override
         protected GraphDocument start() throws SAXException {
-            return new GraphDocument();
+            graphDocument = new GraphDocument();
+            return graphDocument;
         }
     };
     // <group>
-    private ElementHandler<Group, GraphDocument> groupHandler = new XMLParser.ElementHandler<Group, GraphDocument>(GROUP_ELEMENT) {
+    private ElementHandler<Group, Folder> groupHandler = new XMLParser.ElementHandler<Group, Folder>(GROUP_ELEMENT) {
 
         @Override
         protected Group start() throws SAXException {
-            Group group = new Group();
-            Parser.this.difference = false;
+            final Group group = new Group(this.getParentObject());
+
             String differenceProperty = this.readAttribute(DIFFERENCE_PROPERTY);
-            if (differenceProperty != null && (differenceProperty.equals("1") || differenceProperty.equals("true"))) {
-                Parser.this.difference = true;
-            }
+            Parser.this.differenceEncoding.put(group, (differenceProperty != null && (differenceProperty.equals("1") || differenceProperty.equals("true"))));
 
             ParseMonitor monitor = getMonitor();
             if (monitor != null) {
                 monitor.setState(group.getName());
             }
 
+            final Folder parent = getParentObject();
+            if (groupCallback == null || parent instanceof Group) {
+                SwingUtilities.invokeLater(new Runnable(){
+                    @Override
+                    public void run() {
+                        parent.addElement(group);
+                    }
+                });
+            }
+
             return group;
         }
 
         @Override
         protected void end(String text) throws SAXException {
-            if (groupCallback == null) {
-                getParentObject().addGroup(getObject());
-            }
-        }
-    };
-    private HandoverElementHandler<Group> assemblyHandler = new XMLParser.HandoverElementHandler<Group>(ASSEMBLY_ELEMENT, true) {
-
-        @Override
-        protected void end(String text) throws SAXException {
-            getParentObject().setAssembly(text);
         }
     };
     // <method>
@@ -155,7 +167,7 @@
         }
     };
 
-    private InputMethod parseMethod(XMLParser.ElementHandler handler, Group group) throws SAXException {
+    private InputMethod parseMethod(XMLParser.ElementHandler<?,?> handler, Group group) throws SAXException {
         String s = handler.readRequiredAttribute(METHOD_BCI_PROPERTY);
         int bci = 0;
         try {
@@ -175,7 +187,7 @@
         }
     };
     // <inlined>
-    private HandoverElementHandler<InputMethod> inlinedHandler = new XMLParser.HandoverElementHandler<InputMethod>(INLINE_ELEMENT);
+    private HandoverElementHandler<InputMethod> inlinedHandler = new XMLParser.HandoverElementHandler<>(INLINE_ELEMENT);
     // <inlined><method>
     private ElementHandler<InputMethod, InputMethod> inlinedMethodHandler = new XMLParser.ElementHandler<InputMethod, InputMethod>(METHOD_ELEMENT) {
 
@@ -189,45 +201,106 @@
     // <graph>
     private ElementHandler<InputGraph, Group> graphHandler = new XMLParser.ElementHandler<InputGraph, Group>(GRAPH_ELEMENT) {
 
-        private InputGraph graph;
-
         @Override
         protected InputGraph start() throws SAXException {
-
             String name = readAttribute(GRAPH_NAME_PROPERTY);
-            InputGraph previous = getParentObject().getLastAdded();
-            if (!difference) {
-                previous = null;
+            InputGraph curGraph = new InputGraph(name);
+            if (differenceEncoding.get(getParentObject())) {
+                InputGraph previous = lastParsedGraph.get(getParentObject());
+                lastParsedGraph.put(getParentObject(), curGraph);
+                if (previous != null) {
+                    for (InputNode n : previous.getNodes()) {
+                        curGraph.addNode(n);
+                    }
+                    for (InputEdge e : previous.getEdges()) {
+                        curGraph.addEdge(e);
+                    }
+                }
             }
-            InputGraph curGraph = new InputGraph(getParentObject(), previous, name);
-            this.graph = curGraph;
             return curGraph;
         }
 
         @Override
         protected void end(String text) throws SAXException {
-            getParentObject().addGraph(graph);
-            graph.resolveBlockLinks();
+            // NOTE: Some graphs intentionally don't provide blocks. Instead
+            //       they later generate the blocks from other information such
+            //       as node properties (example: ServerCompilerScheduler).
+            //       Thus, we shouldn't assign nodes that don't belong to any
+            //       block to some artificial block below unless blocks are
+            //       defined and nodes are assigned to them.
+
+            final InputGraph graph = getObject();
+            final Group parent = getParentObject();
+            if (graph.getBlocks().size() > 0) {
+                boolean blocksContainNodes = false;
+                for (InputBlock b : graph.getBlocks()) {
+                    if (b.getNodes().size() > 0) {
+                        blocksContainNodes = true;
+                        break;
+                    }
+                }
+
+                if (!blocksContainNodes) {
+                    graph.clearBlocks();
+                    blockConnections.clear();
+                } else {
+                    // Blocks and their nodes defined: add other nodes to an
+                    //  artificial "no block" block
+                    InputBlock noBlock = null;
+                    for (InputNode n : graph.getNodes()) {
+                        if (graph.getBlock(n) == null) {
+                            if (noBlock == null) {
+                                noBlock = graph.addBlock("(no block)");
+                            }
+
+                            noBlock.addNode(n.getId());
+                        }
+
+                        assert graph.getBlock(n) != null;
+                    }
+                }
+            }
+
+            // Resolve block successors
+            for (Pair<String, String> p : blockConnections) {
+                final InputBlock left = graph.getBlock(p.getLeft());
+                assert left != null;
+                final InputBlock right = graph.getBlock(p.getRight());
+                assert right != null;
+                graph.addBlockEdge(left, right);
+            }
+            blockConnections.clear();
+
+            SwingUtilities.invokeLater(new Runnable(){
+
+                @Override
+                public void run() {
+                    // Add to group
+                    parent.addElement(graph);
+                }
+            });
         }
     };
     // <nodes>
-    private HandoverElementHandler<InputGraph> nodesHandler = new HandoverElementHandler<InputGraph>(NODES_ELEMENT);
+    private HandoverElementHandler<InputGraph> nodesHandler = new HandoverElementHandler<>(NODES_ELEMENT);
     // <controlFlow>
-    private HandoverElementHandler<InputGraph> controlFlowHandler = new HandoverElementHandler<InputGraph>(CONTROL_FLOW_ELEMENT);
+    private HandoverElementHandler<InputGraph> controlFlowHandler = new HandoverElementHandler<>(CONTROL_FLOW_ELEMENT);
     // <block>
     private ElementHandler<InputBlock, InputGraph> blockHandler = new ElementHandler<InputBlock, InputGraph>(BLOCK_ELEMENT) {
 
         @Override
         protected InputBlock start() throws SAXException {
             InputGraph graph = getParentObject();
-            String name = readRequiredAttribute(BLOCK_NAME_PROPERTY).intern();
-            InputBlock b = new InputBlock(getParentObject(), name);
-            graph.addBlock(b);
+            String name = readRequiredAttribute(BLOCK_NAME_PROPERTY);
+            InputBlock b = graph.addBlock(name);
+            for (InputNode n : b.getNodes()) {
+                assert graph.getBlock(n).equals(b);
+            }
             return b;
         }
     };
     // <nodes>
-    private HandoverElementHandler<InputBlock> blockNodesHandler = new HandoverElementHandler<InputBlock>(NODES_ELEMENT);
+    private HandoverElementHandler<InputBlock> blockNodesHandler = new HandoverElementHandler<>(NODES_ELEMENT);
     // <node>
     private ElementHandler<InputBlock, InputBlock> blockNodeHandler = new ElementHandler<InputBlock, InputBlock>(NODE_ELEMENT) {
 
@@ -246,14 +319,14 @@
         }
     };
     // <successors>
-    private HandoverElementHandler<InputBlock> successorsHandler = new HandoverElementHandler<InputBlock>(SUCCESSORS_ELEMENT);
+    private HandoverElementHandler<InputBlock> successorsHandler = new HandoverElementHandler<>(SUCCESSORS_ELEMENT);
     // <successor>
     private ElementHandler<InputBlock, InputBlock> successorHandler = new ElementHandler<InputBlock, InputBlock>(SUCCESSOR_ELEMENT) {
 
         @Override
         protected InputBlock start() throws SAXException {
             String name = readRequiredAttribute(BLOCK_NAME_PROPERTY);
-            getParentObject().addSuccessor(name);
+            blockConnections.add(new Pair<>(getParentObject().getName(), name));
             return getParentObject();
         }
     };
@@ -290,7 +363,7 @@
         }
     };
     // <graph>
-    private HandoverElementHandler<InputGraph> edgesHandler = new HandoverElementHandler<InputGraph>(EDGES_ELEMENT);
+    private HandoverElementHandler<InputGraph> edgesHandler = new HandoverElementHandler<>(EDGES_ELEMENT);
 
     // Local class for edge elements
     private class EdgeElementHandler extends ElementHandler<InputEdge, InputGraph> {
@@ -301,24 +374,35 @@
 
         @Override
         protected InputEdge start() throws SAXException {
+            int fromIndex = 0;
             int toIndex = 0;
             int from = -1;
             int to = -1;
+            String label = null;
 
             try {
+                String fromIndexString = readAttribute(FROM_INDEX_PROPERTY);
+                if (fromIndexString != null) {
+                    fromIndex = Integer.parseInt(fromIndexString);
+                }
+
                 String toIndexString = readAttribute(TO_INDEX_PROPERTY);
+                if (toIndexString == null) {
+                    toIndexString = readAttribute(TO_INDEX_ALT_PROPERTY);
+                }
                 if (toIndexString != null) {
                     toIndex = Integer.parseInt(toIndexString);
                 }
 
+                label = readAttribute(LABEL_PROPERTY);
+
                 from = lookupID(readRequiredAttribute(FROM_PROPERTY));
                 to = lookupID(readRequiredAttribute(TO_PROPERTY));
             } catch (NumberFormatException e) {
                 throw new SAXException(e);
             }
 
-
-            InputEdge conn = new InputEdge((char) toIndex, from, to);
+            InputEdge conn = new InputEdge((char) fromIndex, (char) toIndex, from, to, label);
             return start(conn);
         }
 
@@ -345,14 +429,20 @@
         }
     };
     // <properties>
-    private HandoverElementHandler<Properties.Provider> propertiesHandler = new HandoverElementHandler<Properties.Provider>(PROPERTIES_ELEMENT);
+    private HandoverElementHandler<Properties.Provider> propertiesHandler = new HandoverElementHandler<>(PROPERTIES_ELEMENT);
     // <properties>
     private HandoverElementHandler<Group> groupPropertiesHandler = new HandoverElementHandler<Group>(PROPERTIES_ELEMENT) {
 
         @Override
         public void end(String text) throws SAXException {
-            if (groupCallback != null) {
-                groupCallback.started(getParentObject());
+            if (groupCallback != null && getParentObject().getParent() instanceof GraphDocument) {
+                final Group group = getParentObject();
+                SwingUtilities.invokeLater(new Runnable() {
+                    @Override
+                    public void run() {
+                        groupCallback.started(group);
+                    }
+                });
             }
         }
     };
@@ -361,12 +451,12 @@
 
         @Override
         public String start() throws SAXException {
-            return readRequiredAttribute(PROPERTY_NAME_PROPERTY).intern();
-        }
+            return readRequiredAttribute(PROPERTY_NAME_PROPERTY);
+         }
 
         @Override
         public void end(String text) {
-            getParentObject().getProperties().setProperty(getObject(), text.trim().intern());
+            getParentObject().getProperties().setProperty(getObject(), text.trim());
         }
     };
 
@@ -383,8 +473,8 @@
         topHandler.addChild(groupHandler);
 
         groupHandler.addChild(methodHandler);
-        groupHandler.addChild(assemblyHandler);
         groupHandler.addChild(graphHandler);
+        groupHandler.addChild(groupHandler);
 
         methodHandler.addChild(inlinedHandler);
         methodHandler.addChild(bytecodesHandler);
@@ -420,7 +510,9 @@
     }
 
     // Returns a new GraphDocument object deserialized from an XML input source.
-    public GraphDocument parse(XMLReader reader, InputSource source, XMLParser.ParseMonitor monitor) throws SAXException {
+    public GraphDocument parse(InputSource source, XMLParser.ParseMonitor monitor) throws SAXException {
+        XMLReader reader = createReader();
+
         reader.setContentHandler(new XMLParser(xmlDocument, monitor));
         try {
             reader.parse(source);
@@ -428,6 +520,23 @@
             throw new SAXException(ex);
         }
 
-        return topHandler.getObject();
+        return graphDocument;
+    }
+
+    private XMLReader createReader() throws SAXException {
+        try {
+            SAXParserFactory pfactory = SAXParserFactory.newInstance();
+            pfactory.setValidating(false);
+            pfactory.setNamespaceAware(true);
+
+            // Enable schema validation
+            SchemaFactory sfactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
+            InputStream stream = Parser.class.getResourceAsStream("graphdocument.xsd");
+            pfactory.setSchema(sfactory.newSchema(new Source[]{new StreamSource(stream)}));
+
+            return pfactory.newSAXParser().getXMLReader();
+        } catch (ParserConfigurationException ex) {
+            throw new SAXException(ex);
+        }
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Printer.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Printer.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,17 +23,9 @@
  */
 package com.sun.hotspot.igv.data.serialization;
 
-import com.sun.hotspot.igv.data.GraphDocument;
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.InputBlock;
-import com.sun.hotspot.igv.data.InputBytecode;
-import com.sun.hotspot.igv.data.InputEdge;
-import com.sun.hotspot.igv.data.InputGraph;
-import com.sun.hotspot.igv.data.InputMethod;
-import com.sun.hotspot.igv.data.InputNode;
-import com.sun.hotspot.igv.data.Properties;
-import com.sun.hotspot.igv.data.Property;
+import com.sun.hotspot.igv.data.*;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.Writer;
 import java.util.HashSet;
 import java.util.Set;
@@ -44,6 +36,16 @@
  */
 public class Printer {
 
+    private InputStream in;
+
+    public Printer() {
+        this(null);
+    }
+
+    public Printer(InputStream inputStream) {
+        this.in = inputStream;
+    }
+
     public void export(Writer writer, GraphDocument document) {
 
         XMLWriter xmlWriter = new XMLWriter(writer);
@@ -57,8 +59,12 @@
     private void export(XMLWriter xmlWriter, GraphDocument document) throws IOException {
         xmlWriter.startTag(Parser.ROOT_ELEMENT);
         xmlWriter.writeProperties(document.getProperties());
-        for (Group g : document.getGroups()) {
-            export(xmlWriter, g);
+        for (FolderElement e : document.getElements()) {
+            if (e instanceof Group) {
+                export(xmlWriter, (Group) e);
+            } else if (e instanceof InputGraph) {
+                export(xmlWriter, (InputGraph)e, null, false);
+            }
         }
 
         xmlWriter.endTag();
@@ -71,14 +77,29 @@
         writer.startTag(Parser.GROUP_ELEMENT, attributes);
         writer.writeProperties(g.getProperties());
 
-        if (g.getMethod() != null) {
-            export(writer, g.getMethod());
+        boolean shouldExport = true;
+        if (in != null) {
+            char c = (char) in.read();
+            if (c != 'y') {
+                shouldExport = false;
+            }
         }
 
-        InputGraph previous = null;
-        for (InputGraph graph : g.getGraphs()) {
-            export(writer, graph, previous, true);
-            previous = graph;
+        if (shouldExport) {
+            if (g.getMethod() != null) {
+                export(writer, g.getMethod());
+            }
+
+            InputGraph previous = null;
+            for (FolderElement e : g.getElements()) {
+                if (e instanceof InputGraph) {
+                    InputGraph graph = (InputGraph) e;
+                    export(writer, graph, previous, true);
+                    previous = graph;
+                } else if (e instanceof Group) {
+                    export(writer, (Group) e);
+                }
+            }
         }
 
         writer.endTag();
@@ -90,8 +111,8 @@
         writer.writeProperties(graph.getProperties());
         writer.startTag(Parser.NODES_ELEMENT);
 
-        Set<InputNode> removed = new HashSet<InputNode>();
-        Set<InputNode> equal = new HashSet<InputNode>();
+        Set<InputNode> removed = new HashSet<>();
+        Set<InputNode> equal = new HashSet<>();
 
         if (previous != null) {
             for (InputNode n : previous.getNodes()) {
@@ -122,8 +143,8 @@
         writer.endTag();
 
         writer.startTag(Parser.EDGES_ELEMENT);
-        Set<InputEdge> removedEdges = new HashSet<InputEdge>();
-        Set<InputEdge> equalEdges = new HashSet<InputEdge>();
+        Set<InputEdge> removedEdges = new HashSet<>();
+        Set<InputEdge> equalEdges = new HashSet<>();
 
         if (previous != null) {
             for (InputEdge e : previous.getEdges()) {
@@ -153,23 +174,25 @@
 
         writer.startTag(Parser.CONTROL_FLOW_ELEMENT);
         for (InputBlock b : graph.getBlocks()) {
-
             writer.startTag(Parser.BLOCK_ELEMENT, new Properties(Parser.BLOCK_NAME_PROPERTY, b.getName()));
-
-            writer.startTag(Parser.SUCCESSORS_ELEMENT);
-            for (InputBlock s : b.getSuccessors()) {
-                writer.simpleTag(Parser.SUCCESSOR_ELEMENT, new Properties(Parser.BLOCK_NAME_PROPERTY, s.getName()));
+            
+            if (b.getSuccessors().size() > 0) {
+                writer.startTag(Parser.SUCCESSORS_ELEMENT);
+                for (InputBlock s : b.getSuccessors()) {
+                    writer.simpleTag(Parser.SUCCESSOR_ELEMENT, new Properties(Parser.BLOCK_NAME_PROPERTY, s.getName()));
+                }
+                writer.endTag();
             }
-            writer.endTag();
 
+            if (b.getNodes().size() > 0) {
             writer.startTag(Parser.NODES_ELEMENT);
-            for (InputNode n : b.getNodes()) {
-                writer.simpleTag(Parser.NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, n.getId() + ""));
+                for (InputNode n : b.getNodes()) {
+                    writer.simpleTag(Parser.NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, n.getId() + ""));
+                }
+                writer.endTag();
             }
+            
             writer.endTag();
-
-            writer.endTag();
-
         }
 
         writer.endTag();
@@ -199,8 +222,8 @@
             b.append(" ");
             b.append(code.getName());
             b.append("\n");
-
         }
+        
         b.append("]]>");
         w.write(b.toString());
         w.endTag();
@@ -209,7 +232,12 @@
 
     private Properties createProperties(InputEdge edge) {
         Properties p = new Properties();
-        p.setProperty(Parser.TO_INDEX_PROPERTY, Integer.toString(edge.getToIndex()));
+        if (edge.getToIndex() != 0) {
+            p.setProperty(Parser.TO_INDEX_PROPERTY, Integer.toString(edge.getToIndex()));
+        }
+        if (edge.getFromIndex() != 0) {
+            p.setProperty(Parser.FROM_INDEX_PROPERTY, Integer.toString(edge.getFromIndex()));
+        }
         p.setProperty(Parser.TO_PROPERTY, Integer.toString(edge.getTo()));
         p.setProperty(Parser.FROM_PROPERTY, Integer.toString(edge.getFrom()));
         return p;
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLParser.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLParser.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,7 +23,6 @@
  */
 package com.sun.hotspot.igv.data.serialization;
 
-import com.sun.hotspot.igv.data.Property;
 import com.sun.hotspot.igv.data.Properties;
 import java.util.HashMap;
 import java.util.Stack;
@@ -85,24 +84,25 @@
     public static class ElementHandler<T, P> {
 
         private String name;
-        private T object;
+        private Stack<T> object = new Stack<>();
         private Attributes attr;
         private StringBuilder currentText;
         private ParseMonitor monitor;
         private HashMap<String, ElementHandler<?, ? super T>> hashtable;
         private boolean needsText;
-        private ElementHandler<P, ?> parentElement;
+        private Stack<ElementHandler<P, ?>> parentElement = new Stack<>();
+        private Stack<P> parentObject = new Stack<>();
 
         public ElementHandler(String name) {
             this(name, false);
         }
 
         public ElementHandler<P, ?> getParentElement() {
-            return parentElement;
+            return parentElement.peek();
         }
 
         public P getParentObject() {
-            return getParentElement().getObject();
+            return parentObject.peek();
         }
 
         protected boolean needsText() {
@@ -110,7 +110,7 @@
         }
 
         public ElementHandler(String name, boolean needsText) {
-            this.hashtable = new HashMap<String, ElementHandler<?, ? super T>>();
+            this.hashtable = new HashMap<>();
             this.name = name;
             this.needsText = needsText;
         }
@@ -133,7 +133,7 @@
         }
 
         public T getObject() {
-            return object;
+            return object.size() == 0 ? null : object.peek();
         }
 
         public String readAttribute(String name) {
@@ -151,8 +151,8 @@
         public void processAttributesAsProperties(Properties p) {
             int length = attr.getLength();
             for (int i = 0; i < length; i++) {
-                String val = attr.getValue(i).intern();
-                String localName = attr.getLocalName(i).intern();
+                String val = attr.getValue(i);
+                String localName = attr.getLocalName(i);
                 p.setProperty(val, localName);
             }
         }
@@ -161,8 +161,9 @@
             this.currentText = new StringBuilder();
             this.attr = attr;
             this.monitor = monitor;
-            this.parentElement = parentElement;
-            object = start();
+            this.parentElement.push(parentElement);
+            parentObject.push(parentElement.getObject());
+            object.push(start());
         }
 
         protected T start() throws SAXException {
@@ -175,6 +176,9 @@
 
         public void endElement() throws SAXException {
             end(currentText.toString());
+            object.pop();
+            parentElement.pop();
+            parentObject.pop();
         }
 
         protected void text(char[] c, int start, int length) {
@@ -186,32 +190,39 @@
     private ParseMonitor monitor;
 
     public XMLParser(TopElementHandler rootHandler, ParseMonitor monitor) {
-        this.stack = new Stack<ElementHandler>();
+        this.stack = new Stack<>();
         this.monitor = monitor;
         this.stack.push(rootHandler);
     }
 
+    @Override
     public void setDocumentLocator(Locator locator) {
         if (monitor != null) {
             monitor.setState("Starting parsing");
         }
     }
 
+    @Override
     public void startDocument() throws SAXException {
     }
 
+    @Override
     public void endDocument() throws SAXException {
     }
 
+    @Override
     public void startPrefixMapping(String prefix, String uri) throws SAXException {
     }
 
+    @Override
     public void endPrefixMapping(String prefix) throws SAXException {
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
     public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+        assert !stack.isEmpty();
 
-        assert !stack.isEmpty();
         ElementHandler parent = stack.peek();
         if (parent != null) {
             ElementHandler child = parent.getChild(qName);
@@ -225,6 +236,7 @@
         stack.push(null);
     }
 
+    @Override
     public void endElement(String uri, String localName, String qName) throws SAXException {
         ElementHandler handler = stack.pop();
         if (handler != null) {
@@ -232,6 +244,7 @@
         }
     }
 
+    @Override
     public void characters(char[] ch, int start, int length) throws SAXException {
 
         assert !stack.isEmpty();
@@ -243,12 +256,15 @@
         }
     }
 
+    @Override
     public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
     }
 
+    @Override
     public void processingInstruction(String target, String data) throws SAXException {
     }
 
+    @Override
     public void skippedEntity(String name) throws SAXException {
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLWriter.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLWriter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -41,7 +41,7 @@
 
     public XMLWriter(Writer inner) {
         this.inner = inner;
-        elementStack = new Stack<String>();
+        elementStack = new Stack<>();
     }
 
     @Override
@@ -49,6 +49,7 @@
         write(arr, 0, arr.length);
     }
 
+    @Override
     public void write(char[] cbuf, int off, int len) throws IOException {
         for (int i = off; i < off + len; i++) {
             char c = cbuf[i];
@@ -64,10 +65,12 @@
         }
     }
 
+    @Override
     public void flush() throws IOException {
         inner.flush();
     }
 
+    @Override
     public void close() throws IOException {
         inner.close();
     }
@@ -111,7 +114,7 @@
     }
 
     public void writeProperties(Properties props) throws IOException {
-        if (props.getProperties().hasNext() == false) {
+        if (props.iterator().hasNext() == false) {
             return;
         }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/graphdocument.xsd	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+    
+    <xsd:element name="graphDocument">
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element name="properties" type="propertiesType" minOccurs="0" maxOccurs="1" />
+                <xsd:element name="group" type="groupType" minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+        </xsd:complexType>
+    </xsd:element>
+
+    <xsd:complexType name="groupType">
+        <xsd:sequence>
+            <xsd:element name="properties" type="propertiesType" minOccurs="0" maxOccurs="1" />
+            <xsd:element name="assembly" type="assemblyType" minOccurs="0" maxOccurs="1" />
+            <xsd:element name="method" type="methodType" minOccurs="0" maxOccurs="1" />
+            <xsd:element name="graph" type="graphType" minOccurs="0" maxOccurs="unbounded" />
+        </xsd:sequence>
+        <xsd:attribute name="difference" use="optional" />
+    </xsd:complexType>
+    
+    <xsd:complexType name="propertiesType">
+        <xsd:sequence>
+            <xsd:element name="p" minOccurs="0" maxOccurs="unbounded">
+                <xsd:complexType>
+                    <xsd:simpleContent>
+                        <xsd:extension base="xsd:string">
+                            <xsd:attribute name="name" use="required" />
+                        </xsd:extension>
+                    </xsd:simpleContent>
+                </xsd:complexType>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    
+    <xsd:simpleType name="assemblyType">
+        <xsd:restriction base="xsd:string" />
+    </xsd:simpleType>
+    
+    <xsd:complexType name="methodType">
+        <xsd:all>
+            <xsd:element name="properties" type="propertiesType" minOccurs="0" maxOccurs="1" />
+            <xsd:element name="bytecodes" minOccurs="0" maxOccurs="1">
+                <xsd:simpleType>
+                    <xsd:restriction base="xsd:string" />
+                </xsd:simpleType>
+            </xsd:element>
+            <xsd:element name="inlined" minOccurs="0" maxOccurs="1">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="method" type="methodType" minOccurs="0" maxOccurs="unbounded" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+        </xsd:all>
+        <xsd:attribute name="bci" type="xsd:int" use="required" />
+        <xsd:attribute name="shortName" type="xsd:string" use="required" />
+        <xsd:attribute name="name" type="xsd:string" use="required" />
+    </xsd:complexType>
+    
+    <xsd:complexType name="graphType">
+        <xsd:sequence>
+            <xsd:element name="properties" type="propertiesType" minOccurs="0" maxOccurs="1" />
+            
+            <xsd:element name="nodes" minOccurs="0" maxOccurs="1">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:choice minOccurs="0" maxOccurs="unbounded">
+                            <xsd:element name="node" type="nodeType" />
+                            <xsd:element name="removeNode" type="nodeRefType" />
+                        </xsd:choice>
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            
+            <xsd:element name="edges" minOccurs="0" maxOccurs="1">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:choice minOccurs="0" maxOccurs="unbounded">
+                            <xsd:element name="edge" type="edgeType" />
+                            <xsd:element name="removeEdge" type="edgeType" />
+                        </xsd:choice>
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            
+            <xsd:element name="controlFlow" type="controlFlowType" minOccurs="0" maxOccurs="1" />
+        </xsd:sequence>
+        
+        <xsd:attribute name="name" use="optional" />
+    </xsd:complexType>
+    
+    <xsd:complexType name="nodeType">
+        <xsd:sequence>
+            <xsd:element name="properties" type="propertiesType" minOccurs="0" maxOccurs="1" />
+        </xsd:sequence>
+        <xsd:attribute name="id" type="xsd:int" use="required" />
+    </xsd:complexType>
+    
+    <xsd:complexType name="nodeRefType">
+        <xsd:attribute name="id" type="xsd:int" use="required" />
+    </xsd:complexType>
+    
+    <xsd:complexType name="edgeType">
+        <xsd:attribute name="from" type="xsd:int" use="required" />
+        <xsd:attribute name="to" type="xsd:int" use="required" />
+        <xsd:attribute name="label" type="xsd:string" use="optional" />
+        <xsd:attribute name="fromIndex" type="xsd:int" use="optional" />
+        
+        <!-- These are aliases and should be mutually exclusive -->
+        <xsd:attribute name="toIndex" type="xsd:int" use="optional" />
+        <xsd:attribute name="index" type="xsd:int" use="optional" />
+    </xsd:complexType>
+    
+    <xsd:complexType name="controlFlowType">
+        <xsd:sequence>
+            <xsd:element name="block" type="blockType" minOccurs="0" maxOccurs="unbounded" />
+        </xsd:sequence>
+    </xsd:complexType>
+    
+    <xsd:complexType name="blockType">
+        <xsd:all>
+            <xsd:element name="successors" minOccurs="0" maxOccurs="1">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="successor" minOccurs="0" maxOccurs="unbounded">
+                            <xsd:complexType>
+                                <xsd:attribute name="name" type="xsd:string" use="required" />
+                            </xsd:complexType>
+                        </xsd:element>
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="nodes" minOccurs="0" maxOccurs="1">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="node" type="nodeRefType" minOccurs="0" maxOccurs="unbounded" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>    
+        </xsd:all>
+        
+        <xsd:attribute name="name" type="xsd:string" use="required" />
+    </xsd:complexType>
+</xsd:schema>
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GroupOrganizer.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.data.services;
-
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.Pair;
-import java.util.List;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public interface GroupOrganizer {
-
-    public String getName();
-
-    public List<Pair<String, List<Group>>> organize(List<String> subFolders, List<Group> groups);
-}
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GroupReceiver.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.data.services;
-
-import java.awt.Component;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public interface GroupReceiver {
-
-    public Component init(GroupCallback callback);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/ChangedEventTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ChangedEventTest {
+
+    public ChangedEventTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of addListener method, of class Event.
+     */
+    @Test
+    public void testBase() {
+
+        ChangedEvent<Integer> e = new ChangedEvent<>(5);
+        final int[] fireCount = new int[1];
+
+        e.addListener(new ChangedListener<Integer>() {
+            @Override
+            public void changed(Integer s) {
+                assertEquals(s.intValue(), 5);
+                fireCount[0]++;
+            }
+        });
+
+        e.fire();
+        assertEquals(1, fireCount[0]);
+
+        e.fire();
+        assertEquals(2, fireCount[0]);
+
+        e.beginAtomic();
+
+        e.fire();
+        assertEquals(2, fireCount[0]);
+
+        e.fire();
+        assertEquals(2, fireCount[0]);
+
+        e.fire();
+        assertEquals(2, fireCount[0]);
+
+        e.endAtomic();
+        assertEquals(3, fireCount[0]);
+
+    }
+
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/ControllableChangedListenerTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import static org.junit.Assert.*;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ControllableChangedListenerTest {
+
+    public ControllableChangedListenerTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of isEnabled method, of class ControllableChangedListener.
+     */
+    @Test
+    public void testBase() {
+
+        final boolean[] hasFired = new boolean[1];
+        final boolean[] shouldFire = new boolean[1];
+        final Integer[] valueToFire = new Integer[1];
+        ControllableChangedListener<Integer> l = new ControllableChangedListener<Integer>() {
+
+            @Override
+            public void filteredChanged(Integer value) {
+                assertTrue(shouldFire[0]);
+                assertEquals(valueToFire[0], value);
+                hasFired[0] = true;
+            }
+        };
+
+        shouldFire[0] = true;
+        valueToFire[0] = 1;
+        hasFired[0] = false;
+        l.changed(1);
+        assertTrue(hasFired[0]);
+
+        shouldFire[0] = false;
+        hasFired[0] = false;
+        l.setEnabled(false);
+        l.changed(1);
+        assertFalse(hasFired[0]);
+
+        shouldFire[0] = true;
+        valueToFire[0] = 1;
+        hasFired[0] = false;
+        l.setEnabled(true);
+        l.changed(1);
+        assertTrue(hasFired[0]);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/GroupTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import static org.junit.Assert.assertEquals;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class GroupTest {
+
+    public GroupTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getAllNodes method, of class Group.
+     */
+    @Test
+    public void testGetAllNodes() {
+        final Group g = new Group(null);
+        final InputGraph graph1 = new InputGraph("1");
+        final InputGraph graph2 = new InputGraph("2");
+        g.addElement(graph1);
+        g.addElement(graph2);
+        graph1.addNode(new InputNode(1));
+        graph1.addNode(new InputNode(2));
+        graph2.addNode(new InputNode(2));
+        graph2.addNode(new InputNode(3));
+        assertEquals(g.getAllNodes(), new HashSet(Arrays.asList(1, 2, 3)));
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/InputGraphTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputGraphTest {
+
+    /**
+     *    1
+     *   / \
+     *  2   3
+     *   \  |  5
+     *    \ | /
+     *      4
+     */
+    private static InputGraph referenceGraph;
+
+    private static InputGraph emptyGraph;
+
+    private static final InputNode N1 = new InputNode(1);
+    private static final InputNode N2 = new InputNode(2);
+    private static final InputNode N3 = new InputNode(3);
+    private static final InputNode N4 = new InputNode(4);
+    private static final InputNode N5 = new InputNode(5);
+    private static final InputEdge E12 = new InputEdge((char)0, 1, 2);
+    private static final InputEdge E13 = new InputEdge((char)0, 1, 3);
+    private static final InputEdge E24 = new InputEdge((char)0, 2, 4);
+    private static final InputEdge E34 = new InputEdge((char)0, 3, 4);
+    private static final InputEdge E54 = new InputEdge((char)0, 5, 4);
+
+    public InputGraphTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        Group group = new Group(null);
+
+        emptyGraph = new InputGraph("emptyGraph");
+        group.addElement(emptyGraph);
+        
+        referenceGraph = new InputGraph("referenceGraph");
+        group.addElement(referenceGraph);
+        referenceGraph.addNode(N1);
+        referenceGraph.addNode(N2);
+        referenceGraph.addNode(N3);
+        referenceGraph.addNode(N4);
+        referenceGraph.addNode(N5);
+
+        referenceGraph.addEdge(E12);
+        referenceGraph.addEdge(E13);
+        referenceGraph.addEdge(E24);
+        referenceGraph.addEdge(E34);
+        referenceGraph.addEdge(E54);
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of equals method, of class InputGraph.
+     */
+    @Test
+    public void testEquals() {
+
+        Group parentA = new Group(null);
+        InputGraph a = new InputGraph("graph");
+        parentA.addElement(a);
+
+        Group parentB = new Group(null);
+        InputGraph b = new InputGraph("graph");
+        parentB.addElement(b);
+
+        InputGraph c = new InputGraph("graph");
+        parentB.addElement(b);
+
+        Util.assertGraphEquals(a, b);
+        Util.assertGraphEquals(b, c);
+
+        a.addNode(new InputNode(1));
+        Util.assertGraphNotEquals(a, b);
+
+        b.addNode(new InputNode(1));
+        Util.assertGraphEquals(a, b);
+    }
+
+    /**
+     * Test of findRootNodes method, of class InputGraph.
+     */
+    @Test
+    public void testFindRootNodes() {
+        assertTrue(emptyGraph.findRootNodes().isEmpty());
+
+        List<InputNode> result = referenceGraph.findRootNodes();
+        assertTrue(result.size() == 2);
+        assertTrue(result.contains(N1));
+        assertTrue(result.contains(N5));
+    }
+
+    /**
+     * Test of findAllOutgoingEdges method, of class InputGraph.
+     */
+    @Test
+    public void testFindAllOutgoingEdges() {
+        assertTrue(emptyGraph.findAllOutgoingEdges().isEmpty());
+
+        Map<InputNode, List<InputEdge>> result = referenceGraph.findAllOutgoingEdges();
+        assertTrue(result.size() == 5);
+        assertEquals(result.get(N1), Arrays.asList(E12, E13));
+        assertEquals(result.get(N2), Arrays.asList(E24));
+        assertEquals(result.get(N3), Arrays.asList(E34));
+        assertEquals(result.get(N4), Arrays.asList());
+        assertEquals(result.get(N5), Arrays.asList(E54));
+    }
+
+    /**
+     * Test of findAllIngoingEdges method, of class InputGraph.
+     */
+    @Test
+    public void testFindAllIngoingEdges() {
+        assertTrue(emptyGraph.findAllIngoingEdges().isEmpty());
+
+        Map<InputNode, List<InputEdge>> result = referenceGraph.findAllIngoingEdges();
+        assertTrue(result.size() == 5);
+        assertEquals(result.get(N1), Arrays.asList());
+        assertEquals(result.get(N2), Arrays.asList(E12));
+        assertEquals(result.get(N3), Arrays.asList(E13));
+        assertEquals(result.get(N4), Arrays.asList(E24, E34, E54));
+        assertEquals(result.get(N5), Arrays.asList());
+    }
+
+    /**
+     * Test of findOutgoingEdges method, of class InputGraph.
+     */
+    @Test
+    public void testFindOutgoingEdges() {
+        assertTrue(emptyGraph.findOutgoingEdges(new InputNode(1)).isEmpty());
+
+        assertEquals(referenceGraph.findOutgoingEdges(N1), Arrays.asList(E12, E13));
+        assertEquals(referenceGraph.findOutgoingEdges(N2), Arrays.asList(E24));
+        assertEquals(referenceGraph.findOutgoingEdges(N3), Arrays.asList(E34));
+        assertEquals(referenceGraph.findOutgoingEdges(N4), Arrays.asList());
+        assertEquals(referenceGraph.findOutgoingEdges(N5), Arrays.asList(E54));
+    }
+
+    /**
+     * Test of getNext method, of class InputGraph.
+     */
+    @Test
+    public void testGetNextPrev() {
+        final Group group = new Group(null);
+
+        final InputGraph a = new InputGraph("a");
+
+        final InputGraph b = new InputGraph("b");
+
+        final InputGraph c = new InputGraph("c");
+        group.addElement(a);
+        group.addElement(b);
+        group.addElement(c);
+
+        assertEquals(null, a.getPrev());
+        assertEquals(b, a.getNext());
+
+        assertEquals(a, b.getPrev());
+        assertEquals(c, b.getNext());
+
+        assertEquals(b, c.getPrev());
+        assertEquals(null, c.getNext());
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/InputMethodTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,93 @@
+/*
+ * 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.sun.hotspot.igv.data;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas
+ */
+public class InputMethodTest {
+
+    public InputMethodTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+
+    /**
+     * Test of getBytecodes method, of class InputMethod.
+     */
+    @Test
+    public void testGetSetBytecodes() {
+
+        final String input = "0 iload_0\n" +
+                             "1 iconst_1\n" +
+                             "2 if_icmpne 7\n" +
+                             "5 iconst_1\n" +
+                             "6 ireturn\n" +
+                             "7 iconst_0\n" +
+                             "8 ireturn";
+
+        final Group g = new Group(null);
+        InputMethod m = new InputMethod(g, "name", "shortName", -1);
+        m.setBytecodes(input);
+
+        assertThat(m.getBytecodes().size(), is(7));
+
+        assertThat(m.getBytecodes().get(0).getBci(), is(0));
+        assertThat(m.getBytecodes().get(1).getBci(), is(1));
+        assertThat(m.getBytecodes().get(2).getBci(), is(2));
+        assertThat(m.getBytecodes().get(3).getBci(), is(5));
+
+        assertThat(m.getBytecodes().get(0).getName(), is("iload_0"));
+        assertThat(m.getBytecodes().get(1).getName(), is("iconst_1"));
+        assertThat(m.getBytecodes().get(2).getName(), is("if_icmpne 7"));
+        assertThat(m.getBytecodes().get(6).getName(), is("ireturn"));
+
+        assertThat(m.getBytecodes().get(2).getInlined(), nullValue());
+        assertThat(m.getBytecodes().get(6).getInlined(), nullValue());
+    }
+
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/PairTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1998, 2007, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.data;
+
+import static org.junit.Assert.*;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class PairTest {
+
+    public PairTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getLeft method, of class Pair.
+     */
+    @Test
+    public void testBase() {
+        Pair p = new Pair();
+        assertTrue(p.getLeft() == null);
+        assertTrue(p.getRight() == null);
+        assertEquals("[null/null]", p.toString());
+        assertFalse(p.equals(null));
+
+        Pair<Integer, Integer> p2 = new Pair(1, 2);
+        assertTrue(p2.getLeft().intValue() == 1);
+        assertTrue(p2.getRight().intValue() == 2);
+        assertFalse(p.equals(p2));
+        assertFalse(p2.equals(p));
+        assertFalse(p.hashCode() == p2.hashCode());
+        assertEquals("[1/2]", p2.toString());
+
+        Pair p3 = new Pair(1, 2);
+        assertTrue(p2.equals(p3));
+        assertTrue(p2.hashCode() == p3.hashCode());
+
+        p2.setLeft(2);
+        assertFalse(p2.equals(p3));
+        assertTrue(p2.getLeft().intValue() == 2);
+        assertTrue(p2.getRight().intValue() == 2);
+        assertFalse(p2.hashCode() == p3.hashCode());
+        assertEquals("[2/2]", p2.toString());
+
+        p2.setRight(1);
+        assertFalse(p2.equals(p3));
+        assertTrue(p2.getLeft().intValue() == 2);
+        assertTrue(p2.getRight().intValue() == 1);
+        assertFalse(p2.hashCode() == p3.hashCode());
+        assertEquals("[2/1]", p2.toString());
+
+        p3.setLeft(2);
+        p3.setRight(1);
+        assertTrue(p2.hashCode() == p3.hashCode());
+        assertTrue(p2.equals(p3));
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/PropertiesTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,401 @@
+/*
+ * Copyright (c) 1998, 2007, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.data;
+
+import com.sun.hotspot.igv.data.Properties.InvertPropertyMatcher;
+import com.sun.hotspot.igv.data.Properties.PropertyMatcher;
+import com.sun.hotspot.igv.data.Properties.PropertySelector;
+import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher;
+import com.sun.hotspot.igv.data.Properties.StringPropertyMatcher;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import junit.framework.TestCase;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class PropertiesTest extends TestCase {
+
+
+    
+    public PropertiesTest(String testName) {
+        super(testName);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * Test of equals method, of class Properties.
+     */
+    public void testEquals() {
+        Properties a = new Properties();
+        assertFalse(a.equals(null));
+        assertTrue(a.equals(a));
+        
+        Properties b = new Properties();
+        assertTrue(a.equals(b));
+        assertTrue(a.hashCode() == b.hashCode());
+
+        a.setProperty("p1", "1");
+        assertFalse(a.equals(b));
+        assertFalse(b.equals(a));
+        assertFalse(a.hashCode() == b.hashCode());
+
+        b.setProperty("p1", "1");
+        assertTrue(a.equals(b));
+        assertTrue(a.hashCode() == b.hashCode());
+
+        Properties c = new Properties(a);
+        assertTrue(c.equals(a));
+        assertTrue(c.equals(b));
+
+        c.setProperty("p1", "2");
+        assertFalse(c.equals(b));
+        assertFalse(c.hashCode() == b.hashCode());
+        assertFalse(c.equals(a));
+        assertFalse(c.hashCode() == a.hashCode());
+
+        a.setProperty("p2", "2");
+        Properties d = new Properties();
+        d.setProperty("p2", "2");
+        d.setProperty("p1", "1");
+        assertTrue(d.equals(a));
+    }
+
+    /**
+     * Test of selectSingle method, of class Properties.
+     */
+    public void testSelectSingle() {
+        
+        final boolean[] called = new boolean[1];
+        final String v = "2";
+        final String n = "p2";
+        
+        PropertyMatcher matcher = new PropertyMatcher() {
+
+            @Override
+            public String getName() {
+                assertFalse(called[0]);
+                called[0] = true;
+                return n;
+            }
+
+            @Override
+            public boolean match(String value) {
+                assertTrue(v.equals(value));
+                return true;
+            }
+        };
+
+        Properties instance = new Properties();
+        instance.setProperty("p1", "1");
+        instance.setProperty(n, v);
+        instance.setProperty("p3", "3");
+        Property result = instance.selectSingle(matcher);
+        assertEquals(result, new Property(n, v));
+
+
+        called[0] = false;
+        PropertyMatcher matcher2 = new PropertyMatcher() {
+
+            @Override
+            public String getName() {
+                assertFalse(called[0]);
+                called[0] = true;
+                return n;
+            }
+
+            @Override
+            public boolean match(String value) {
+                return false;
+            }
+        };
+
+
+        Property result2 = instance.selectSingle(matcher2);
+        assertTrue(result2 == null);
+    }
+
+    /**
+     * Test of get method, of class Properties.
+     */
+    public void testGet() {
+        Properties instance = new Properties();
+        instance.setProperty("p1", "1");
+        assertEquals("1", instance.get("p1"));
+        assertEquals(null, instance.get("p2"));
+    }
+
+    /**
+     * Test of getProperties method, of class Properties.
+     */
+    public void testIterator() {
+        Properties instance = new Properties();
+        instance.setProperty("p1", "1");
+        instance.setProperty("p2", "2");
+        Iterator<Property> result = instance.iterator();
+        assertTrue(result.hasNext());
+        assertEquals(new Property("p1", "1"), result.next());
+        assertTrue(result.hasNext());
+        assertEquals(new Property("p2", "2"), result.next());
+        assertFalse(result.hasNext());
+        assertTrue(result.next() == null);
+
+        try {
+            result.remove();
+            fail();
+        } catch(UnsupportedOperationException e) {}
+    }
+
+    /**
+     * Test of add method, of class Properties.
+     */
+    public void testAdd() {
+        Properties a = new Properties();
+        a.setProperty("p1", "1");
+        a.setProperty("p2", "2");
+
+        Properties b = new Properties();
+        b.setProperty("p1", "1");
+
+        Properties c = new Properties();
+        c.setProperty("p2", "2");
+
+        assertFalse(a.equals(b));
+        b.add(c);
+
+        assertTrue(a.equals(b));
+        
+        b.setProperty("p3", null);
+        assertTrue(a.equals(b));
+    
+        Properties empty = new Properties();
+        b.add(empty);
+        assertTrue(a.equals(b));
+        
+        empty.add(b);
+        assertTrue(a.equals(empty));
+    }
+
+
+    /**
+     * Test the multiple argument constructors.
+     */
+    public void testConstructors() {
+        Properties a = new Properties("p1", "1", "p2", "2", "p3", "3");
+        Properties b = new Properties("p1", "1", "p2", "2");
+        Properties c = new Properties("p1", "1");
+
+        assertTrue(a.get("p3").equals("3"));
+        assertTrue(b.get("p2").equals("2"));
+        assertTrue(b.get("p1").equals("1"));
+
+        b.setProperty("p3", "3");
+        c.setProperty("p2", "2");
+        c.setProperty("p3", "3");
+
+        assertTrue(a.equals(b));
+        assertTrue(a.equals(c));
+    }
+
+    /**
+     * Test Entity class
+     */
+    public void testEntity() {
+
+        Properties p = new Properties();
+
+        Properties.Entity entity = new Properties.Entity();
+        assertEquals(entity.getProperties(), p);
+
+        entity.getProperties().setProperty("p1", "1");
+        Properties.Entity entity2 = new Properties.Entity(entity);
+        assertEquals(entity.getProperties(), entity2.getProperties());
+    }
+
+    /**
+     * Test property selector
+     */
+    public void testPropertySelector() {
+        final Collection<Properties.Entity> c = new ArrayList<>();
+
+        final Properties.Entity e1 = new Properties.Entity();
+        e1.getProperties().setProperty("p1", "1");
+        e1.getProperties().setProperty("p2", "2");
+        c.add(e1);
+
+        final Properties.Entity e2 = new Properties.Entity();
+        e2.getProperties().setProperty("p2", "2");
+        e2.getProperties().setProperty("p1", "1");
+        e2.getProperties().setProperty("p3", "3");
+        c.add(e2);
+
+        final Properties.Entity e3 = new Properties.Entity();
+        e3.getProperties().setProperty("p3", "3");
+        e3.getProperties().setProperty("p4", "4");
+        c.add(e3);
+
+        final PropertySelector<Properties.Entity> sel = new PropertySelector<>(c);
+
+        final StringPropertyMatcher matcher1 = new StringPropertyMatcher("p2", "2");
+        assertTrue(sel.selectMultiple(matcher1).size() == 2);
+        assertTrue(sel.selectMultiple(matcher1).contains(e1));
+        assertTrue(sel.selectMultiple(matcher1).contains(e2));
+        assertTrue(sel.selectSingle(matcher1).equals(e1) || sel.selectSingle(matcher1).equals(e2));
+
+        final StringPropertyMatcher matcher2 = new StringPropertyMatcher("p3", "3");
+        assertTrue(sel.selectMultiple(matcher2).size() == 2);
+        assertTrue(sel.selectMultiple(matcher2).contains(e2));
+        assertTrue(sel.selectMultiple(matcher2).contains(e3));
+        assertTrue(sel.selectSingle(matcher2).equals(e2) || sel.selectSingle(matcher2).equals(e3));
+
+        final StringPropertyMatcher matcher3 = new StringPropertyMatcher("p4", "4");
+        assertTrue(sel.selectMultiple(matcher3).size() == 1);
+        assertTrue(sel.selectMultiple(matcher3).contains(e3));
+        assertTrue(sel.selectSingle(matcher3).equals(e3));
+
+        final StringPropertyMatcher matcher4 = new StringPropertyMatcher("p5", "5");
+        assertTrue(sel.selectMultiple(matcher4).size() == 0);
+        assertTrue(sel.selectSingle(matcher4) == null);
+    }
+
+    public void testRemoveProperty() {
+        final Properties p = new Properties();
+        p.setProperty("p1", "1");
+        p.setProperty("p2", "2");
+
+        assertTrue(p.get("p1").equals("1"));
+        assertTrue(p.get("p2").equals("2"));
+
+        p.setProperty("p1", null);
+        assertTrue(p.get("p1") == null);
+        assertTrue(p.get("p2").equals("2"));
+
+        p.setProperty("p2", null);
+        assertTrue(p.get("p1") == null);
+        assertTrue(p.get("p2") == null);
+
+        p.setProperty("p3", "3");
+        assertTrue(p.get("p1") == null);
+        assertTrue(p.get("p2") == null);
+        assertTrue(p.get("p3").equals("3"));
+    }
+
+    /**
+     * Test property matchers
+     */
+    public void testPropertyMatchers() {
+        final StringPropertyMatcher matcher = new StringPropertyMatcher("p1", "1");
+        assertTrue(matcher.getName().equals("p1"));
+        assertTrue(matcher.match("1"));
+        assertFalse(matcher.match("2"));
+        try {
+            matcher.match(null);
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new StringPropertyMatcher(null, "**");
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new StringPropertyMatcher("p1", null);
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        final RegexpPropertyMatcher matcher2 = new RegexpPropertyMatcher("p1", "C.*");
+        assertTrue(matcher2.getName().equals("p1"));
+        assertTrue(matcher2.match("C"));
+        assertTrue(matcher2.match("Casdf"));
+        assertFalse(matcher2.match(" C"));
+        assertFalse(matcher2.match("c"));
+        assertFalse(matcher2.match("asdfC"));
+        
+        try {
+            matcher2.match(null);
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new RegexpPropertyMatcher("p1", "**");
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new RegexpPropertyMatcher(null, "1");
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new RegexpPropertyMatcher("p1", null);
+            fail();
+        } catch(IllegalArgumentException e) {}
+        
+        final InvertPropertyMatcher matcher3 = new InvertPropertyMatcher(matcher);
+        assertTrue(matcher3.getName().equals("p1"));
+        assertFalse(matcher3.match("1"));
+        assertTrue(matcher3.match("2"));
+        assertFalse(matcher3.match(null));
+    }
+
+    public void testToString() {
+        Properties p = new Properties();
+        assertEquals(p.toString(), "[]");
+
+        p.setProperty("p1", "1");
+        assertEquals(p.toString(), "[p1=1]");
+
+        Properties p2 = new Properties();
+        p2.setProperty("p1", "1");
+        p2.setProperty("p2", "2");
+        assertEquals(p2.toString(), "[p1=1, p2=2]");
+
+        Properties p3 = new Properties();
+        p3.setProperty("p2", "2");
+        p3.setProperty("p1", "1");
+        assertEquals(p3.toString(), "[p1=1, p2=2]");
+        
+        p3.setProperty("p0", "0");
+        assertEquals(p3.toString(), "[p0=0, p1=1, p2=2]");
+
+        p2.setProperty("p1", null);
+        assertEquals(p2.toString(), "[p2=2]");
+
+        p2.setProperty("p2", null);
+        assertEquals(p2.toString(), "[]");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/PropertyTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1998, 2007, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.data;
+
+import static org.junit.Assert.*;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class PropertyTest {
+
+    public PropertyTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getName method, of class Property.
+     */
+    @Test
+    public void testGetNameAndValue() {
+        final Property p = new Property("name", "value");
+        assertEquals(p.getName(), "name");
+        assertEquals(p.getValue(), "value");
+
+        try {
+            new Property(null, "value");
+            fail();
+        } catch(IllegalArgumentException e) {
+        }
+
+
+        try {
+            new Property("name", null);
+            fail();
+        } catch(IllegalArgumentException e) {
+        }
+    }
+
+    /**
+     * Test of toString method, of class Property.
+     */
+    @Test
+    public void testToString() {
+        final Property p = new Property("name", "value");
+        assertEquals(p.toString(), "name=value");
+    }
+
+    /**
+     * Test of equals method, of class Property.
+     */
+    @Test
+    public void testEquals() {
+        final Property p = new Property("name", "value");
+        final Object o = new Object();
+        assertFalse(p.equals(o));
+        assertFalse(p.equals(null));
+        assertTrue(p.equals(p));
+
+        final Property p2 = new Property("name", "value1");
+        assertFalse(p.equals(p2));
+        assertTrue(p.hashCode() != p2.hashCode());
+
+        final Property p3 = new Property("name2", "value");
+        assertFalse(p.equals(p3));
+        assertTrue(p.hashCode() != p3.hashCode());
+        assertTrue(p2.hashCode() != p3.hashCode());
+
+        final Property p4 = new Property("name", "value");
+        assertEquals(p, p4);
+        assertEquals(p.hashCode(), p4.hashCode());
+    
+        final Property p5 = new Property("value", "name");
+        assertFalse(p.equals(p5));
+        assertTrue(p.hashCode() != p5.hashCode());
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/SourceTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * 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.sun.hotspot.igv.data;
+
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import static org.junit.Assert.assertEquals;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas
+ */
+public class SourceTest {
+
+    public SourceTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getSourceNodes method, of class Source.
+     */
+    @Test
+    public void testBase() {
+        final Source s = new Source();
+
+        final InputNode N1 = new InputNode(1);
+        final InputNode N2 = new InputNode(2);
+
+        s.addSourceNode(N1);
+        assertEquals(s.getSourceNodes(), Arrays.asList(N1));
+        assertEquals(s.getSourceNodesAsSet(), new LinkedHashSet<>(Arrays.asList(1)));
+
+        s.addSourceNode(N2);
+        assertEquals(s.getSourceNodes(), Arrays.asList(N1, N2));
+        assertEquals(s.getSourceNodesAsSet(), new LinkedHashSet<>(Arrays.asList(1, 2)));
+
+        s.addSourceNode(N1);
+        assertEquals(s.getSourceNodes(), Arrays.asList(N1, N2));
+        assertEquals(s.getSourceNodesAsSet(), new LinkedHashSet<>(Arrays.asList(1, 2)));
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/Util.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 1998, 2007, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.data;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Util {
+
+    public static void assertGraphDocumentNotEquals(GraphDocument a, GraphDocument b) {
+        try {
+            assertGraphDocumentEquals(a, b);
+        } catch(AssertionError e) {
+            return;
+        }
+
+        fail("Graphs documents are equal!");
+    }
+
+    public static void assertGraphDocumentEquals(GraphDocument a, GraphDocument b) {
+
+        if (a.getElements().size() != b.getElements().size()) {
+            fail();
+        }
+
+        int z = 0;
+        for (FolderElement e : b.getElements()) {
+
+            if (e instanceof Group) {
+                Group g = (Group) e;
+                Group thisG = (Group) a.getElements().get(z);
+                assertGroupEquals(thisG, g);
+            z++;
+            }
+        }
+    }
+
+    public static void assertGroupNotEquals(Group a, Group b) {
+        try {
+            assertGroupEquals(a, b);
+        } catch(AssertionError e) {
+            return;
+        }
+
+        fail("Groups are equal!");
+    }
+
+    public static void assertGroupEquals(Group a, Group b) {
+
+        if (a.getGraphsCount() != b.getGraphsCount()) {
+            fail();
+        }
+
+        int z = 0;
+        for (InputGraph graph : a.getGraphs()) {
+            InputGraph otherGraph = b.getGraphs().get(z);
+            assertGraphEquals(graph, otherGraph);
+            z++;
+        }
+
+        if (a.getMethod() == null || b.getMethod() == null) {
+            if (a.getMethod() != b.getMethod()) {
+                fail();
+            }
+        } else {
+            if (!a.getMethod().equals(b.getMethod())) {
+                fail();
+            }
+        }
+    }
+
+    public static void assertGraphNotEquals(InputGraph a, InputGraph b) {
+        try {
+            assertGraphEquals(a, b);
+        } catch(AssertionError e) {
+            return;
+        }
+
+        fail("Graphs are equal!");
+    }
+
+    public static void assertGraphEquals(InputGraph a, InputGraph b) {
+        
+        if(!a.getNodesAsSet().equals(b.getNodesAsSet())) {
+            fail();
+        }
+        
+        if (!a.getEdges().equals(b.getEdges())) {
+            fail();
+        }
+        
+        if (a.getBlocks().equals(b.getBlocks())) {
+            fail();
+        }
+
+        for (InputNode n : a.getNodes()) {
+            assertEquals(a.getBlock(n), b.getBlock(n));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/serialization/ParserTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 1998, 2007, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.data.serialization;
+
+import com.sun.hotspot.igv.data.*;
+import java.io.CharArrayWriter;
+import java.io.StringReader;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import org.junit.*;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ParserTest {
+
+    public ParserTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    private void test(GraphDocument document) {
+        final Printer printer = new Printer();
+        final CharArrayWriter writer = new CharArrayWriter();
+        printer.export(writer, document);
+        test(document, writer.toString());
+    }
+
+    private void test(GraphDocument document, String xmlString) {
+        
+        StringReader sr = new StringReader(xmlString);
+        InputSource is = new InputSource(sr);
+
+        try {
+            Parser parser = new Parser();
+            final GraphDocument parsedDocument = parser.parse(is, null);
+            Util.assertGraphDocumentEquals(document, parsedDocument);
+        } catch (SAXException ex) {
+            fail(ex.toString());
+        }
+    }
+
+    private void testBoth(GraphDocument document, String xmlString) {
+        test(document);
+        test(document, xmlString);
+    }
+
+    /**
+     * Test of graph document serialization
+     */
+    @Test
+    public void testSerialization() {
+        final GraphDocument doc = new GraphDocument();
+
+        test(doc);
+
+        final Group group1 = new Group(doc);
+        doc.addElement(group1);
+        test(doc);
+
+        final Group group2 = new Group(doc);
+        doc.addElement(group2);
+        test(doc);
+
+        final InputGraph graph = new InputGraph("");
+        group1.addElement(graph);
+        test(doc);
+
+        graph.addNode(new InputNode(0));
+        test(doc);
+
+        graph.addNode(new InputNode(1));
+        test(doc);
+
+        graph.addNode(new InputNode(2));
+        test(doc);
+
+        graph.addNode(new InputNode(3));
+        test(doc);
+
+        graph.addEdge(new InputEdge((char)0, (char)0, 0, 1));
+        test(doc);
+
+        graph.addEdge(new InputEdge((char)1, (char)1, 0, 1));
+        test(doc);
+
+        graph.addEdge(new InputEdge((char)0, (char)0, 1, 2));
+        test(doc);
+        
+        graph.addEdge(new InputEdge((char)0, (char)0, 2, 3));
+        test(doc);
+
+        group1.setMethod(new InputMethod(group1, "testMethod", "tM", 1));
+        test(doc);
+
+        final InputBlock b1 = graph.addBlock("1");
+        b1.addNode(0);
+        b1.addNode(1);
+
+        final InputBlock b2 = graph.addBlock("2");
+        b2.addNode(2);
+        b2.addNode(3);
+        test(doc);
+
+        final GraphDocument document2 = new GraphDocument();
+        doc.addGraphDocument(document2);
+        test(doc);
+        assertTrue(doc.getElements().size() == 2);
+
+        final Group group3 = new Group(document2);
+        document2.addElement(group3);
+        doc.addGraphDocument(document2);
+        assertTrue(doc.getElements().size() == 3);
+        assertTrue(document2.getElements().size() == 0);
+
+        doc.clear();
+        test(doc);
+        Util.assertGraphDocumentEquals(doc, new GraphDocument());
+    }
+
+	@Test
+	public void testSimpleExport() {
+		GraphDocument document = new GraphDocument();
+		Group g = new Group(document);
+		document.addElement(g);
+        
+		InputGraph graph = new InputGraph("TestGraph");
+                g.addElement(graph);
+		graph.getProperties().setProperty("testName", "testValue");
+
+		InputNode n1 = new InputNode(0);
+		InputNode n2 = new InputNode(1);
+		InputEdge e1 = new InputEdge((char)0, 0, 1);
+		InputEdge e2 = new InputEdge((char)1, 0, 1);
+		graph.addNode(n1);
+		graph.addNode(n2);
+		graph.addEdge(e1);
+		graph.addEdge(e2);
+        
+        test(document);
+	}
+
+	@Test
+	public void testComplexExport() {
+
+		GraphDocument document = new GraphDocument();
+		Group g = new Group(document);
+		document.addElement(g);
+
+		InputGraph graph = new InputGraph("TestGraph");
+                g.addElement(graph);
+		graph.getProperties().setProperty("testName", "testValue");
+
+		InputNode n1 = new InputNode(0);
+		InputNode n2 = new InputNode(1);
+		InputEdge e1 = new InputEdge((char)0, 0, 0);
+		InputEdge e2 = new InputEdge((char)1, 1, 1);
+		graph.addNode(n1);
+		graph.addNode(n2);
+		graph.addEdge(e1);
+		graph.addEdge(e2);
+
+		InputGraph graph2 = new InputGraph("TestGraph2");
+                g.addElement(graph2);
+		graph2.addNode(n1);
+		InputNode n3 = new InputNode(2);
+		graph2.addNode(n3);
+		InputEdge e3 = new InputEdge((char)0, 0, 2);
+		graph2.addEdge(e3);
+
+        test(document);
+	}
+
+
+    /**
+     * Test of parse method, of class Parser.
+     */
+    @Test
+    public void testParse() {
+        testBoth(new GraphDocument(), "<graphDocument></graphDocument>");
+    }
+
+}
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/Difference/nbproject/project.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Difference/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/Difference/nbproject/project.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Difference/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -14,6 +14,14 @@
                         <specification-version>1.0</specification-version>
                     </run-dependency>
                 </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
+                    </run-dependency>
+                </dependency>
             </module-dependencies>
             <public-packages>
                 <package>com.sun.hotspot.igv.difference</package>
--- a/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java	Mon Feb 27 13:10:13 2012 +0100
@@ -24,16 +24,11 @@
  */
 package com.sun.hotspot.igv.difference;
 
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.InputEdge;
-import com.sun.hotspot.igv.data.InputGraph;
-import com.sun.hotspot.igv.data.InputNode;
-import com.sun.hotspot.igv.data.Property;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.*;
+import com.sun.hotspot.igv.data.services.Scheduler;
+import java.util.*;
+import org.openide.util.Lookup;
 
 /**
  *
@@ -60,14 +55,14 @@
     }
 
     private static InputGraph createDiffSameGroup(InputGraph a, InputGraph b) {
-        Map<Integer, InputNode> keyMapB = new HashMap<Integer, InputNode>();
+        Map<Integer, InputNode> keyMapB = new HashMap<>(b.getNodes().size());
         for (InputNode n : b.getNodes()) {
             Integer key = n.getId();
             assert !keyMapB.containsKey(key);
             keyMapB.put(key, n);
         }
 
-        Set<Pair> pairs = new HashSet<Pair>();
+        Set<NodePair> pairs = new HashSet<>();
 
         for (InputNode n : a.getNodes()) {
             Integer key = n.getId();
@@ -75,30 +70,92 @@
 
             if (keyMapB.containsKey(key)) {
                 InputNode nB = keyMapB.get(key);
-                pairs.add(new Pair(n, nB));
+                pairs.add(new NodePair(n, nB));
             }
         }
 
         return createDiff(a, b, pairs);
     }
 
-    private static InputGraph createDiff(InputGraph a, InputGraph b, Set<Pair> pairs) {
-        Group g = new Group();
+    private static void ensureScheduled(InputGraph a) {
+        if (a.getBlocks().isEmpty()) {
+            Scheduler s = Lookup.getDefault().lookup(Scheduler.class);
+            a.clearBlocks();
+            s.schedule(a);
+            a.ensureNodesInBlocks();
+        }
+    }
+
+    private static InputGraph createDiff(InputGraph a, InputGraph b, Set<NodePair> pairs) {
+        ensureScheduled(a);
+        ensureScheduled(b);
+
+        Group g = new Group(null);
         g.setMethod(a.getGroup().getMethod());
-        g.setAssembly(a.getGroup().getAssembly());
+        if (a.getGroup() == b.getGroup()) {
+            g.getProperties().add(a.getGroup().getProperties());
+        } else {
+            // copy properties that have the same value in both groups
+            Properties bps = b.getGroup().getProperties();
+            for (Property p : a.getGroup().getProperties()) {
+                String value = p.getValue();
+                if (value != null && value.equals(bps.get(p.getName()))) {
+                    g.getProperties().setProperty(p.getName(), value);
+                }
+            }
+        }
         g.getProperties().setProperty("name", "Difference");
-        InputGraph graph = new InputGraph(g, null);
-        graph.setName(a.getName() + ", " + b.getName());
-        graph.setIsDifferenceGraph(true);
+        InputGraph graph = new InputGraph(a.getName() + ", " + b.getName());
+        g.addElement(graph);
 
-        Set<InputNode> nodesA = new HashSet<InputNode>(a.getNodes());
-        Set<InputNode> nodesB = new HashSet<InputNode>(b.getNodes());
+        Map<InputBlock, InputBlock> blocksMap = new HashMap<>();
+        for (InputBlock blk : a.getBlocks()) {
+            InputBlock diffblk = graph.addBlock(blk.getName());
+            blocksMap.put(blk, diffblk);
+        }
+        for (InputBlock blk : b.getBlocks()) {
+            InputBlock diffblk = graph.getBlock(blk.getName());
+            if (diffblk == null) {
+                diffblk = graph.addBlock(blk.getName());
+            }
+            blocksMap.put(blk, diffblk);
+        }
 
-        Map<InputNode, InputNode> inputNodeMap = new HashMap<InputNode, InputNode>();
-        for (Pair p : pairs) {
-            InputNode n = p.getN1();
+        // Difference between block edges
+        Set<Pair<String, String>> aEdges = new HashSet<>();
+        for (InputBlockEdge edge : a.getBlockEdges()) {
+            aEdges.add(new Pair<>(edge.getFrom().getName(), edge.getTo().getName()));
+        }
+        for (InputBlockEdge bEdge : b.getBlockEdges()) {
+            InputBlock from = bEdge.getFrom();
+            InputBlock to = bEdge.getTo();
+            Pair<String, String> pair = new Pair<>(from.getName(), to.getName());
+            if (aEdges.contains(pair)) {
+                // same
+                graph.addBlockEdge(blocksMap.get(from), blocksMap.get(to));
+                aEdges.remove(pair);
+            } else {
+                // added
+                InputBlockEdge edge = graph.addBlockEdge(blocksMap.get(from), blocksMap.get(to));
+                edge.setState(InputBlockEdge.State.NEW);
+            }
+        }
+        for (Pair<String, String> deleted : aEdges) {
+            // removed
+            InputBlock from = graph.getBlock(deleted.getLeft());
+            InputBlock to = graph.getBlock(deleted.getRight());
+            InputBlockEdge edge = graph.addBlockEdge(from, to);
+            edge.setState(InputBlockEdge.State.DELETED);
+        }
+
+        Set<InputNode> nodesA = new HashSet<>(a.getNodes());
+        Set<InputNode> nodesB = new HashSet<>(b.getNodes());
+
+        Map<InputNode, InputNode> inputNodeMap = new HashMap<>(pairs.size());
+        for (NodePair p : pairs) {
+            InputNode n = p.getLeft();
             assert nodesA.contains(n);
-            InputNode nB = p.getN2();
+            InputNode nB = p.getRight();
             assert nodesB.contains(nB);
 
             nodesA.remove(n);
@@ -107,39 +164,53 @@
             inputNodeMap.put(n, n2);
             inputNodeMap.put(nB, n2);
             graph.addNode(n2);
+            InputBlock block = blocksMap.get(a.getBlock(n));
+            block.addNode(n2.getId());
             markAsChanged(n2, n, nB);
         }
 
         for (InputNode n : nodesA) {
             InputNode n2 = new InputNode(n);
             graph.addNode(n2);
-            markAsNew(n2);
+            InputBlock block = blocksMap.get(a.getBlock(n));
+            block.addNode(n2.getId());
+            markAsDeleted(n2);
             inputNodeMap.put(n, n2);
         }
 
+        int curIndex = 0;
         for (InputNode n : nodesB) {
             InputNode n2 = new InputNode(n);
-            n2.setId(-n2.getId());
+
+            // Find new ID for node of b, does not change the id property
+            while (graph.getNode(curIndex) != null) {
+                curIndex++;
+            }
+
+            n2.setId(curIndex);
             graph.addNode(n2);
-            markAsDeleted(n2);
+            InputBlock block = blocksMap.get(b.getBlock(n));
+            block.addNode(n2.getId());
+            markAsNew(n2);
             inputNodeMap.put(n, n2);
         }
 
         Collection<InputEdge> edgesA = a.getEdges();
         Collection<InputEdge> edgesB = b.getEdges();
 
-        Set<InputEdge> newEdges = new HashSet<InputEdge>();
+        Set<InputEdge> newEdges = new HashSet<>();
 
         for (InputEdge e : edgesA) {
             int from = e.getFrom();
             int to = e.getTo();
             InputNode nodeFrom = inputNodeMap.get(a.getNode(from));
             InputNode nodeTo = inputNodeMap.get(a.getNode(to));
-            char index = e.getToIndex();
+            char fromIndex = e.getFromIndex();
+            char toIndex = e.getToIndex();
 
-            InputEdge newEdge = new InputEdge(index, nodeFrom.getId(), nodeTo.getId());
+            InputEdge newEdge = new InputEdge(fromIndex, toIndex, nodeFrom.getId(), nodeTo.getId());
             if (!newEdges.contains(newEdge)) {
-                markAsNew(newEdge);
+                markAsDeleted(newEdge);
                 newEdges.add(newEdge);
                 graph.addEdge(newEdge);
             }
@@ -150,11 +221,12 @@
             int to = e.getTo();
             InputNode nodeFrom = inputNodeMap.get(b.getNode(from));
             InputNode nodeTo = inputNodeMap.get(b.getNode(to));
-            char index = e.getToIndex();
+            char fromIndex = e.getFromIndex();
+            char toIndex = e.getToIndex();
 
-            InputEdge newEdge = new InputEdge(index, nodeFrom.getId(), nodeTo.getId());
+            InputEdge newEdge = new InputEdge(fromIndex, toIndex, nodeFrom.getId(), nodeTo.getId());
             if (!newEdges.contains(newEdge)) {
-                markAsDeleted(newEdge);
+                markAsNew(newEdge);
                 newEdges.add(newEdge);
                 graph.addEdge(newEdge);
             } else {
@@ -166,24 +238,20 @@
             }
         }
 
-        g.addGraph(graph);
         return graph;
     }
 
-    private static class Pair {
+    private static class NodePair extends Pair<InputNode, InputNode> {
+
 
-        private InputNode n1;
-        private InputNode n2;
-
-        public Pair(InputNode n1, InputNode n2) {
-            this.n1 = n1;
-            this.n2 = n2;
+        public NodePair(InputNode n1, InputNode n2) {
+            super(n1, n2);
         }
 
         public double getValue() {
 
             double result = 0.0;
-            for (Property p : n1.getProperties()) {
+            for (Property p : getLeft().getProperties()) {
                 double faktor = 1.0;
                 for (String forbidden : IGNORE_PROPERTIES) {
                     if (p.getName().equals(forbidden)) {
@@ -191,7 +259,7 @@
                         break;
                     }
                 }
-                String p2 = n2.getProperties().get(p.getName());
+                String p2 = getRight().getProperties().get(p.getName());
                 result += evaluate(p.getValue(), p2) * faktor;
             }
 
@@ -208,21 +276,13 @@
                 return (double) (Math.abs(p.length() - p2.length())) / p.length() + 0.5;
             }
         }
-
-        public InputNode getN1() {
-            return n1;
-        }
-
-        public InputNode getN2() {
-            return n2;
-        }
     }
 
     private static InputGraph createDiff(InputGraph a, InputGraph b) {
 
-        Set<InputNode> matched = new HashSet<InputNode>();
+        Set<InputNode> matched = new HashSet<>();
 
-        Set<Pair> pairs = new HashSet<Pair>();
+        Set<NodePair> pairs = new HashSet<>();
         for (InputNode n : a.getNodes()) {
             String s = n.getProperties().get(MAIN_PROPERTY);
             if (s == null) {
@@ -235,18 +295,18 @@
                 }
 
                 if (s.equals(s2)) {
-                    Pair p = new Pair(n, n2);
+                    NodePair p = new NodePair(n, n2);
                     pairs.add(p);
                 }
             }
         }
 
-        Set<Pair> selectedPairs = new HashSet<Pair>();
+        Set<NodePair> selectedPairs = new HashSet<>();
         while (pairs.size() > 0) {
 
             double min = Double.MAX_VALUE;
-            Pair minPair = null;
-            for (Pair p : pairs) {
+            NodePair minPair = null;
+            for (NodePair p : pairs) {
                 double cur = p.getValue();
                 if (cur < min) {
                     minPair = p;
@@ -259,9 +319,9 @@
             } else {
                 selectedPairs.add(minPair);
 
-                Set<Pair> toRemove = new HashSet<Pair>();
-                for (Pair p : pairs) {
-                    if (p.getN1() == minPair.getN1() || p.getN2() == minPair.getN2()) {
+                Set<NodePair> toRemove = new HashSet<>();
+                for (NodePair p : pairs) {
+                    if (p.getLeft() == minPair.getLeft() || p.getRight() == minPair.getRight()) {
                         toRemove.add(p);
                     }
                 }
--- a/src/share/tools/IdealGraphVisualizer/Filter/nbproject/project.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/Filter/nbproject/project.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -23,12 +23,28 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
+                    <code-name-base>com.sun.hotspot.igv.layout</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
                     <code-name-base>org.jdesktop.layout</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
                         <release-version>1</release-version>
-                        <specification-version>1.4.1</specification-version>
+                        <specification-version>1.16.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.30.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -36,7 +52,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.5.1</specification-version>
+                        <specification-version>7.18.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -44,7 +60,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.3</specification-version>
+                        <specification-version>7.46.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -52,7 +68,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.2.0.1</specification-version>
+                        <specification-version>7.20.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -60,7 +76,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.9.0.1</specification-version>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -68,7 +92,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.16</specification-version>
+                        <specification-version>6.39.1</specification-version>
                     </run-dependency>
                 </dependency>
             </module-dependencies>
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/META-INF/services/com.sun.hotspot.igv.filter.ScriptEngineAbstraction	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-com.sun.hotspot.igv.filter.JavaSE6ScriptEngine
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/AbstractFilter.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/AbstractFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -42,14 +42,17 @@
         properties = new Properties();
     }
 
+    @Override
     public Properties getProperties() {
         return properties;
     }
 
+    @Override
     public OpenCookie getEditor() {
         return null;
     }
 
+    @Override
     public ChangedEvent<Filter> getChangedEvent() {
         return changedEvent;
     }
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/ColorFilter.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/ColorFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,13 +23,9 @@
  */
 package com.sun.hotspot.igv.filter;
 
-import com.sun.hotspot.igv.graph.Connection;
+import com.sun.hotspot.igv.data.Properties;
 import com.sun.hotspot.igv.graph.Connection.ConnectionStyle;
-import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.OutputSlot;
-import com.sun.hotspot.igv.graph.Selector;
-import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.graph.*;
 import java.awt.Color;
 import java.util.ArrayList;
 import java.util.List;
@@ -45,16 +41,18 @@
 
     public ColorFilter(String name) {
         this.name = name;
-        colorRules = new ArrayList<ColorRule>();
+        colorRules = new ArrayList<>();
     }
 
+    @Override
     public String getName() {
         return name;
     }
 
+    @Override
     public void apply(Diagram diagram) {
 
-        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(diagram.getFigures());
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(diagram.getFigures());
         for (ColorRule rule : colorRules) {
             if (rule.getSelector() != null) {
                 List<Figure> figures = rule.getSelector().selected(diagram);
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CombineFilter.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CombineFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,13 +23,9 @@
  */
 package com.sun.hotspot.igv.filter;
 
-import com.sun.hotspot.igv.graph.Connection;
-import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.InputSlot;
-import com.sun.hotspot.igv.graph.OutputSlot;
 import com.sun.hotspot.igv.data.Properties;
 import com.sun.hotspot.igv.data.Properties.PropertyMatcher;
+import com.sun.hotspot.igv.graph.*;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -46,23 +42,25 @@
 
     public CombineFilter(String name) {
         this.name = name;
-        rules = new ArrayList<CombineRule>();
+        rules = new ArrayList<>();
     }
 
+    @Override
     public String getName() {
         return name;
     }
 
+    @Override
     public void apply(Diagram diagram) {
 
-        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(diagram.getFigures());
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(diagram.getFigures());
         for (CombineRule r : rules) {
 
             List<Figure> list = selector.selectMultiple(r.getFirstMatcher());
-            Set<Figure> figuresToRemove = new HashSet<Figure>();
+            Set<Figure> figuresToRemove = new HashSet<>();
             for (Figure f : list) {
 
-                List<Figure> successors = new ArrayList<Figure>(f.getSuccessors());
+                List<Figure> successors = new ArrayList<>(f.getSuccessors());
                 if (r.isReversed()) {
                     if (successors.size() == 1) {
                         Figure succ = successors.get(0);
@@ -76,21 +74,30 @@
                             }
                         }
 
-                        assert slot != null;
-                        slot.setName(f.getProperties().get("dump_spec"));
-                        if (f.getProperties().get("short_name") != null) {
-                            slot.setShortName(f.getProperties().get("short_name"));
+                        slot.getSource().addSourceNodes(f.getSource());
+                        if (r.getShortProperty() != null) {
+                            String s = f.getProperties().get(r.getShortProperty());
+                            if (s != null && s.length() > 0) {
+                                slot.setShortName(s);
+                                slot.setText(s);
+                                slot.setColor(f.getColor());
+                            }
                         } else {
-                            String s = f.getProperties().get("dump_spec");
-                            if (s != null && s.length() <= 5) {
-                                slot.setShortName(s);
+                            assert slot != null;
+                            slot.setText(f.getProperties().get("dump_spec"));
+                            if (f.getProperties().get("short_name") != null) {
+                                slot.setShortName(f.getProperties().get("short_name"));
+                            } else {
+                                String s = f.getProperties().get("dump_spec");
+                                if (s != null && s.length() <= 5) {
+                                    slot.setShortName(s);
+                                }
                             }
-
                         }
 
                         for (InputSlot s : f.getInputSlots()) {
                             for (Connection c : s.getConnections()) {
-                                Connection newConn = diagram.createConnection(slot, c.getOutputSlot());
+                                Connection newConn = diagram.createConnection(slot, c.getOutputSlot(), c.getLabel());
                                 newConn.setColor(c.getColor());
                                 newConn.setStyle(c.getStyle());
                             }
@@ -101,7 +108,7 @@
                 } else {
 
                     for (Figure succ : successors) {
-                        if (succ.getPredecessors().size() == 1) {
+                        if (succ.getPredecessors().size() == 1 && succ.getInputSlots().size() == 1) {
                             if (succ.getProperties().selectSingle(r.getSecondMatcher()) != null && succ.getOutputSlots().size() == 1) {
 
 
@@ -122,22 +129,32 @@
                                     pos = Integer.parseInt(succ.getProperties().get("con"));
                                 }
                                 OutputSlot slot = f.createOutputSlot(pos);
-                                slot.setName(succ.getProperties().get("dump_spec"));
-                                if (succ.getProperties().get("short_name") != null) {
-                                    slot.setShortName(succ.getProperties().get("short_name"));
+                                slot.getSource().addSourceNodes(succ.getSource());
+                                if (r.getShortProperty() != null) {
+                                    String s = succ.getProperties().get(r.getShortProperty());
+                                    if (s != null && s.length() > 0) {
+                                        slot.setShortName(s);
+                                        slot.setText(s);
+                                        slot.setColor(succ.getColor());
+                                    }
                                 } else {
-                                    String s = succ.getProperties().get("dump_spec");
-                                    if (s != null && s.length() <= 2) {
-                                        slot.setShortName(s);
+                                    slot.setText(succ.getProperties().get("dump_spec"));
+                                    if (succ.getProperties().get("short_name") != null) {
+                                        slot.setShortName(succ.getProperties().get("short_name"));
                                     } else {
-                                        String tmpName = succ.getProperties().get("name");
-                                        if (tmpName != null && tmpName.length() > 0) {
-                                            slot.setShortName(tmpName.substring(0, 1));
+                                        String s = succ.getProperties().get("dump_spec");
+                                        if (s != null && s.length() <= 2) {
+                                            slot.setShortName(s);
+                                        } else {
+                                            String tmpName = succ.getProperties().get("name");
+                                            if (tmpName != null && tmpName.length() > 0) {
+                                                slot.setShortName(tmpName.substring(0, 1));
+                                            }
                                         }
                                     }
                                 }
                                 for (Connection c : nextSlot.getConnections()) {
-                                    Connection newConn = diagram.createConnection(c.getInputSlot(), slot);
+                                    Connection newConn = diagram.createConnection(c.getInputSlot(), slot, c.getLabel());
                                     newConn.setColor(c.getColor());
                                     newConn.setStyle(c.getStyle());
                                 }
@@ -167,6 +184,7 @@
         private PropertyMatcher first;
         private PropertyMatcher second;
         private boolean reversed;
+        private String shortProperty;
 
         public CombineRule(PropertyMatcher first, PropertyMatcher second) {
             this(first, second, false);
@@ -174,9 +192,14 @@
         }
 
         public CombineRule(PropertyMatcher first, PropertyMatcher second, boolean reversed) {
+            this(first, second, reversed, null);
+        }
+
+        public CombineRule(PropertyMatcher first, PropertyMatcher second, boolean reversed, String shortProperty) {
             this.first = first;
             this.second = second;
             this.reversed = reversed;
+            this.shortProperty = shortProperty;
         }
 
         public boolean isReversed() {
@@ -190,5 +213,9 @@
         public PropertyMatcher getSecondMatcher() {
             return second;
         }
+
+        public String getShortProperty() {
+            return shortProperty;
+        }
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/ConnectionFilter.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/ConnectionFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,12 +23,8 @@
  */
 package com.sun.hotspot.igv.filter;
 
-import com.sun.hotspot.igv.graph.Connection;
-import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.OutputSlot;
-import com.sun.hotspot.igv.graph.Selector;
 import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.graph.*;
 import java.awt.Color;
 import java.util.ArrayList;
 import java.util.List;
@@ -44,16 +40,18 @@
 
     public ConnectionFilter(String name) {
         this.name = name;
-        connectionStyleRules = new ArrayList<ConnectionStyleRule>();
+        connectionStyleRules = new ArrayList<>();
     }
 
+    @Override
     public String getName() {
         return name;
     }
 
+    @Override
     public void apply(Diagram diagram) {
 
-        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(diagram.getFigures());
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(diagram.getFigures());
         for (ConnectionStyleRule rule : connectionStyleRules) {
             List<Figure> figures = null;
             if (rule.getSelector() != null) {
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CustomFilter.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CustomFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -29,17 +29,13 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.util.Collection;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import org.openide.DialogDisplayer;
-import org.openide.NotifyDescriptor;
+import javax.script.*;
 import org.openide.cookies.OpenCookie;
-import org.openide.filesystems.Repository;
-import org.openide.filesystems.FileSystem;
 import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
 import org.openide.util.Exceptions;
-import org.openide.util.Lookup;
 
 /**
  *
@@ -48,7 +44,6 @@
 public class CustomFilter extends AbstractFilter {
 
     public static final String JAVASCRIPT_HELPER_ID = "JavaScriptHelper";
-    private static ScriptEngineAbstraction engine;
     private String code;
     private String name;
 
@@ -58,6 +53,7 @@
         getProperties().setProperty("name", name);
     }
 
+    @Override
     public String getName() {
         return name;
     }
@@ -80,6 +76,7 @@
     public OpenCookie getEditor() {
         return new OpenCookie() {
 
+            @Override
             public void open() {
                 openInEditor();
             }
@@ -89,7 +86,9 @@
     public boolean openInEditor() {
         EditFilterDialog dialog = new EditFilterDialog(CustomFilter.this);
         dialog.setVisible(true);
-        return dialog.wasAccepted();
+        boolean result = dialog.wasAccepted();
+        this.getChangedEvent().fire();
+        return result;
     }
 
     @Override
@@ -97,41 +96,11 @@
         return getName();
     }
 
-    public static ScriptEngineAbstraction getEngine() {
-        if (engine == null) {
-
-            ScriptEngineAbstraction chosen = null;
-            try {
-                Collection<? extends ScriptEngineAbstraction> list = Lookup.getDefault().lookupAll(ScriptEngineAbstraction.class);
-                for (ScriptEngineAbstraction s : list) {
-                    if (s.initialize(getJsHelperText())) {
-                        if (chosen == null || !(chosen instanceof JavaSE6ScriptEngine)) {
-                            chosen = s;
-                        }
-                    }
-                }
-            } catch (NoClassDefFoundError ncdfe) {
-                Logger.getLogger("global").log(Level.SEVERE, null, ncdfe);
-            }
-
-            if (chosen == null) {
-                NotifyDescriptor message = new NotifyDescriptor.Message("Could not find a scripting engine. Please make sure that the Rhino scripting engine is available. Otherwise filter cannot be used.", NotifyDescriptor.ERROR_MESSAGE);
-                DialogDisplayer.getDefault().notifyLater(message);
-                chosen = new NullScriptEngine();
-            }
-
-            engine = chosen;
-        }
-
-        return engine;
-    }
-
     private static String getJsHelperText() {
         InputStream is = null;
         StringBuilder sb = new StringBuilder("importPackage(Packages.com.sun.hotspot.igv.filter);importPackage(Packages.com.sun.hotspot.igv.graph);importPackage(Packages.com.sun.hotspot.igv.data);importPackage(Packages.com.sun.hotspot.igv.util);importPackage(java.awt);");
         try {
-            FileSystem fs = Repository.getDefault().getDefaultFileSystem();
-            FileObject fo = fs.getRoot().getFileObject(JAVASCRIPT_HELPER_ID);
+            FileObject fo = FileUtil.getConfigRoot().getFileObject(JAVASCRIPT_HELPER_ID);
             is = fo.getInputStream();
             BufferedReader r = new BufferedReader(new InputStreamReader(is));
             String s;
@@ -152,7 +121,18 @@
         return sb.toString();
     }
 
+    @Override
     public void apply(Diagram d) {
-        getEngine().execute(d, code);
+        try {
+            ScriptEngineManager sem = new ScriptEngineManager();
+            ScriptEngine e = sem.getEngineByName("ECMAScript");
+            e.eval(getJsHelperText());
+            Bindings b = e.getContext().getBindings(ScriptContext.ENGINE_SCOPE);
+            b.put("graph", d);
+            b.put("IO", System.out);
+            e.eval(code, b);
+        } catch (ScriptException ex) {
+            Exceptions.printStackTrace(ex);
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/EdgeColorIndexFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,77 @@
+/*
+ * 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.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.graph.*;
+import java.awt.Color;
+import java.util.List;
+
+public class EdgeColorIndexFilter extends AbstractFilter {
+
+    public static final String INPUTS = "INPUTS";
+    public static final String OUTPUTS = "OUTPUTS";
+    private final String applyTo;
+    private final Color[] colors;
+
+    public EdgeColorIndexFilter(String applyTo, Color... color) {
+        if (!applyTo.equals(INPUTS) && !applyTo.equals(OUTPUTS)) {
+            throw new IllegalArgumentException("applyTo");
+        }
+
+        this.applyTo = applyTo;
+        this.colors = color;
+    }
+
+    @Override
+    public String getName() {
+        return "Edge Color Index Filter";
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        List<Figure> figures = d.getFigures();
+        for (Figure f : figures) {
+            Slot[] slots;
+            if (applyTo.equals(INPUTS)) {
+                List<InputSlot> inputSlots = f.getInputSlots();
+                slots = inputSlots.toArray(new Slot[inputSlots.size()]);
+            } else {
+                List<OutputSlot> outputSlots = f.getOutputSlots();
+                slots = outputSlots.toArray(new Slot[outputSlots.size()]);
+            }
+            int index = 0;
+            for (Slot slot : slots) {
+                if (index < colors.length && colors[index] != null) {
+                    slot.setColor(colors[index]);
+                    for (Connection c : slot.getConnections()) {
+
+                        c.setColor(colors[index]);
+                    }
+                }
+                index++;
+            }
+
+        }
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/EditFilterDialog.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/EditFilterDialog.java	Mon Feb 27 13:10:13 2012 +0100
@@ -137,17 +137,17 @@
     }// </editor-fold>//GEN-END:initComponents
 
 private void okButtonClicked(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonClicked
-        this.customFilter.setName(this.nameTextField.getText());
-        this.customFilter.setCode(this.sourceTextArea.getText());
-        accepted = true;
-        setVisible(false);
+	this.customFilter.setName(this.nameTextField.getText());
+	this.customFilter.setCode(this.sourceTextArea.getText());
+	accepted = true;
+	setVisible(false);
 }//GEN-LAST:event_okButtonClicked
 
 private void cancelButtonClicked(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonClicked
-        setVisible(false);
+	setVisible(false);
 }//GEN-LAST:event_cancelButtonClicked
-
-
+	
+	
     // Variables declaration - do not modify//GEN-BEGIN:variables
     private javax.swing.JButton cancelButton;
     private javax.swing.JScrollPane jScrollPane1;
@@ -157,5 +157,5 @@
     private javax.swing.JLabel sourceLabel;
     private javax.swing.JTextArea sourceTextArea;
     // End of variables declaration//GEN-END:variables
-
+	
 }
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/Filter.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/Filter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -41,5 +41,6 @@
 
     OpenCookie getEditor();
 
+    @Override
     ChangedEvent<Filter> getChangedEvent();
 }
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/FilterChain.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/FilterChain.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,9 +23,10 @@
  */
 package com.sun.hotspot.igv.filter;
 
-import com.sun.hotspot.igv.graph.Diagram;
 import com.sun.hotspot.igv.data.ChangedEvent;
 import com.sun.hotspot.igv.data.ChangedEventProvider;
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.graph.Diagram;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -38,20 +39,25 @@
 
     private List<Filter> filters;
     private transient ChangedEvent<FilterChain> changedEvent;
-    private boolean fireEvents;
+    
+    private ChangedListener<Filter> changedListener = new ChangedListener<Filter>() {
+        @Override
+        public void changed(Filter source) {
+            changedEvent.fire();
+        }
+    };
 
     public FilterChain() {
-        filters = new ArrayList<Filter>();
-        changedEvent = new ChangedEvent<FilterChain>(this);
-        this.fireEvents = true;
+        filters = new ArrayList<>();
+        changedEvent = new ChangedEvent<>(this);
     }
 
     public FilterChain(FilterChain f) {
-        this.filters = new ArrayList<Filter>(f.filters);
-        changedEvent = new ChangedEvent<FilterChain>(this);
-        this.fireEvents = true;
+        this.filters = new ArrayList<>(f.filters);
+        changedEvent = new ChangedEvent<>(this);
     }
 
+    @Override
     public ChangedEvent<FilterChain> getChangedEvent() {
         return changedEvent;
     }
@@ -68,7 +74,7 @@
     }
 
     public void apply(Diagram d, FilterChain sequence) {
-        List<Filter> applied = new ArrayList<Filter>();
+        List<Filter> applied = new ArrayList<>();
         for (Filter f : sequence.getFilters()) {
             if (filters.contains(f)) {
                 f.apply(d);
@@ -84,29 +90,12 @@
         }
     }
 
-    public void beginAtomic() {
-        this.fireEvents = false;
-    }
-
-    public void endAtomic() {
-        this.fireEvents = true;
-        changedEvent.fire();
-    }
 
     public void addFilter(Filter filter) {
         assert filter != null;
         filters.add(filter);
-        if (fireEvents) {
-            changedEvent.fire();
-        }
-    }
-
-    public void addFilterSameSequence(Filter filter) {
-        assert filter != null;
-        filters.add(filter);
-        if (fireEvents) {
-            changedEvent.fire();
-        }
+        filter.getChangedEvent().addListener(changedListener);
+        changedEvent.fire();
     }
 
     public boolean containsFilter(Filter filter) {
@@ -116,9 +105,8 @@
     public void removeFilter(Filter filter) {
         assert filters.contains(filter);
         filters.remove(filter);
-        if (fireEvents) {
-            changedEvent.fire();
-        }
+        filter.getChangedEvent().removeListener(changedListener);
+        changedEvent.fire();
     }
 
     public void moveFilterUp(Filter filter) {
@@ -128,9 +116,7 @@
             filters.remove(index);
             filters.add(index - 1, filter);
         }
-        if (fireEvents) {
-            changedEvent.fire();
-        }
+        changedEvent.fire();
     }
 
     public void moveFilterDown(Filter filter) {
@@ -140,16 +126,10 @@
             filters.remove(index);
             filters.add(index + 1, filter);
         }
-        if (fireEvents) {
-            changedEvent.fire();
-        }
+        changedEvent.fire();
     }
 
     public List<Filter> getFilters() {
         return Collections.unmodifiableList(filters);
     }
-
-    public void clear() {
-        filters.clear();
-    }
 }
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/FilterSetting.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/FilterSetting.java	Mon Feb 27 13:10:13 2012 +0100
@@ -42,7 +42,7 @@
 
     public FilterSetting(String name) {
         this.name = name;
-        filters = new HashSet<Filter>();
+        filters = new HashSet<>();
     }
 
     public Set<Filter> getFilters() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/GradientColorFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,161 @@
+/*
+ * 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.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.Figure;
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import java.awt.image.Raster;
+import java.util.List;
+
+/**
+ * Filter that colors nodes using a customizable color gradient, based on how
+ * a numeric property is located in a specified interval.
+ * 
+ * @author Peter Hofer
+ */
+public class GradientColorFilter extends AbstractFilter {
+
+    public static final String LINEAR = "LINEAR";
+    public static final String LOGARITHMIC = "LOGARITHMIC";
+
+    private String propertyName = "probability";
+    private float minValue = 0;
+    private float maxValue = 500;
+    private float[] fractions = {0, 0.5f, 1};
+    private Color[] colors = {Color.BLUE, Color.YELLOW, Color.RED};
+    private int shadeCount = 8;
+    private String mode = LINEAR;
+
+    @Override
+    public String getName() {
+        return "Gradient Color Filter";
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        boolean logarithmic = mode.equalsIgnoreCase(LOGARITHMIC);
+        if (!logarithmic && !mode.equalsIgnoreCase(LINEAR)) {
+            throw new RuntimeException("Unknown mode: " + mode);
+        }
+
+        Rectangle bounds = new Rectangle(shadeCount, 1);
+        LinearGradientPaint lgp = new LinearGradientPaint(bounds.x, bounds.y, bounds.width, bounds.y, fractions, colors);
+        PaintContext context = lgp.createContext(null, bounds, bounds.getBounds2D(), AffineTransform.getTranslateInstance(0, 0), new RenderingHints(null));
+        Raster raster = context.getRaster(bounds.x, bounds.y, bounds.width, bounds.height);
+        int[] rgb = raster.getPixels(bounds.x, bounds.y, bounds.width, bounds.height, (int[]) null);
+        Color[] shades = new Color[rgb.length / 3];
+        for (int i = 0; i < shades.length; ++i) {
+            shades[i] = new Color(rgb[i * 3], rgb[i * 3 + 1], rgb[i * 3 + 2]);
+        }
+
+        List<Figure> figures = d.getFigures();
+        for (Figure f : figures) {
+            String property = f.getProperties().get(propertyName);
+            if (property != null) {
+                try {
+                    float value = Float.parseFloat(property);
+
+                    Color nodeColor;
+                    if (value <= minValue) {
+                        nodeColor = colors[0];
+                    } else if (value >= maxValue) {
+                        nodeColor = colors[colors.length - 1];
+                    } else {
+                        double normalized = value - minValue;
+                        double interval = maxValue - minValue;
+                        int index;
+                        // Use Math.ceil() to make values above zero distinguishable from zero
+                        if (logarithmic) {
+                            index = (int) Math.ceil(shades.length * Math.log(1 + normalized) / Math.log(1 + interval));
+                        } else {
+                            index = (int) Math.ceil(shades.length * normalized / interval);
+                        }
+                        nodeColor = shades[index];
+                    }
+                    f.setColor(nodeColor);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    public String getPropertyName() {
+        return propertyName;
+    }
+
+    public void setPropertyName(String propertyName) {
+        this.propertyName = propertyName;
+    }
+
+    public float getMinValue() {
+        return minValue;
+    }
+
+    public void setMinValue(float minValue) {
+        this.minValue = minValue;
+    }
+
+    public float getMaxValue() {
+        return maxValue;
+    }
+
+    public void setMaxValue(float maxValue) {
+        this.maxValue = maxValue;
+    }
+
+    public float[] getFractions() {
+        return fractions;
+    }
+
+    public void setFractions(float[] fractions) {
+        this.fractions = fractions;
+    }
+
+    public Color[] getColors() {
+        return colors;
+    }
+
+    public void setColors(Color[] colors) {
+        this.colors = colors;
+    }
+
+    public int getShadeCount() {
+        return shadeCount;
+    }
+
+    public void setShadeCount(int shadeCount) {
+        this.shadeCount = shadeCount;
+    }
+
+    public String getMode() {
+        return mode;
+    }
+
+    public void setMode(String mode) {
+        this.mode = mode;
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/JavaSE6ScriptEngine.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.sun.hotspot.igv.filter;
-
-import com.sun.hotspot.igv.graph.Diagram;
-import javax.script.Bindings;
-import javax.script.ScriptContext;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
-import org.openide.util.Exceptions;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class JavaSE6ScriptEngine implements ScriptEngineAbstraction {
-
-    private ScriptEngine engine;
-    private Bindings bindings;
-
-    public boolean initialize(String jsHelperText) {
-        try {
-            ScriptEngineManager sem = new ScriptEngineManager();
-            ScriptEngine e = sem.getEngineByName("ECMAScript");
-            engine = e;
-            e.eval(jsHelperText);
-            Bindings b = e.getContext().getBindings(ScriptContext.ENGINE_SCOPE);
-            b.put("IO", System.out);
-            bindings = b;
-            return true;
-        } catch (Exception e) {
-            return false;
-        }
-    }
-
-    public void execute(Diagram d, String code) {
-        try {
-            Bindings b = bindings;
-            b.put("graph", d);
-            engine.eval(code, b);
-        } catch (ScriptException ex) {
-            Exceptions.printStackTrace(ex);
-        }
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/NullScriptEngine.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.filter;
-
-import com.sun.hotspot.igv.graph.Diagram;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class NullScriptEngine implements ScriptEngineAbstraction {
-
-    public boolean initialize(String jsHelperText) {
-        return true;
-    }
-
-    public void execute(Diagram d, String code) {
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveFilter.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -25,9 +25,7 @@
 
 import com.sun.hotspot.igv.graph.Diagram;
 import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.InputSlot;
 import com.sun.hotspot.igv.graph.Selector;
-import com.sun.hotspot.igv.data.Properties;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -44,56 +42,36 @@
 
     public RemoveFilter(String name) {
         this.name = name;
-        rules = new ArrayList<RemoveRule>();
+        rules = new ArrayList<>();
     }
 
+    @Override
     public String getName() {
         return name;
     }
 
+    @Override
     public void apply(Diagram diagram) {
-
         for (RemoveRule r : rules) {
+            List<Figure> selected = r.getSelector().selected(diagram);
+            Set<Figure> toRemove = new HashSet<>(selected);
 
-            List<Figure> list = r.getSelector().selected(diagram);
-            Set<Figure> figuresToRemove = new HashSet<Figure>();
-
-            List<Figure> protectedFigures = null;
-            if (r.getRemoveAllWithoutPredecessor()) {
-                protectedFigures = diagram.getRootFigures();
+            if (r.getRemoveOrphans()) {
+                boolean changed;
+                do {
+                    changed = false;
+                    for (Figure f : diagram.getFigures()) {
+                        if (!toRemove.contains(f)) {
+                            if (toRemove.containsAll(f.getPredecessors()) && toRemove.containsAll(f.getSuccessors())) {
+                                toRemove.add(f);
+                                changed = true;
+                            }
+                        }
+                    }
+                } while (changed);
             }
 
-            for (Figure f : list) {
-                if (r.getRemoveOnlyInputs()) {
-                    List<InputSlot> inputSlots = new ArrayList<InputSlot>();
-                    for (InputSlot is : f.getInputSlots()) {
-                        inputSlots.add(is);
-                    }
-                    for (InputSlot is : inputSlots) {
-                        f.removeSlot(is);
-                    }
-
-                    f.createInputSlot();
-                } else {
-                    figuresToRemove.add(f);
-                }
-            }
-
-            if (r.getRemoveAllWithoutPredecessor()) {
-                boolean progress = true;
-                while (progress) {
-                    List<Figure> rootFigures = diagram.getRootFigures();
-                    progress = false;
-                    for (Figure f : rootFigures) {
-                        if (!protectedFigures.contains(f)) {
-                            figuresToRemove.add(f);
-                            progress = true;
-                        }
-                    }
-                }
-            }
-
-            diagram.removeAllFigures(figuresToRemove);
+            diagram.removeAllFigures(toRemove);
         }
     }
 
@@ -104,29 +82,23 @@
     public static class RemoveRule {
 
         private Selector selector;
-        private boolean removeAllWithoutPredecessor;
-        private boolean removeOnlyInputs;
+        private boolean removeOrphans;
 
-        public RemoveRule(Selector selector, boolean b) {
-            this(selector, b, false);
+        public RemoveRule(Selector selector) {
+            this(selector, false);
         }
 
-        public RemoveRule(Selector selector, boolean removeAllWithoutPredecessor, boolean removeOnlyInputs) {
+        public RemoveRule(Selector selector, boolean removeOrphans) {
             this.selector = selector;
-            this.removeOnlyInputs = removeOnlyInputs;
-            this.removeAllWithoutPredecessor = removeAllWithoutPredecessor;
+            this.removeOrphans = removeOrphans;
         }
 
         public Selector getSelector() {
             return selector;
         }
 
-        public boolean getRemoveOnlyInputs() {
-            return removeOnlyInputs;
-        }
-
-        public boolean getRemoveAllWithoutPredecessor() {
-            return removeAllWithoutPredecessor;
+        public boolean getRemoveOrphans() {
+            return removeOrphans;
         }
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveInputsFilter.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveInputsFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,12 +23,7 @@
  */
 package com.sun.hotspot.igv.filter;
 
-import com.sun.hotspot.igv.graph.Connection;
-import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.InputSlot;
-import com.sun.hotspot.igv.graph.OutputSlot;
-import com.sun.hotspot.igv.graph.Selector;
+import com.sun.hotspot.igv.graph.*;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -43,13 +38,15 @@
 
     public RemoveInputsFilter(String name) {
         this.name = name;
-        rules = new ArrayList<RemoveInputsRule>();
+        rules = new ArrayList<>();
     }
 
+    @Override
     public String getName() {
         return name;
     }
 
+    @Override
     public void apply(Diagram diagram) {
 
         for (RemoveInputsRule r : rules) {
@@ -57,7 +54,7 @@
             List<Figure> list = r.getSelector().selected(diagram);
             for (Figure f : list) {
                 int z = 0;
-                List<InputSlot> last = new ArrayList<InputSlot>();
+                List<InputSlot> last = new ArrayList<>();
                 for (InputSlot is : f.getInputSlots()) {
                     if (z >= r.getStartingIndex() && z <= r.getEndIndex() && is.getConnections().size() > 0) {
                         StringBuilder sb = new StringBuilder();
@@ -73,7 +70,7 @@
                         }
                         is.removeAllConnections();
                         is.setShortName("X");
-                        is.setName(sb.toString());
+                        is.setText(sb.toString());
                         last.add(is);
                     } else {
                         last.clear();
@@ -91,10 +88,10 @@
                         if (i != 0) {
                             sb.append("<BR>");
                         }
-                        sb.append(is2.getName());
+                        sb.append(is2.getText());
                     }
 
-                    first.setName(sb.toString());
+                    first.setText(sb.toString());
 
                     for (int i = 1; i < last.size(); i++) {
                         f.removeSlot(last.get(i));
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveSelfLoopsFilter.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveSelfLoopsFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,11 +23,7 @@
  */
 package com.sun.hotspot.igv.filter;
 
-import com.sun.hotspot.igv.graph.Connection;
-import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.InputSlot;
-import com.sun.hotspot.igv.graph.OutputSlot;
+import com.sun.hotspot.igv.graph.*;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -44,17 +40,19 @@
         this.name = name;
     }
 
+    @Override
     public String getName() {
         return name;
     }
 
+    @Override
     public void apply(Diagram d) {
 
         for (Figure f : d.getFigures()) {
 
             for (InputSlot is : f.getInputSlots()) {
 
-                List<Connection> toRemove = new ArrayList<Connection>();
+                List<Connection> toRemove = new ArrayList<>();
                 for (Connection c : is.getConnections()) {
 
                     if (c.getOutputSlot().getFigure() == f) {
@@ -72,7 +70,7 @@
                     }
 
                     c.getInputSlot().setShortName("O");
-                    c.getInputSlot().setName("Self Loop");
+                    c.getInputSlot().setText("Self Loop");
                 }
             }
         }
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/ScriptEngineAbstraction.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.sun.hotspot.igv.filter;
-
-import com.sun.hotspot.igv.graph.Diagram;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public interface ScriptEngineAbstraction {
-
-    public boolean initialize(String jsHelperText);
-
-    public void execute(Diagram d, String code);
-}
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/SplitFilter.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/SplitFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,12 +23,7 @@
  */
 package com.sun.hotspot.igv.filter;
 
-import com.sun.hotspot.igv.graph.Connection;
-import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.InputSlot;
-import com.sun.hotspot.igv.graph.OutputSlot;
-import com.sun.hotspot.igv.graph.Selector;
+import com.sun.hotspot.igv.graph.*;
 import java.util.List;
 
 /**
@@ -39,25 +34,52 @@
 
     private String name;
     private Selector selector;
+    private String propertyName;
 
-    public SplitFilter(String name, Selector selector) {
+    public SplitFilter(String name, Selector selector, String propertyName) {
         this.name = name;
         this.selector = selector;
+        this.propertyName = propertyName;
     }
 
+    @Override
     public String getName() {
         return name;
     }
-
+    
+    @Override
     public void apply(Diagram d) {
         List<Figure> list = selector.selected(d);
 
         for (Figure f : list) {
+            
+            for (InputSlot is : f.getInputSlots()) {
+                for (Connection c : is.getConnections()) {
+                    OutputSlot os = c.getOutputSlot();
+                    if (f.getSource().getSourceNodes().size() > 0) {
+                        os.getSource().addSourceNodes(f.getSource());
+                        os.setAssociatedNode(f.getSource().getSourceNodes().get(0));
+                        os.setColor(f.getColor());
+                    }
+
+
+                    String s = Figure.resolveString(propertyName, f.getProperties());
+                    if (s != null) {
+                        os.setShortName(s);
+                    }
+
+                }
+            }
             for (OutputSlot os : f.getOutputSlots()) {
                 for (Connection c : os.getConnections()) {
                     InputSlot is = c.getInputSlot();
-                    is.setName(f.getProperties().get("dump_spec"));
-                    String s = f.getProperties().get("short_name");
+                    if (f.getSource().getSourceNodes().size() > 0) {
+                        is.getSource().addSourceNodes(f.getSource());
+                        is.setAssociatedNode(f.getSource().getSourceNodes().get(0));
+                        is.setColor(f.getColor());
+                    }
+
+                    String s = Figure.resolveString(propertyName, f.getProperties());
                     if (s != null) {
                         is.setShortName(s);
                     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/UnconnectedSlotFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,76 @@
+/*
+ * 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.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.graph.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Filter that hides slots with no connections.
+ */
+public class UnconnectedSlotFilter extends AbstractFilter {
+
+    private final boolean removeInputs;
+    private final boolean removeOutputs;
+
+    public UnconnectedSlotFilter(boolean inputs, boolean outputs) {
+        this.removeInputs = inputs;
+        this.removeOutputs = outputs;
+    }
+
+    @Override
+    public String getName() {
+        return "Unconnected Slot Filter";
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        if (!removeInputs && !removeOutputs) {
+            return;
+        }
+
+        List<Figure> figures = d.getFigures();
+        for (Figure f : figures) {
+            List<Slot> remove = new ArrayList<>();
+            if (removeInputs) {
+                for (InputSlot is : f.getInputSlots()) {
+                    if (is.getConnections().isEmpty()) {
+                        remove.add(is);
+                    }
+                }
+            }
+            if (removeOutputs) {
+                for (OutputSlot os : f.getOutputSlots()) {
+                    if (os.getConnections().isEmpty()) {
+                        remove.add(os);
+                    }
+                }
+            }
+            for (Slot s : remove) {
+                f.removeSlot(s);
+            }
+        }
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/helper.js	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/helper.js	Mon Feb 27 13:10:13 2012 +0100
@@ -21,26 +21,35 @@
  * questions.
  *
  */
-
+ 
  /**
  *
  * @author Thomas Wuerthinger
  */
-
+ 
 function colorize(property, regexp, color) {
     var f = new ColorFilter("");
     f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), color));
-    f.apply(graph);
+    f.apply(graph); 
 }
 
 function remove(property, regexp) {
     var f = new RemoveFilter("");
-    f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), false, false));
+    f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp))));
     f.apply(graph);
 }
 
-function split(property, regexp) {
-    var f = new SplitFilter("", new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)));
+function removeIncludingOrphans(property, regexp) {
+    var f = new RemoveFilter("");
+    f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), true));
+    f.apply(graph);
+}
+
+function split(property, regexp, propertyName) {
+    if (propertyName == undefined) {
+        propertyName = graph.getNodeText();
+    }
+    var f = new SplitFilter("", new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), propertyName);
     f.apply(graph);
 }
 
@@ -56,6 +65,40 @@
     f.apply(graph);
 }
 
+function removeUnconnectedSlots(inputs, outputs) {
+    var f = new UnconnectedSlotFilter(inputs, outputs);
+    f.apply(graph);
+}
+
+function colorizeGradient(property, min, max) {
+    var f = new GradientColorFilter();
+    f.setPropertyName(property);
+    f.setMinValue(min);
+    f.setMaxValue(max);
+    f.apply(graph);
+}
+
+function colorizeGradientWithMode(property, min, max, mode) {
+    var f = new GradientColorFilter();
+    f.setPropertyName(property);
+    f.setMinValue(min);
+    f.setMaxValue(max);
+    f.setMode(mode);
+    f.apply(graph);
+}
+
+function colorizeGradientCustom(property, min, max, mode, colors, fractions, nshades) {
+    var f = new GradientColorFilter();
+    f.setPropertyName(property);
+    f.setMinValue(min);
+    f.setMaxValue(max);
+    f.setMode(mode);
+    f.setColors(colors);
+    f.setFractions(fractions);
+    f.setShadeCount(nshades);
+    f.apply(graph);
+}
+
 var black = Color.black;
 var blue = Color.blue;
 var cyan = Color.cyan;
@@ -68,4 +111,4 @@
 var pink = Color.pink
 var red = Color.red;
 var yellow = Color.yellow;
-var white = Color.white;
+var white = Color.white;
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/build-impl.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -4,6 +4,13 @@
 ***         EDIT ../build.xml INSTEAD         ***
 -->
 <project name="com.sun.hotspot.igv.filterwindow-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
     <property file="nbproject/private/suite-private.properties"/>
     <property file="nbproject/suite.properties"/>
     <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
@@ -16,13 +23,21 @@
             <property name="@{name}" value="${@{value}}"/>
         </sequential>
     </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
     <property file="${user.properties.file}"/>
     <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
-    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
-    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
         <condition>
             <not>
-                <available file="${harness.dir}" type="dir"/>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
             </not>
         </condition>
     </fail>
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/genfiles.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,8 +1,5 @@
-build.xml.data.CRC32=401b2654
-build.xml.script.CRC32=9c158403
-build.xml.stylesheet.CRC32=79c3b980
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=401b2654
-nbproject/build-impl.xml.script.CRC32=19fb08e0
-nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
+nbproject/build-impl.xml.data.CRC32=09ba2a87
+nbproject/build-impl.xml.script.CRC32=e4293f0e
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.45.1
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/project.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/project.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -43,7 +43,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.6.1.1</specification-version>
+                        <specification-version>6.21.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -51,7 +51,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.5.1</specification-version>
+                        <specification-version>7.18.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -59,7 +59,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.12.1</specification-version>
+                        <specification-version>6.34.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -67,7 +67,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.3.1</specification-version>
+                        <specification-version>7.46.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -75,7 +75,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.7.1</specification-version>
+                        <specification-version>7.20.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -83,7 +83,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.2.1.1</specification-version>
+                        <specification-version>7.20.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -91,7 +91,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.10.1.1</specification-version>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -99,7 +107,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.18.1</specification-version>
+                        <specification-version>6.39.1</specification-version>
                     </run-dependency>
                 </dependency>
             </module-dependencies>
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/Bundle.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,3 +1,3 @@
 OpenIDE-Module-Name=FilterWindow
-CTL_FilterTopComponent=Filter Window
-HINT_FilterTopComponent=This is a Filter window
+CTL_FilterTopComponent=Filters
+HINT_FilterTopComponent=Allows to choose active filters and modify them.
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckListView.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckListView.java	Mon Feb 27 13:10:13 2012 +0100
@@ -44,8 +44,8 @@
     }
 
     @Override
-    protected JList createList() {
-        JList tmpList = super.createList();
+    protected JList<Object> createList() {
+        JList<Object> tmpList = super.createList();
         tmpList.setCellRenderer(new CheckRenderer(tmpList));
         return tmpList;
     }
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckNode.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -40,7 +40,7 @@
 
     public CheckNode(Children c, Lookup lookup) {
         super(c, lookup);
-        selectionChangedEvent = new ChangedEvent<CheckNode>(this);
+        selectionChangedEvent = new ChangedEvent<>(this);
         selected = false;
         enabled = true;
     }
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckNodeListModel.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckNodeListModel.java	Mon Feb 27 13:10:13 2012 +0100
@@ -24,7 +24,7 @@
 package com.sun.hotspot.igv.filterwindow;
 
 import org.openide.explorer.view.NodeListModel;
-import org.openide.nodes.Node;
+import org.openide.explorer.view.Visualizer;
 
 /**
  *
@@ -32,15 +32,11 @@
  */
 public class CheckNodeListModel extends NodeListModel {
 
-    private Node rootNode;
-
-    @Override
-    public void setNode(Node rootNode) {
-        this.rootNode = rootNode;
-        super.setNode(rootNode);
-    }
-
     public CheckNode getCheckNodeAt(int index) {
-        return (CheckNode) rootNode.getChildren().getNodes()[index];
+        Object item = getElementAt(index);
+        if (item != null) {
+            return (CheckNode) Visualizer.findNode(item);
+        }
+        return null;
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckRenderer.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckRenderer.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,11 +23,7 @@
  */
 package com.sun.hotspot.igv.filterwindow;
 
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.Point;
-import java.awt.Rectangle;
+import java.awt.*;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import javax.swing.JCheckBox;
@@ -37,12 +33,12 @@
 /**
  * @author Thomas Wuerthinger
  */
-public class CheckRenderer extends JCheckBox implements ListCellRenderer {
+public class CheckRenderer extends JCheckBox implements ListCellRenderer<Object> {
 
-    private JList list;
+    private JList<Object> list;
     private Color startBackground;
 
-    public CheckRenderer(final JList list) {
+    public CheckRenderer(final JList<Object> list) {
         this.list = list;
         list.addMouseListener(
                 new MouseAdapter() {
@@ -65,7 +61,8 @@
         startBackground = this.getBackground();
     }
 
-    public Component getListCellRendererComponent(final JList list, Object value, final int index, boolean isSelected, boolean cellHasFocus) {
+    @Override
+    public Component getListCellRendererComponent(final JList<? extends Object> list, Object value, final int index, boolean isSelected, boolean cellHasFocus) {
         setText(value.toString());
         CheckNode node = ((CheckNodeListModel) list.getModel()).getCheckNodeAt(index);
         this.setSelected(node.isSelected());
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterChainProviderImplementation.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterChainProviderImplementation.java	Mon Feb 27 13:10:13 2012 +0100
@@ -32,10 +32,12 @@
  */
 public class FilterChainProviderImplementation implements FilterChainProvider {
 
+    @Override
     public FilterChain getFilterChain() {
         return FilterTopComponent.findInstance().getFilterChain();
     }
 
+    @Override
     public FilterChain getSequence() {
         return FilterTopComponent.findInstance().getSequence();
     }
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterNode.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,12 +23,12 @@
  */
 package com.sun.hotspot.igv.filterwindow;
 
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.filter.Filter;
+import com.sun.hotspot.igv.filter.FilterChain;
 import com.sun.hotspot.igv.filterwindow.actions.MoveFilterDownAction;
 import com.sun.hotspot.igv.filterwindow.actions.MoveFilterUpAction;
 import com.sun.hotspot.igv.filterwindow.actions.RemoveFilterAction;
-import com.sun.hotspot.igv.filter.Filter;
-import com.sun.hotspot.igv.filter.FilterChain;
-import com.sun.hotspot.igv.data.ChangedListener;
 import com.sun.hotspot.igv.util.PropertiesSheet;
 import javax.swing.Action;
 import org.openide.actions.OpenAction;
@@ -48,7 +48,7 @@
 public class FilterNode extends CheckNode implements LookupListener, ChangedListener<FilterTopComponent> {
 
     private Filter filter;
-    private Lookup.Result result;
+    private Lookup.Result<FilterChain> result;
 
     public FilterNode(Filter filter) {
         this(filter, new InstanceContent());
@@ -62,6 +62,7 @@
         this.filter = filter;
         filter.getChangedEvent().addListener(new ChangedListener<Filter>() {
 
+            @Override
             public void changed(Filter source) {
                 update();
             }
@@ -69,12 +70,14 @@
 
         update();
 
-        Lookup.Template<FilterChain> tpl = new Lookup.Template<FilterChain>(FilterChain.class);
+        Lookup.Template<FilterChain> tpl = new Lookup.Template<>(FilterChain.class);
         result = Utilities.actionsGlobalContext().lookup(tpl);
         result.addLookupListener(this);
 
         FilterTopComponent.findInstance().getFilterSettingsChangedEvent().addListener(this);
         resultChanged(null);
+        
+        setShortDescription("Double-click to open filter");
     }
 
     private void update() {
@@ -102,10 +105,12 @@
         return OpenAction.get(OpenAction.class).createContextAwareInstance(Utilities.actionsGlobalContext());
     }
 
+    @Override
     public void resultChanged(LookupEvent lookupEvent) {
         changed(FilterTopComponent.findInstance());
     }
 
+    @Override
     public void changed(FilterTopComponent source) {
         setSelected(source.getFilterChain().containsFilter(filter));
     }
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponent.form	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponent.form	Mon Feb 27 13:10:13 2012 +0100
@@ -3,6 +3,8 @@
 <Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
   <AuxValues>
     <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
     <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponent.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponent.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,68 +23,41 @@
  */
 package com.sun.hotspot.igv.filterwindow;
 
-import com.sun.hotspot.igv.filterwindow.actions.MoveFilterDownAction;
-import com.sun.hotspot.igv.filterwindow.actions.MoveFilterUpAction;
-import com.sun.hotspot.igv.filterwindow.actions.NewFilterAction;
-import com.sun.hotspot.igv.filterwindow.actions.RemoveFilterAction;
-import com.sun.hotspot.igv.filterwindow.actions.RemoveFilterSettingsAction;
-import com.sun.hotspot.igv.filterwindow.actions.SaveFilterSettingsAction;
+import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.data.ChangedListener;
 import com.sun.hotspot.igv.filter.CustomFilter;
 import com.sun.hotspot.igv.filter.Filter;
 import com.sun.hotspot.igv.filter.FilterChain;
 import com.sun.hotspot.igv.filter.FilterSetting;
-import com.sun.hotspot.igv.data.ChangedEvent;
-import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.filterwindow.actions.*;
 import java.awt.BorderLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.io.BufferedReader;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Serializable;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.io.*;
+import java.util.*;
 import javax.swing.JComboBox;
 import javax.swing.UIManager;
 import javax.swing.border.Border;
 import org.openide.DialogDisplayer;
 import org.openide.ErrorManager;
 import org.openide.NotifyDescriptor;
+import org.openide.awt.Toolbar;
 import org.openide.awt.ToolbarPool;
 import org.openide.explorer.ExplorerManager;
 import org.openide.explorer.ExplorerUtils;
+import org.openide.filesystems.FileLock;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
 import org.openide.nodes.AbstractNode;
 import org.openide.nodes.Children;
 import org.openide.nodes.Node;
-import org.openide.util.Exceptions;
-import org.openide.util.Lookup;
-import org.openide.util.LookupEvent;
-import org.openide.util.LookupListener;
-import org.openide.util.NbBundle;
-import org.openide.util.Utilities;
-import org.openide.awt.Toolbar;
-import org.openide.filesystems.FileLock;
+import org.openide.util.*;
 import org.openide.util.actions.SystemAction;
 import org.openide.windows.TopComponent;
 import org.openide.windows.WindowManager;
-import org.openide.filesystems.Repository;
-import org.openide.filesystems.FileSystem;
-import org.openide.filesystems.FileObject;
 
 /**
- *
+ * 
  * @author Thomas Wuerthinger
  */
 public final class FilterTopComponent extends TopComponent implements LookupListener, ExplorerManager.Provider {
@@ -98,13 +71,14 @@
     private ExplorerManager manager;
     private FilterChain filterChain;
     private FilterChain sequence;
-    private Lookup.Result result;
+    private Lookup.Result<FilterChain> result;
     private JComboBox comboBox;
     private List<FilterSetting> filterSettings;
     private FilterSetting customFilterSetting = new FilterSetting("-- Custom --");
     private ChangedEvent<FilterTopComponent> filterSettingsChangedEvent;
     private ActionListener comboBoxActionListener = new ActionListener() {
 
+        @Override
         public void actionPerformed(ActionEvent e) {
             comboBoxSelectionChanged();
         }
@@ -139,8 +113,8 @@
 
         if (s != customFilterSetting) {
             FilterChain chain = getFilterChain();
-            chain.beginAtomic();
-            List<Filter> toRemove = new ArrayList<Filter>();
+            chain.getChangedEvent().beginAtomic();
+            List<Filter> toRemove = new ArrayList<>();
             for (Filter f : chain.getFilters()) {
                 if (!s.containsFilter(f)) {
                     toRemove.add(f);
@@ -156,7 +130,7 @@
                 }
             }
 
-            chain.endAtomic();
+            chain.getChangedEvent().endAtomic();
             filterSettingsChangedEvent.fire();
         } else {
             this.updateComboBoxSelection();
@@ -177,14 +151,14 @@
     }
 
     public void addFilterSetting() {
-        NotifyDescriptor.InputLine l = new NotifyDescriptor.InputLine("Enter a name:", "Filter");
+        NotifyDescriptor.InputLine l = new NotifyDescriptor.InputLine("Name of the new profile:", "Filter Profile");
         if (DialogDisplayer.getDefault().notify(l) == NotifyDescriptor.OK_OPTION) {
             String name = l.getInputText();
 
             FilterSetting toRemove = null;
             for (FilterSetting s : filterSettings) {
                 if (s.getName().equals(name)) {
-                    NotifyDescriptor.Confirmation conf = new NotifyDescriptor.Confirmation("Filter \"" + name + "\" already exists, to you want to overwrite?", "Filter");
+                    NotifyDescriptor.Confirmation conf = new NotifyDescriptor.Confirmation("Filter profile \"" + name + "\" already exists, do you want to replace it?", "Filter");
                     if (DialogDisplayer.getDefault().notify(conf) == NotifyDescriptor.YES_OPTION) {
                         toRemove = s;
                         break;
@@ -203,6 +177,7 @@
             // Sort alphabetically
             Collections.sort(filterSettings, new Comparator<FilterSetting>() {
 
+                @Override
                 public int compare(FilterSetting o1, FilterSetting o2) {
                     return o1.getName().compareTo(o2.getName());
                 }
@@ -223,7 +198,7 @@
             FilterSetting f = (FilterSetting) o;
             assert f != customFilterSetting;
             assert filterSettings.contains(f);
-            NotifyDescriptor.Confirmation l = new NotifyDescriptor.Confirmation("Do you really want to remove filter \"" + f + "\"?", "Filter");
+            NotifyDescriptor.Confirmation l = new NotifyDescriptor.Confirmation("Do you really want to remove filter profile \"" + f + "\"?", "Filter Profile");
             if (DialogDisplayer.getDefault().notify(l) == NotifyDescriptor.YES_OPTION) {
                 filterSettings.remove(f);
                 updateComboBox();
@@ -267,28 +242,26 @@
         }
     }
 
-    private class FilterChildren extends Children.Keys implements ChangedListener<CheckNode> {
+    private class FilterChildren extends Children.Keys<Filter> implements ChangedListener<CheckNode> {
+
+        private HashMap<Filter, Node> nodeHash = new HashMap<>();
 
-        //private Node[] oldSelection;
-        //private ArrayList<Node> newSelection;
-        private HashMap<Object, Node> nodeHash = new HashMap<Object, Node>();
-
-        protected Node[] createNodes(Object object) {
-            if (nodeHash.containsKey(object)) {
-                return new Node[]{nodeHash.get(object)};
+        @Override
+        protected Node[] createNodes(Filter filter) {
+            if (nodeHash.containsKey(filter)) {
+                return new Node[]{nodeHash.get(filter)};
             }
 
-            assert object instanceof Filter;
-            Filter filter = (Filter) object;
-            com.sun.hotspot.igv.filterwindow.FilterNode node = new com.sun.hotspot.igv.filterwindow.FilterNode(filter);
+            FilterNode node = new FilterNode(filter);
             node.getSelectionChangedEvent().addListener(this);
-            nodeHash.put(object, node);
+            nodeHash.put(filter, node);
             return new Node[]{node};
         }
 
         public FilterChildren() {
             sequence.getChangedEvent().addListener(new ChangedListener<FilterChain>() {
 
+                @Override
                 public void changed(FilterChain source) {
                     addNotify();
                 }
@@ -297,11 +270,13 @@
             setBefore(false);
         }
 
+        @Override
         protected void addNotify() {
             setKeys(sequence.getFilters());
             updateSelection();
         }
 
+        @Override
         public void changed(CheckNode source) {
             FilterNode node = (FilterNode) source;
             Filter f = node.getFilter();
@@ -322,16 +297,11 @@
     }
 
     public FilterChain getFilterChain() {
-        return filterChain;/*
-    EditorTopComponent tc = EditorTopComponent.getActive();
-    if (tc == null) {
-    return filterChain;
-    }
-    return tc.getFilterChain();*/
+        return filterChain;
     }
 
     private FilterTopComponent() {
-        filterSettingsChangedEvent = new ChangedEvent<FilterTopComponent>(this);
+        filterSettingsChangedEvent = new ChangedEvent<>(this);
         initComponents();
         setName(NbBundle.getMessage(FilterTopComponent.class, "CTL_FilterTopComponent"));
         setToolTipText(NbBundle.getMessage(FilterTopComponent.class, "HINT_FilterTopComponent"));
@@ -355,13 +325,13 @@
         toolBar.add(SaveFilterSettingsAction.get(SaveFilterSettingsAction.class));
         toolBar.add(RemoveFilterSettingsAction.get(RemoveFilterSettingsAction.class));
         toolBar.addSeparator();
+        toolBar.add(NewFilterAction.get(NewFilterAction.class));
+        toolBar.add(RemoveFilterAction.get(RemoveFilterAction.class).createContextAwareInstance(this.getLookup()));
         toolBar.add(MoveFilterUpAction.get(MoveFilterUpAction.class).createContextAwareInstance(this.getLookup()));
         toolBar.add(MoveFilterDownAction.get(MoveFilterDownAction.class).createContextAwareInstance(this.getLookup()));
-        toolBar.add(RemoveFilterAction.get(RemoveFilterAction.class).createContextAwareInstance(this.getLookup()));
-        toolBar.add(NewFilterAction.get(NewFilterAction.class));
         this.add(view, BorderLayout.CENTER);
 
-        filterSettings = new ArrayList<FilterSetting>();
+        filterSettings = new ArrayList<>();
         updateComboBox();
 
         comboBox.addActionListener(comboBoxActionListener);
@@ -401,6 +371,7 @@
             filter = cf;
         }
 
+        @Override
         public void changed(Filter source) {
             try {
                 if (!fileObject.getName().equals(filter.getName())) {
@@ -409,15 +380,14 @@
                     lock.releaseLock();
                     FileObject newFileObject = fileObject.getParent().getFileObject(filter.getName());
                     fileObject = newFileObject;
-
                 }
 
                 FileLock lock = fileObject.lock();
                 OutputStream os = fileObject.getOutputStream(lock);
-                Writer w = new OutputStreamWriter(os);
-                String s = filter.getCode();
-                w.write(s);
-                w.close();
+                try (Writer w = new OutputStreamWriter(os)) {
+                    String s = filter.getCode();
+                    w.write(s);
+                }
                 lock.releaseLock();
 
             } catch (IOException ex) {
@@ -427,15 +397,13 @@
     }
 
     public void initFilters() {
-
-        FileSystem fs = Repository.getDefault().getDefaultFileSystem();
-        FileObject folder = fs.getRoot().getFileObject(FOLDER_ID);
+        FileObject folder = FileUtil.getConfigRoot().getFileObject(FOLDER_ID);
         FileObject[] children = folder.getChildren();
 
-        List<CustomFilter> customFilters = new ArrayList<CustomFilter>();
-        HashMap<CustomFilter, String> afterMap = new HashMap<CustomFilter, String>();
-        Set<CustomFilter> enabledSet = new HashSet<CustomFilter>();
-        HashMap<String, CustomFilter> map = new HashMap<String, CustomFilter>();
+        List<CustomFilter> customFilters = new ArrayList<>();
+        HashMap<CustomFilter, String> afterMap = new HashMap<>();
+        Set<CustomFilter> enabledSet = new HashSet<>();
+        HashMap<String, CustomFilter> map = new HashMap<>();
 
         for (final FileObject fo : children) {
             InputStream is = null;
@@ -447,13 +415,12 @@
                 is = fo.getInputStream();
                 BufferedReader r = new BufferedReader(new InputStreamReader(is));
                 String s;
-                StringBuffer sb = new StringBuffer();
+                StringBuilder sb = new StringBuilder();
                 while ((s = r.readLine()) != null) {
                     sb.append(s);
                     sb.append("\n");
                 }
                 code = sb.toString();
-
             } catch (FileNotFoundException ex) {
                 Exceptions.printStackTrace(ex);
             } catch (IOException ex) {
@@ -488,7 +455,7 @@
 
         for (int j = 0; j < customFilters.size(); j++) {
             for (int i = 0; i < customFilters.size(); i++) {
-                List<CustomFilter> copiedList = new ArrayList<CustomFilter>(customFilters);
+                List<CustomFilter> copiedList = new ArrayList<>(customFilters);
                 for (CustomFilter cf : copiedList) {
 
                     String after = afterMap.get(cf);
@@ -573,7 +540,7 @@
 
     @Override
     public void componentOpened() {
-        Lookup.Template<FilterChain> tpl = new Lookup.Template<FilterChain>(FilterChain.class);
+        Lookup.Template<FilterChain> tpl = new Lookup.Template<>(FilterChain.class);
         result = Utilities.actionsGlobalContext().lookup(tpl);
         result.addLookupListener(this);
     }
@@ -584,13 +551,9 @@
         result = null;
     }
 
+    @Override
     public void resultChanged(LookupEvent lookupEvent) {
         setChain(Utilities.actionsGlobalContext().lookup(FilterChain.class));
-    /*
-    EditorTopComponent tc = EditorTopComponent.getActive();
-    if (tc != null) {
-    setChain(tc.getFilterChain());
-    }*/
     }
 
     public void setChain(FilterChain chain) {
@@ -598,10 +561,10 @@
     }
 
     private FileObject getFileObject(CustomFilter cf) {
-        FileObject fo = Repository.getDefault().getDefaultFileSystem().getRoot().getFileObject(FOLDER_ID + "/" + cf.getName());
+        FileObject fo = FileUtil.getConfigRoot().getFileObject(FOLDER_ID + "/" + cf.getName());
         if (fo == null) {
             try {
-                fo = org.openide.filesystems.Repository.getDefault().getDefaultFileSystem().getRoot().getFileObject(FOLDER_ID).createData(cf.getName());
+                fo = FileUtil.getConfigRoot().getFileObject(FOLDER_ID).createData(cf.getName());
             } catch (IOException ex) {
                 Exceptions.printStackTrace(ex);
             }
@@ -610,6 +573,24 @@
     }
 
     @Override
+    public boolean requestFocus(boolean temporary) {
+        view.requestFocus();
+        return super.requestFocus(temporary);
+    }
+
+    @Override
+    protected boolean requestFocusInWindow(boolean temporary) {
+        view.requestFocus();
+        return super.requestFocusInWindow(temporary);
+    }
+
+    @Override
+    public void requestActive() {
+        super.requestActive();
+        view.requestFocus();
+    }
+
+    @Override
     public void writeExternal(ObjectOutput out) throws IOException {
         super.writeExternal(out);
 
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/Bundle.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,10 +1,7 @@
-# To change this template, choose Tools | Templates
-# and open the template in the editor.
-
-CTL_FilterAction=Open Filter Window
+CTL_FilterAction=Filters
+CTL_MoveFilterUpAction=Move upwards
 CTL_MoveFilterDownAction=Move downwards
-CTL_MoveFilterUpAction=Move upwards
-CTL_NewFilterAction=New filter...
 CTL_RemoveFilterAction=Remove
 CTL_RemoveFilterSettingsAction=Remove filter setting
-CTL_SaveFilterSettingsAction=Save filter settings...
+CTL_SaveFilterSettingsAction=Create filter profile...
+CTL_NewFilterAction=New filter...
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/FilterAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/FilterAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,7 +23,7 @@
  */
 package com.sun.hotspot.igv.filterwindow.actions;
 
-import com.sun.hotspot.igv.filterwindow.*;
+import com.sun.hotspot.igv.filterwindow.FilterTopComponent;
 import java.awt.event.ActionEvent;
 import javax.swing.AbstractAction;
 import org.openide.util.NbBundle;
@@ -39,6 +39,7 @@
         super(NbBundle.getMessage(FilterAction.class, "CTL_FilterAction"));
     }
 
+    @Override
     public void actionPerformed(ActionEvent evt) {
         TopComponent win = FilterTopComponent.findInstance();
         win.open();
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/MoveFilterDownAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/MoveFilterDownAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,8 +23,8 @@
  */
 package com.sun.hotspot.igv.filterwindow.actions;
 
+import com.sun.hotspot.igv.filter.Filter;
 import com.sun.hotspot.igv.filterwindow.FilterTopComponent;
-import com.sun.hotspot.igv.filter.Filter;
 import javax.swing.Action;
 import org.openide.nodes.Node;
 import org.openide.util.HelpCtx;
@@ -37,6 +37,7 @@
  */
 public final class MoveFilterDownAction extends CookieAction {
 
+    @Override
     protected void performAction(Node[] activatedNodes) {
         for (Node n : activatedNodes) {
             Filter c = n.getLookup().lookup(Filter.class);
@@ -44,19 +45,22 @@
         }
     }
 
+    @Override
     protected int mode() {
         return CookieAction.MODE_EXACTLY_ONE;
     }
 
     public MoveFilterDownAction() {
 
-        putValue(Action.SHORT_DESCRIPTION, "Move filter downwards");
+        putValue(Action.SHORT_DESCRIPTION, "Move selected filter downwards");
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(MoveFilterUpAction.class, "CTL_MoveFilterDownAction");
     }
 
+    @Override
     protected Class[] cookieClasses() {
         return new Class[]{
             Filter.class
@@ -65,7 +69,7 @@
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/filterwindow/images/down.gif";
+        return "com/sun/hotspot/igv/filterwindow/images/down.png";
     }
 
     @Override
@@ -74,6 +78,7 @@
         putValue("noIconInMenu", Boolean.TRUE);
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/MoveFilterUpAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/MoveFilterUpAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,8 +23,8 @@
  */
 package com.sun.hotspot.igv.filterwindow.actions;
 
+import com.sun.hotspot.igv.filter.Filter;
 import com.sun.hotspot.igv.filterwindow.FilterTopComponent;
-import com.sun.hotspot.igv.filter.Filter;
 import javax.swing.Action;
 import org.openide.nodes.Node;
 import org.openide.util.HelpCtx;
@@ -37,6 +37,7 @@
  */
 public final class MoveFilterUpAction extends CookieAction {
 
+    @Override
     protected void performAction(Node[] activatedNodes) {
         for (Node n : activatedNodes) {
             Filter c = n.getLookup().lookup(Filter.class);
@@ -44,18 +45,21 @@
         }
     }
 
+    @Override
     protected int mode() {
         return CookieAction.MODE_EXACTLY_ONE;
     }
 
     public MoveFilterUpAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Move filter upwards");
+        putValue(Action.SHORT_DESCRIPTION, "Move selected filter upwards");
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(MoveFilterUpAction.class, "CTL_MoveFilterUpAction");
     }
 
+    @Override
     protected Class[] cookieClasses() {
         return new Class[]{
             Filter.class
@@ -64,7 +68,7 @@
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/filterwindow/images/up.gif";
+        return "com/sun/hotspot/igv/filterwindow/images/up.png";
     }
 
     @Override
@@ -73,6 +77,7 @@
         putValue("noIconInMenu", Boolean.TRUE);
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/NewFilterAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/NewFilterAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -39,10 +39,12 @@
         putValue(Action.SHORT_DESCRIPTION, "Create new filter");
     }
 
+    @Override
     public void performAction() {
         FilterTopComponent.findInstance().newFilter();
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(SaveFilterSettingsAction.class, "CTL_NewFilterAction");
     }
@@ -52,6 +54,7 @@
         super.initialize();
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -63,6 +66,6 @@
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/filterwindow/images/plus.gif";
+        return "com/sun/hotspot/igv/filterwindow/images/plus.png";
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/RemoveFilterAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/RemoveFilterAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,8 +23,8 @@
  */
 package com.sun.hotspot.igv.filterwindow.actions;
 
+import com.sun.hotspot.igv.filter.Filter;
 import com.sun.hotspot.igv.filterwindow.FilterTopComponent;
-import com.sun.hotspot.igv.filter.Filter;
 import javax.swing.Action;
 import javax.swing.JOptionPane;
 import org.openide.nodes.Node;
@@ -39,13 +39,14 @@
  */
 public final class RemoveFilterAction extends CookieAction {
 
+    @Override
     protected void performAction(Node[] activatedNodes) {
         Object[] options = {"Yes",
             "No",
             "Cancel"
         };
         int n = JOptionPane.showOptionDialog(WindowManager.getDefault().getMainWindow(),
-                "Do you really want to delete " + activatedNodes.length + " filter/s?", "Delete?",
+                "Do you really want to delete " + activatedNodes.length + " filter(s)?", "Delete Filters",
                 JOptionPane.YES_NO_CANCEL_OPTION,
                 JOptionPane.QUESTION_MESSAGE,
                 null,
@@ -59,18 +60,21 @@
         }
     }
 
+    @Override
     protected int mode() {
         return CookieAction.MODE_ALL;
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(RemoveFilterAction.class, "CTL_RemoveFilterAction");
     }
 
     public RemoveFilterAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Remove filter");
+        putValue(Action.SHORT_DESCRIPTION, "Remove selected filter");
     }
 
+    @Override
     protected Class[] cookieClasses() {
         return new Class[]{
             Filter.class
@@ -85,9 +89,10 @@
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/filterwindow/images/minus.gif";
+        return "com/sun/hotspot/igv/filterwindow/images/minus.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/RemoveFilterSettingsAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/RemoveFilterSettingsAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -35,16 +35,18 @@
  */
 public final class RemoveFilterSettingsAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         FilterTopComponent.findInstance().removeFilterSetting();
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(RemoveFilterSettingsAction.class, "CTL_RemoveFilterSettingsAction");
     }
 
     public RemoveFilterSettingsAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Remove filter profile");
+        putValue(Action.SHORT_DESCRIPTION, "Delete current filter profile");
     }
 
     @Override
@@ -52,6 +54,7 @@
         super.initialize();
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -63,6 +66,6 @@
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/filterwindow/images/delete.gif";
+        return "com/sun/hotspot/igv/filterwindow/images/delete.png";
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/SaveFilterSettingsAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/SaveFilterSettingsAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -35,10 +35,12 @@
  */
 public final class SaveFilterSettingsAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         FilterTopComponent.findInstance().addFilterSetting();
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(SaveFilterSettingsAction.class, "CTL_SaveFilterSettingsAction");
     }
@@ -49,9 +51,10 @@
     }
 
     public SaveFilterSettingsAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Create new filter profile");
+        putValue(Action.SHORT_DESCRIPTION, "Save filter configuration as profile...");
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -63,6 +66,6 @@
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/filterwindow/images/add.gif";
+        return "com/sun/hotspot/igv/filterwindow/images/add.png";
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/customRightTopWsmode.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/customRightTopWsmode.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -4,8 +4,8 @@
     <kind type="view" />
     <state type="joined" />
     <constraints>
-        <path orientation="horizontal" number="45" weight="0.21761006289308177"/>
-        <path orientation="vertical" number="0" weight="0.2510122989593188"/>
+        <path orientation="horizontal" number="90" weight="0.2"/>
+        <path orientation="vertical" number="0" weight="0.75"/>
     </constraints>
     <bounds x="0" y="0" width="0" height="0" />
     <frame state="0"/>
Binary file src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/add.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/add.png has changed
Binary file src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/delete.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/delete.png has changed
Binary file src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/down.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/down.png has changed
Binary file src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/minus.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/minus.png has changed
Binary file src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/plus.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/plus.png has changed
Binary file src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/up.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/up.png has changed
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/layer.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/layer.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -18,8 +18,11 @@
             <attr name="position" intvalue="900"/>
         </file>
     </folder>
-    <folder name="Window">
-        <file name="com-sun-hotspot-igv-coordinator-actions-FilterAction.instance"/>
+    
+    <folder name="Actions">
+        <folder name="Window">
+            <file name="com-sun-hotspot-igv-filterwindow-actions-FilterAction.instance"/>
+        </folder>
     </folder>
     <folder name="Menu">
         <folder name="Window">
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.graal" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.graal.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.graal
+OpenIDE-Module-Layer: com/sun/hotspot/igv/graal/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/graal/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.graal-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=79002a09
+build.xml.script.CRC32=3534d355
+build.xml.stylesheet.CRC32=a56c6a5b@2.47.1
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=79002a09
+nbproject/build-impl.xml.script.CRC32=2867f2d5
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.47.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.graal</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.filter</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages/>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=Graal Compiler Support
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/GraalCFGFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * 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.sun.hotspot.igv.graal.filters;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.filter.AbstractFilter;
+import com.sun.hotspot.igv.graph.Connection;
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.graph.InputSlot;
+import java.util.HashSet;
+import java.util.Set;
+
+public class GraalCFGFilter extends AbstractFilter {
+    
+    @Override
+    public String getName() {
+        return "Graal CFG Filter";
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        Set<Figure> figuresToRemove = new HashSet<>();
+        Set<Connection> connectionsToRemove = new HashSet<>();
+        for (Figure f : d.getFigures()) {
+            final String prop = f.getProperties().get("probability");
+            
+            if (prop == null) {
+                figuresToRemove.add(f);
+            }
+        }
+        d.removeAllFigures(figuresToRemove);
+        
+        for (Figure f : d.getFigures()) {
+            Properties p = f.getProperties();
+            int predCount = Integer.parseInt(p.get("predecessorCount"));
+            for (InputSlot is : f.getInputSlots()) {
+                if (is.getPosition() >= predCount && !"EndNode".equals(is.getProperties().get("class"))) {
+                    for (Connection c : is.getConnections()) {
+                        if (!"EndNode".equals(c.getOutputSlot().getFigure().getProperties().get("class"))) {
+                            connectionsToRemove.add(c);
+                        }
+                    }
+                }
+            }
+        }
+        
+        for (Connection c : connectionsToRemove) {
+            c.remove();
+            System.out.println("rm " + c);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/GraalColoringFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,81 @@
+/*
+ * 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.sun.hotspot.igv.graal.filters;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.filter.AbstractFilter;
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.Figure;
+import java.awt.Color;
+import java.util.List;
+
+public class GraalColoringFilter extends AbstractFilter {
+    
+    private String colorName;
+
+    public GraalColoringFilter(String colorName) {
+        this.colorName = colorName;
+    }
+
+    @Override
+    public String getName() {
+        return "Graal Coloring Filter (" + colorName + ")";
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        List<Figure> figures = d.getFigures();
+        int colors = 0;
+        for (Figure f : figures) {
+            Properties p = f.getProperties();
+            final String prop = p.get(colorName + "Color");
+            if (prop == null) {
+                continue;
+            }
+            try {
+                int color = Integer.parseInt(prop);
+                if (color > colors) {
+                    colors = color;
+                }
+            } catch (NumberFormatException nfe) {
+                // nothing to do
+            }
+        }
+        colors++;
+        for (Figure f : figures) {
+            Properties p = f.getProperties();
+            final String prop = p.get(colorName + "Color");
+            if (prop == null) {
+                continue;
+            }
+            try {
+                int color = Integer.parseInt(prop);
+                Color c = Color.getHSBColor((float) color / colors, 1.0f, 0.7f);
+                f.setColor(c);
+            } catch (NumberFormatException nfe) {
+                // nothing to do
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/GraalEdgeColorFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,116 @@
+/*
+ * 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.sun.hotspot.igv.graal.filters;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.filter.AbstractFilter;
+import com.sun.hotspot.igv.graph.Connection;
+import com.sun.hotspot.igv.graph.Connection.ConnectionStyle;
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.graph.InputSlot;
+import java.awt.Color;
+import java.util.List;
+
+/**
+ * Filter that colors usage and successor edges differently.
+ *
+ * @author Peter Hofer
+ */
+public class GraalEdgeColorFilter extends AbstractFilter {
+
+    private Color successorColor = Color.BLUE;
+    private Color usageColor = Color.RED;
+    private Color memoryColor = Color.GREEN;
+
+    public GraalEdgeColorFilter() {
+    }
+
+    @Override
+    public String getName() {
+        return "Graal Edge Color Filter";
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        List<Figure> figures = d.getFigures();
+        for (Figure f : figures) {
+            Properties p = f.getProperties();
+            int predCount;
+            if (p.get("predecessorCount") != null) {
+                predCount = Integer.parseInt(p.get("predecessorCount"));
+            } else {
+                predCount = 0;
+            }
+            for (InputSlot is : f.getInputSlots()) {
+                Color color;
+                ConnectionStyle style = ConnectionStyle.NORMAL;
+                if (is.getPosition() < predCount) {
+                    color = successorColor;
+                    style = ConnectionStyle.BOLD;
+                } else {
+                    color = usageColor;
+                }
+
+                is.setColor(color);
+                for (Connection c : is.getConnections()) {
+                    if (c.getLabel() == null || !c.getLabel().endsWith("#NDF")) {
+                        c.setColor(color);
+                        if (c.getStyle() != ConnectionStyle.DASHED) {
+                            c.setStyle(style);
+                        }
+                    } else if ("EndNode".equals(c.getOutputSlot().getFigure().getProperties().get("class"))
+                            || "EndNode".equals(c.getOutputSlot().getProperties().get("class"))) {
+                        c.setColor(successorColor);
+                        c.setStyle(ConnectionStyle.BOLD);
+                    }
+                }
+            }
+        }
+    }
+
+    public Color getUsageColor() {
+        return usageColor;
+    }
+
+    public void setUsageColor(Color usageColor) {
+        this.usageColor = usageColor;
+    }
+
+    public void setMemoryColor(Color memoryColor) {
+        this.memoryColor = memoryColor;
+    }
+
+    public Color getMemoryColor() {
+        return memoryColor;
+    }
+
+    public Color getSuccessorColor() {
+        return successorColor;
+    }
+
+    public void setSuccessorColor(Color successorColor) {
+        this.successorColor = successorColor;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/beginend.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,4 @@
+var f = new CombineFilter("Combine Filter");
+f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("class", ".*"), new Properties.RegexpPropertyMatcher("class", "BeginNode"), false, "shortName"));
+f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("class", "EndNode"), new Properties.RegexpPropertyMatcher("class", ".*"), true, "shortName"));
+f.apply(graph);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/callgraph.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,4 @@
+colorize("name", "<init>.*", yellow);
+colorize("name", "<clinit>.*", pink);
+colorize("leaf", "1", lightGray);
+colorize("cutoff", "1", red);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/cfg.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+var f = new com.sun.hotspot.igv.graal.filters.GraalCFGFilter();
+f.apply(graph);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/color.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,11 @@
+colorize("name", ".*", white);
+colorize("name", "Begin|EndNode|LoopBegin|LoopEnd|Return", orange);
+colorize("name", "Phi.*", magenta);
+colorize("name", "FrameState@.*", new java.awt.Color(0.5, 0.8, 1.0));
+colorize("name", "If|Merge", pink);
+colorize("name", "const.*", new java.awt.Color(0.7, 0.7, 0.7));
+colorize("name", "Local", new java.awt.Color(0.85, 0.85, 0.85));
+colorize("name", "\\+|-|\\*|/|&|\\||<<|>>|>>>", cyan);
+colorize("name", "Comp .*", yellow);
+
+colorize("notInOwnBlock", "true", red);
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/edgeColor.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,4 @@
+var f = new com.sun.hotspot.igv.graal.filters.GraalEdgeColorFilter();
+f.setUsageColor(blue);
+f.setSuccessorColor(red);
+f.apply(graph);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/framestatelocks.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+colorize("class", "FrameState", red);
+colorize("locks", "", gray);
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/noframestate.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+remove("class", "FrameState");
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/probability.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,3 @@
+colorizeGradientWithMode("probability", 0, 500, "logarithmic");
+
+// more parameters: colorizeGradientCustom("probability", 0, 500, "logarithmic", [blue, yellow, red], [0, 0.5, 1], 16);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/slots.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+removeUnconnectedSlots(true, true);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/layer.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
+<filesystem>
+    <folder name="Filters">
+        <file name="Graal Coloring" url="filters/color.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Graal Edge Coloring" url="filters/edgeColor.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Graal Remove Unconnected Slots" url="filters/slots.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Graal Probability" url="filters/probability.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Graal Reduce Begin-End" url="filters/beginend.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Graal Remove FrameState" url="filters/noframestate.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Graal Mark FrameState With Lock" url="filters/framestatelocks.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Graal Call Analysis" url="filters/callgraph.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Graal CFG-only" url="filters/cfg.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+    </folder>
+</filesystem>
--- a/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -25,6 +25,7 @@
             </module-dependencies>
             <public-packages>
                 <package>com.sun.hotspot.igv.graph</package>
+                <package>com.sun.hotspot.igv.graph.services</package>
             </public-packages>
         </data>
     </configuration>
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/AndSelector.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/AndSelector.java	Mon Feb 27 13:10:13 2012 +0100
@@ -40,10 +40,11 @@
         this.selector2 = s2;
     }
 
+    @Override
     public List<Figure> selected(Diagram d) {
         List<Figure> l1 = selector1.selected(d);
         List<Figure> l2 = selector2.selected(d);
-        List<Figure> result = new ArrayList<Figure>();
+        List<Figure> result = new ArrayList<>();
         for (Figure f : l2) {
             if (l1.contains(f)) {
                 result.add(f);
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Block.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.graph;
-
-import com.sun.hotspot.igv.data.InputBlock;
-import com.sun.hotspot.igv.layout.Cluster;
-import java.awt.Rectangle;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class Block implements Cluster {
-
-    private InputBlock inputBlock;
-    private Rectangle bounds;
-    private Diagram diagram;
-
-    public Block(InputBlock inputBlock, Diagram diagram) {
-        this.inputBlock = inputBlock;
-        this.diagram = diagram;
-    }
-
-    public Cluster getOuter() {
-        return null;
-    }
-
-    public InputBlock getInputBlock() {
-        return inputBlock;
-    }
-
-    public Set<? extends Cluster> getSuccessors() {
-        Set<Block> succs = new HashSet<Block>();
-        for (InputBlock b : inputBlock.getSuccessors()) {
-            succs.add(diagram.getBlock(b));
-        }
-        return succs;
-    }
-
-    public Set<? extends Cluster> getPredecessors() {
-        Set<Block> succs = new HashSet<Block>();
-        for (InputBlock b : inputBlock.getPredecessors()) {
-            succs.add(diagram.getBlock(b));
-        }
-        return succs;
-    }
-
-    public void setBounds(Rectangle r) {
-        this.bounds = r;
-    }
-
-    public Rectangle getBounds() {
-        return bounds;
-    }
-
-    public int compareTo(Cluster o) {
-        return toString().compareTo(o.toString());
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Connection.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Connection.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,6 +23,7 @@
  */
 package com.sun.hotspot.igv.graph;
 
+import com.sun.hotspot.igv.data.Source;
 import com.sun.hotspot.igv.layout.Link;
 import com.sun.hotspot.igv.layout.Port;
 import java.awt.Color;
@@ -36,6 +37,11 @@
  */
 public class Connection implements Source.Provider, Link {
 
+    @Override
+    public boolean isVIP() {
+        return style == ConnectionStyle.BOLD;
+    }
+
     public enum ConnectionStyle {
 
         NORMAL,
@@ -48,13 +54,15 @@
     private Color color;
     private ConnectionStyle style;
     private List<Point> controlPoints;
+    private String label;
 
-    protected Connection(InputSlot inputSlot, OutputSlot outputSlot) {
+    protected Connection(InputSlot inputSlot, OutputSlot outputSlot, String label) {
         this.inputSlot = inputSlot;
         this.outputSlot = outputSlot;
+        this.label = label;
         this.inputSlot.connections.add(this);
         this.outputSlot.connections.add(this);
-        controlPoints = new ArrayList<Point>();
+        controlPoints = new ArrayList<>();
         Figure sourceFigure = this.outputSlot.getFigure();
         Figure destFigure = this.inputSlot.getFigure();
         sourceFigure.addSuccessor(destFigure);
@@ -89,10 +97,15 @@
         style = s;
     }
 
+    @Override
     public Source getSource() {
         return source;
     }
 
+    public String getLabel() {
+        return label;
+    }
+
     public void remove() {
         inputSlot.getFigure().removePredecessor(outputSlot.getFigure());
         inputSlot.connections.remove(this);
@@ -100,24 +113,42 @@
         outputSlot.connections.remove(this);
     }
 
+    public String getToolTipText() {
+        StringBuilder builder = new StringBuilder();
+        if (label != null) {
+            builder.append(label).append(": from ");
+        } else {
+            builder.append("From ");
+        }
+        builder.append(getOutputSlot().getFigure().getSource().getSourceNodes().get(0).getId());
+        builder.append(" to ");
+        builder.append(getInputSlot().getFigure().getSource().getSourceNodes().get(0).getId());
+        return builder.toString();
+    }
+
     @Override
     public String toString() {
-        return "Connection(" + getFrom().getVertex() + " to " + getTo().getVertex() + ")";
+        return "Connection('" + label + "', " + getFrom().getVertex() + " to " + getTo().getVertex() + ")";
     }
 
+    @Override
     public Port getFrom() {
         return outputSlot;
     }
 
+    @Override
     public Port getTo() {
         return inputSlot;
     }
 
+    @Override
     public List<Point> getControlPoints() {
         return controlPoints;
     }
 
+    @Override
     public void setControlPoints(List<Point> list) {
         controlPoints = list;
     }
 }
+
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,22 +23,13 @@
  */
 package com.sun.hotspot.igv.graph;
 
-import com.sun.hotspot.igv.data.InputBlock;
 import com.sun.hotspot.igv.data.InputEdge;
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.InputNode;
 import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Properties.StringPropertyMatcher;
 import java.awt.Font;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 /**
  *
@@ -47,52 +38,35 @@
 public class Diagram {
 
     private List<Figure> figures;
-    private Map<InputBlock, Block> blocks;
     private InputGraph graph;
     private int curId;
     private String nodeText;
     private Font font;
+    private Font slotFont;
 
     public Font getFont() {
         return font;
     }
 
+    public Font getSlotFont() {
+        return slotFont;
+    }
+    
     private Diagram() {
-        figures = new ArrayList<Figure>();
-        blocks = new HashMap<InputBlock, Block>();
+        figures = new ArrayList<>();
         this.nodeText = "";
-        this.font = new Font("Serif", Font.PLAIN, 14);
-    }
-
-    public Block getBlock(InputBlock b) {
-        return blocks.get(b);
+        this.font = new Font("Arial", Font.PLAIN, 13);
+        this.slotFont = new Font("Arial", Font.PLAIN, 10);
     }
 
     public String getNodeText() {
         return nodeText;
     }
 
-    public void schedule(Collection<InputBlock> newBlocks) {
-        graph.schedule(newBlocks);
-        updateBlocks();
-    }
-
-    private void updateBlocks() {
-        blocks.clear();
-        for (InputBlock b : graph.getBlocks()) {
-            Block curBlock = new Block(b, this);
-            blocks.put(b, curBlock);
-        }
-    }
-
     public Diagram getNext() {
         return Diagram.createDiagram(graph.getNext(), nodeText);
     }
 
-    public Collection<Block> getBlocks() {
-        return Collections.unmodifiableCollection(blocks.values());
-    }
-
     public Diagram getPrev() {
         return Diagram.createDiagram(graph.getPrev(), nodeText);
     }
@@ -108,10 +82,26 @@
         return f;
     }
 
-    public Connection createConnection(InputSlot inputSlot, OutputSlot outputSlot) {
+    public Connection createConnection(InputSlot inputSlot, OutputSlot outputSlot, String label) {
         assert inputSlot.getFigure().getDiagram() == this;
         assert outputSlot.getFigure().getDiagram() == this;
-        return new Connection(inputSlot, outputSlot);
+        return new Connection(inputSlot, outputSlot, label);
+    }
+    
+    public Map<InputNode, Set<Figure>> calcSourceToFigureRelation() {
+        Map<InputNode, Set<Figure>> map = new HashMap<>();
+        
+        for(InputNode node : this.getGraph().getNodes()) {
+            map.put(node, new HashSet<Figure>());
+        }
+        
+        for(Figure f : this.getFigures()) {
+            for(InputNode node : f.getSource().getSourceNodes()) {
+                map.get(node).add(f);
+            }
+        }
+        
+        return map;
     }
 
     public static Diagram createDiagram(InputGraph graph, String nodeText) {
@@ -123,10 +113,8 @@
         d.graph = graph;
         d.nodeText = nodeText;
 
-        d.updateBlocks();
-
         Collection<InputNode> nodes = graph.getNodes();
-        HashMap<Integer, Figure> figureHash = new HashMap<Integer, Figure>();
+        Hashtable<Integer, Figure> figureHash = new Hashtable<>();
         for (InputNode n : nodes) {
             Figure f = d.createFigure();
             f.getSource().addSourceNode(n);
@@ -140,23 +128,23 @@
             int to = e.getTo();
             Figure fromFigure = figureHash.get(from);
             Figure toFigure = figureHash.get(to);
+            
+            if(fromFigure == null || toFigure == null) continue;
             assert fromFigure != null && toFigure != null;
 
+            int fromIndex = e.getFromIndex();
+            while (fromFigure.getOutputSlots().size() <= fromIndex) {
+                fromFigure.createOutputSlot();
+            }
+            OutputSlot outputSlot = fromFigure.getOutputSlots().get(fromIndex);
+
             int toIndex = e.getToIndex();
-
-            while (fromFigure.getOutputSlots().size() <= 0) {
-                fromFigure.createOutputSlot();
-            }
-
-            OutputSlot outputSlot = fromFigure.getOutputSlots().get(0);
-
             while (toFigure.getInputSlots().size() <= toIndex) {
                 toFigure.createInputSlot();
             }
-
             InputSlot inputSlot = toFigure.getInputSlots().get(toIndex);
 
-            Connection c = d.createConnection(inputSlot, outputSlot);
+            Connection c = d.createConnection(inputSlot, outputSlot, e.getLabel());
 
             if (e.getState() == InputEdge.State.NEW) {
                 c.setStyle(Connection.ConnectionStyle.BOLD);
@@ -174,7 +162,7 @@
             freeFigure(f);
         }
 
-        ArrayList<Figure> newFigures = new ArrayList<Figure>();
+        ArrayList<Figure> newFigures = new ArrayList<>();
         for (Figure f : this.figures) {
             if (!figuresToRemove.contains(f)) {
                 newFigures.add(f);
@@ -185,12 +173,12 @@
 
     private void freeFigure(Figure succ) {
 
-        List<InputSlot> inputSlots = new ArrayList<InputSlot>(succ.getInputSlots());
+        List<InputSlot> inputSlots = new ArrayList<>(succ.getInputSlots());
         for (InputSlot s : inputSlots) {
             succ.removeInputSlot(s);
         }
 
-        List<OutputSlot> outputSlots = new ArrayList<OutputSlot>(succ.getOutputSlots());
+        List<OutputSlot> outputSlots = new ArrayList<>(succ.getOutputSlots());
         for (OutputSlot s : outputSlots) {
             succ.removeOutputSlot(s);
         }
@@ -219,7 +207,7 @@
 
     public Set<Connection> getConnections() {
 
-        Set<Connection> connections = new HashSet<Connection>();
+        Set<Connection> connections = new HashSet<>();
         for (Figure f : figures) {
 
             for (InputSlot s : f.getInputSlots()) {
@@ -231,10 +219,10 @@
     }
 
     public Figure getRootFigure() {
-        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(figures);
-        Figure root = selector.selectSingle("name", "Root");
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(figures);
+        Figure root = selector.selectSingle(new StringPropertyMatcher("name", "Root"));
         if (root == null) {
-            root = selector.selectSingle("name", "Start");
+            root = selector.selectSingle(new StringPropertyMatcher("name", "Start"));
         }
         if (root == null) {
             List<Figure> rootFigures = getRootFigures();
@@ -258,9 +246,10 @@
         System.out.println("Number of figures: " + tmpFigures.size());
         System.out.println("Number of connections: " + connections.size());
 
-        List<Figure> figuresSorted = new ArrayList<Figure>(tmpFigures);
+        List<Figure> figuresSorted = new ArrayList<>(tmpFigures);
         Collections.sort(figuresSorted, new Comparator<Figure>() {
 
+            @Override
             public int compare(Figure a, Figure b) {
                 return b.getPredecessors().size() + b.getSuccessors().size() - a.getPredecessors().size() - a.getSuccessors().size();
             }
@@ -283,7 +272,7 @@
     }
 
     public List<Figure> getRootFigures() {
-        ArrayList<Figure> rootFigures = new ArrayList<Figure>();
+        ArrayList<Figure> rootFigures = new ArrayList<>();
         for (Figure f : figures) {
             if (f.getPredecessors().size() == 0) {
                 rootFigures.add(f);
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,20 +23,14 @@
  */
 package com.sun.hotspot.igv.graph;
 
-import com.sun.hotspot.igv.layout.Cluster;
-import com.sun.hotspot.igv.layout.Vertex;
+import com.sun.hotspot.igv.data.InputNode;
 import com.sun.hotspot.igv.data.Properties;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.FontMetrics;
-import java.awt.Graphics;
-import java.awt.Point;
+import com.sun.hotspot.igv.data.Source;
+import com.sun.hotspot.igv.layout.Vertex;
+import java.awt.*;
 import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 /**
  *
@@ -44,9 +38,11 @@
  */
 public class Figure extends Properties.Entity implements Source.Provider, Vertex {
 
-    public static final int INSET = 6;
-    public static final int SLOT_WIDTH = 10;
-    public static final int SLOT_START = 3;
+    public static final int INSET = 12;
+    public static int SLOT_WIDTH = 12;
+    public static final int OVERLAPPING = 6;
+    public static final int SLOT_START = 4;
+    public static final int SLOT_OFFSET = 8;
     public static final boolean VERTICAL_LAYOUT = true;
     protected List<InputSlot> inputSlots;
     protected List<OutputSlot> outputSlots;
@@ -66,28 +62,49 @@
         if (heightCash == -1) {
             BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
             Graphics g = image.getGraphics();
-            g.setFont(diagram.getFont());
+            g.setFont(diagram.getFont().deriveFont(Font.BOLD));
             FontMetrics metrics = g.getFontMetrics();
             String nodeText = diagram.getNodeText();
             heightCash = nodeText.split("\n").length * metrics.getHeight() + INSET;
         }
         return heightCash;
     }
+    
+    public static <T> List<T> getAllBefore(List<T> inputList, T tIn) {
+        List<T> result = new ArrayList<>();
+        for(T t : inputList) {
+            if(t.equals(tIn)) {
+                break;
+            }
+            result.add(t);
+        }
+        return result;
+    }
+    
+    public static int getSlotsWidth(Collection<? extends Slot> slots) {
+        int result = Figure.SLOT_OFFSET;
+        for(Slot s : slots) {
+            result += s.getWidth() + Figure.SLOT_OFFSET;
+        }
+        return result;
+    }
 
     public int getWidth() {
         if (widthCash == -1) {
             int max = 0;
             BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
             Graphics g = image.getGraphics();
-            g.setFont(diagram.getFont());
+            g.setFont(diagram.getFont().deriveFont(Font.BOLD));
             FontMetrics metrics = g.getFontMetrics();
-            for (String s : lines) {
+            for (String s : getLines()) {
                 int cur = metrics.stringWidth(s);
                 if (cur > max) {
                     max = cur;
                 }
             }
             widthCash = max + INSET;
+            widthCash = Math.max(widthCash, Figure.getSlotsWidth(inputSlots));
+            widthCash = Math.max(widthCash, Figure.getSlotsWidth(outputSlots));
         }
         return widthCash;
     }
@@ -95,10 +112,10 @@
     protected Figure(Diagram diagram, int id) {
         this.diagram = diagram;
         this.source = new Source();
-        inputSlots = new ArrayList<InputSlot>(5);
-        outputSlots = new ArrayList<OutputSlot>(1);
-        predecessors = new ArrayList<Figure>(6);
-        successors = new ArrayList<Figure>(6);
+        inputSlots = new ArrayList<>(5);
+        outputSlots = new ArrayList<>(1);
+        predecessors = new ArrayList<>(6);
+        successors = new ArrayList<>(6);
         this.id = id;
         idString = Integer.toString(id);
 
@@ -123,7 +140,7 @@
     }
 
     public Set<Figure> getPredecessorSet() {
-        Set<Figure> result = new HashSet<Figure>();
+        Set<Figure> result = new HashSet<>();
         for (Figure f : getPredecessors()) {
             result.add(f);
         }
@@ -131,7 +148,7 @@
     }
 
     public Set<Figure> getSuccessorSet() {
-        Set<Figure> result = new HashSet<Figure>();
+        Set<Figure> result = new HashSet<>();
         for (Figure f : getSuccessors()) {
             result.add(f);
         }
@@ -160,10 +177,12 @@
         successors.remove(f);
     }
 
+    @Override
     public void setPosition(Point p) {
         this.position = p;
     }
 
+    @Override
     public Point getPosition() {
         return position;
     }
@@ -172,6 +191,7 @@
         return diagram;
     }
 
+    @Override
     public Source getSource() {
         return source;
     }
@@ -193,7 +213,7 @@
 
         assert inputSlots.contains(s) || outputSlots.contains(s);
 
-        List<Connection> connections = new ArrayList<Connection>(s.getConnections());
+        List<Connection> connections = new ArrayList<>(s.getConnections());
         for (Connection c : connections) {
             c.remove();
         }
@@ -221,6 +241,13 @@
     public List<InputSlot> getInputSlots() {
         return Collections.unmodifiableList(inputSlots);
     }
+    
+    public Set<Slot> getSlots() {
+        Set<Slot> result = new HashSet<>();
+        result.addAll(getInputSlots());
+        result.addAll(getOutputSlots());
+        return result;
+    }
 
     public List<OutputSlot> getOutputSlots() {
         return Collections.unmodifiableList(outputSlots);
@@ -248,13 +275,13 @@
         String[] result = new String[strings.length];
 
         for (int i = 0; i < strings.length; i++) {
-            result[i] = resolveString(strings[i]);
+            result[i] = resolveString(strings[i], getProperties());
         }
 
         lines = result;
     }
 
-    private String resolveString(String string) {
+    public static final String resolveString(String string, Properties properties) {
 
         StringBuilder sb = new StringBuilder();
         boolean inBrackets = false;
@@ -264,7 +291,7 @@
             char c = string.charAt(i);
             if (inBrackets) {
                 if (c == ']') {
-                    String value = getProperties().get(curIdent.toString());
+                    String value = properties.get(curIdent.toString());
                     if (value == null) {
                         value = "";
                     }
@@ -286,13 +313,16 @@
         return sb.toString();
     }
 
+    @Override
     public Dimension getSize() {
         if (VERTICAL_LAYOUT) {
             int width = Math.max(getWidth(), Figure.SLOT_WIDTH * (Math.max(inputSlots.size(), outputSlots.size()) + 1));
-            int height = getHeight() + 2 * Figure.SLOT_WIDTH;
+            int height = getHeight() + 2 * Figure.SLOT_WIDTH - 2 * Figure.OVERLAPPING;
+            
+            
             return new Dimension(width, height);
         } else {
-            int width = getWidth() + 2 * Figure.SLOT_WIDTH;
+            int width = getWidth() + 2 * Figure.SLOT_WIDTH - 2*Figure.OVERLAPPING;
             int height = Figure.SLOT_WIDTH * (Math.max(inputSlots.size(), outputSlots.size()) + 1);
             return new Dimension(width, height);
         }
@@ -303,26 +333,23 @@
         return idString;
     }
 
-    public Cluster getCluster() {
-        if (getSource().getSourceNodes().size() == 0) {
-            assert false : "Should never reach here, every figure must have at least one source node!";
-            return null;
-        } else {
-            Cluster result = diagram.getBlock(diagram.getGraph().getBlock(getSource().getSourceNodes().get(0)));
-            assert result != null;
-            return result;
-        }
-    }
-
+    @Override
     public boolean isRoot() {
-        if (source.getSourceNodes().size() > 0 && source.getSourceNodes().get(0).getProperties().get("name").equals("Root")) {
-            return true;
+  
+        List<InputNode> sourceNodes = source.getSourceNodes();
+        if (sourceNodes.size() > 0 && sourceNodes.get(0).getProperties().get("name") != null) {
+            return source.getSourceNodes().get(0).getProperties().get("name").equals("Root");
         } else {
             return false;
         }
     }
 
+    @Override
     public int compareTo(Vertex f) {
         return toString().compareTo(f.toString());
     }
+
+    public Rectangle getBounds() {
+        return new Rectangle(this.getPosition(), new Dimension(this.getWidth(), this.getHeight()));
+    }
 }
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/InputSlot.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/InputSlot.java	Mon Feb 27 13:10:13 2012 +0100
@@ -27,7 +27,7 @@
 import java.util.List;
 
 /**
- *
+ * 
  * @author Thomas Wuerthinger
  */
 public class InputSlot extends Slot {
@@ -36,18 +36,24 @@
         super(figure, wantedIndex);
     }
 
+    @Override
     public int getPosition() {
         return getFigure().getInputSlots().indexOf(this);
     }
 
+    @Override
     public void setPosition(int position) {
         List<InputSlot> inputSlots = getFigure().inputSlots;
         InputSlot s = inputSlots.remove(position);
         inputSlots.add(position, s);
     }
-
+    @Override
     public Point getRelativePosition() {
-        return new Point(getFigure().getWidth() * (getPosition() + 1) / (getFigure().getInputSlots().size() + 1), Figure.SLOT_WIDTH - Figure.SLOT_START);
+        int gap = getFigure().getWidth() - Figure.getSlotsWidth(getFigure().getInputSlots());
+        double gapRatio = (double)gap / (double)(getFigure().getInputSlots().size() + 1);
+        int gapAmount = (int)((getPosition() + 1)*gapRatio);
+        return new Point(gapAmount + Figure.getSlotsWidth(Figure.getAllBefore(getFigure().getInputSlots(), this)) + getWidth()/2, -Figure.SLOT_START);
+        //return new Point((getFigure().getWidth() / (getFigure().getInputSlots().size() * 2)) * (getPosition() * 2 + 1), -Figure.SLOT_START);
     }
 
     @Override
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/InvertSelector.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/InvertSelector.java	Mon Feb 27 13:10:13 2012 +0100
@@ -38,9 +38,10 @@
         this.selector = selector;
     }
 
+    @Override
     public List<Figure> selected(Diagram d) {
 
-        List<Figure> result = new ArrayList<Figure>();
+        List<Figure> result = new ArrayList<>();
         List<Figure> otherResult = selector.selected(d);
         for (Figure f : d.getFigures()) {
             if (!otherResult.contains(f)) {
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/MatcherSelector.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/MatcherSelector.java	Mon Feb 27 13:10:13 2012 +0100
@@ -39,8 +39,9 @@
         this.matcher = matcher;
     }
 
+    @Override
     public List<Figure> selected(Diagram d) {
-        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(d.getFigures());
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(d.getFigures());
         List<Figure> list = selector.selectMultiple(matcher);
         return list;
     }
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/OrSelector.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/OrSelector.java	Mon Feb 27 13:10:13 2012 +0100
@@ -40,6 +40,7 @@
         this.selector2 = s2;
     }
 
+    @Override
     public List<Figure> selected(Diagram d) {
 
         List<Figure> l1 = selector1.selected(d);
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/OutputSlot.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/OutputSlot.java	Mon Feb 27 13:10:13 2012 +0100
@@ -26,7 +26,7 @@
 import java.awt.Point;
 
 /**
- *
+ * 
  * @author Thomas Wuerthinger
  */
 public class OutputSlot extends Slot {
@@ -35,17 +35,26 @@
         super(figure, wantedIndex);
     }
 
+    @Override
     public int getPosition() {
         return getFigure().getOutputSlots().indexOf(this);
     }
 
+    @Override
     public void setPosition(int position) {
         OutputSlot s = getFigure().outputSlots.remove(position);
         getFigure().outputSlots.add(position, s);
     }
 
+    @Override
     public Point getRelativePosition() {
-        return new Point(getFigure().getWidth() * (getPosition() + 1) / (getFigure().getOutputSlots().size() + 1), getFigure().getSize().height - Figure.SLOT_WIDTH + Figure.SLOT_START);
+        int gap = getFigure().getWidth() - Figure.getSlotsWidth(getFigure().getOutputSlots());
+        if(gap < 0) {
+            gap = 0;
+        }
+        double gapRatio = (double)gap / (double)(getFigure().getOutputSlots().size() + 1);
+        int gapAmount = (int)((getPosition() + 1)*gapRatio);
+        return new Point(gapAmount + Figure.getSlotsWidth(Figure.getAllBefore(getFigure().getOutputSlots(), this)) + getWidth()/2, Figure.SLOT_START);
     }
 
     @Override
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/PredecessorSelector.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/PredecessorSelector.java	Mon Feb 27 13:10:13 2012 +0100
@@ -38,9 +38,10 @@
         this.innerSelector = innerSelector;
     }
 
+    @Override
     public List<Figure> selected(Diagram d) {
         List<Figure> inner = innerSelector.selected(d);
-        List<Figure> result = new ArrayList<Figure>();
+        List<Figure> result = new ArrayList<>();
         for (Figure f : d.getFigures()) {
             boolean saved = false;
             for (Figure f2 : f.getSuccessors()) {
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Slot.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Slot.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,103 +23,173 @@
  */
 package com.sun.hotspot.igv.graph;
 
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Source;
 import com.sun.hotspot.igv.layout.Port;
 import com.sun.hotspot.igv.layout.Vertex;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
-import java.util.Comparator;
 
 /**
- *
+ * 
  * @author Thomas Wuerthinger
  */
-public abstract class Slot implements Port, Source.Provider {
+public abstract class Slot implements Port, Source.Provider, Properties.Provider {
 
-    private int wantedIndex;
-    private String name;
-    private String shortName; // 1 - 2 characters
-    private Source source;
-    protected List<Connection> connections;
-    private Figure figure;
+	private int wantedIndex;
+	private Source source;
+	protected List<Connection> connections;
+	private InputNode associatedNode;
+	private Color color;
+	private String text;
+	private String shortName;
+	private Figure figure;
 
-    protected Slot(Figure figure, int wantedIndex) {
-        this.figure = figure;
-        connections = new ArrayList<Connection>(2);
-        source = new Source();
-        this.wantedIndex = wantedIndex;
-        name = "";
-        shortName = "";
-        assert figure != null;
-    }
-    public static final Comparator<Slot> slotIndexComparator = new Comparator<Slot>() {
+	protected Slot(Figure figure, int wantedIndex) {
+		this.figure = figure;
+		connections = new ArrayList<>(2);
+		source = new Source();
+		this.wantedIndex = wantedIndex;
+		text = "";
+		shortName = "";
+		assert figure != null;
+	}
+
+    @Override
+	public Properties getProperties() {
+		Properties p = new Properties();
+		if (source.getSourceNodes().size() > 0) {
+			for (InputNode n : source.getSourceNodes()) {
+				p.add(n.getProperties());
+			}
+		} else {
+			p.setProperty("name", "Slot");
+			p.setProperty("figure", figure.getProperties().get("name"));
+			p.setProperty("connectionCount", Integer.toString(connections.size()));
+		}
+		return p;
+	}
+	public static final Comparator<Slot> slotIndexComparator = new Comparator<Slot>() {
 
-        public int compare(Slot o1, Slot o2) {
-            return o1.wantedIndex - o2.wantedIndex;
-        }
-    };
-    public static final Comparator<Slot> slotFigureComparator = new Comparator<Slot>() {
+        @Override
+		public int compare(Slot o1, Slot o2) {
+			return o1.wantedIndex - o2.wantedIndex;
+		}
+	};
+	public static final Comparator<Slot> slotFigureComparator = new Comparator<Slot>() {
 
-        public int compare(Slot o1, Slot o2) {
-            return o1.figure.getId() - o2.figure.getId();
-        }
-    };
+        @Override
+		public int compare(Slot o1, Slot o2) {
+			return o1.figure.getId() - o2.figure.getId();
+		}
+	};
+
+	public InputNode getAssociatedNode() {
+		return associatedNode;
+	}
 
-    public int getWantedIndex() {
-        return wantedIndex;
-    }
+	public void setAssociatedNode(InputNode node) {
+		associatedNode = node;
+	}
 
-    public Source getSource() {
-        return source;
-    }
+	public int getWidth() {
+		if (shortName == null || shortName.length() <= 1) {
+			return Figure.SLOT_WIDTH;
+		} else {
+			BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
+			Graphics g = image.getGraphics();
+			g.setFont(figure.getDiagram().getSlotFont().deriveFont(Font.BOLD));
+			FontMetrics metrics = g.getFontMetrics();
+			return Math.max(Figure.SLOT_WIDTH, metrics.stringWidth(shortName) + 6);
+		}
+	}
 
-    public String getName() {
-        return name;
-    }
+	public int getWantedIndex() {
+		return wantedIndex;
+	}
 
-    public void setShortName(String s) {
-        assert s != null;
-        assert s.length() <= 2;
-        this.shortName = s;
+    @Override
+	public Source getSource() {
+		return source;
+	}
 
-    }
+	public String getText() {
+		return text;
+	}
 
-    public String getShortName() {
-        return shortName;
-    }
+	public void setShortName(String s) {
+		assert s != null;
+//        assert s.length() <= 2;
+		this.shortName = s;
+
+	}
 
-    public boolean getShowName() {
-        return getShortName() != null && getShortName().length() > 0;
-    }
+	public String getShortName() {
+		return shortName;
+	}
+
+	public String getToolTipText() {
+		StringBuilder sb = new StringBuilder();
+		sb.append(text);
 
-    public void setName(String s) {
-        if (s == null) {
-            s = "";
-        }
-        this.name = s;
-    }
+		for (InputNode n : getSource().getSourceNodes()) {
+			sb.append("Node (ID=" + n.getId() + "): " + n.getProperties().get("name"));
+			sb.append("<br>");
+		}
+
+		return sb.toString();
+	}
+
+	public boolean shouldShowName() {
+		return getShortName() != null && getShortName().length() > 0;
+	}
 
-    public Figure getFigure() {
-        assert figure != null;
-        return figure;
-    }
+	public void setText(String s) {
+		if (s == null) {
+			s = "";
+		}
+		this.text = s;
+	}
 
-    public List<Connection> getConnections() {
-        return Collections.unmodifiableList(connections);
-    }
+	public Figure getFigure() {
+		assert figure != null;
+		return figure;
+	}
+
+	public Color getColor() {
+		return this.color;
+	}
+
+	public void setColor(Color c) {
+		color = c;
+	}
 
-    public void removeAllConnections() {
-        List<Connection> connectionsCopy = new ArrayList<Connection>(this.connections);
-        for (Connection c : connectionsCopy) {
-            c.remove();
-        }
-    }
+	public List<Connection> getConnections() {
+		return Collections.unmodifiableList(connections);
+	}
+
+	public void removeAllConnections() {
+		List<Connection> connectionsCopy = new ArrayList<>(this.connections);
+		for (Connection c : connectionsCopy) {
+			c.remove();
+		}
+	}
 
-    public Vertex getVertex() {
-        return figure;
-    }
+    @Override
+	public Vertex getVertex() {
+		return figure;
+	}
 
-    public abstract int getPosition();
+	public abstract int getPosition();
 
-    public abstract void setPosition(int position);
+	public abstract void setPosition(int position);
 }
+
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Source.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.graph;
-
-import com.sun.hotspot.igv.data.InputBlock;
-import com.sun.hotspot.igv.data.InputGraph;
-import com.sun.hotspot.igv.data.InputNode;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class Source {
-
-    private List<InputNode> sourceNodes;
-    private Set<Integer> set;
-
-    public Source() {
-        sourceNodes = new ArrayList<InputNode>(1);
-    }
-
-    public List<InputNode> getSourceNodes() {
-        return Collections.unmodifiableList(sourceNodes);
-    }
-
-    public Set<Integer> getSourceNodesAsSet() {
-        if (set == null) {
-            set = new HashSet<Integer>();
-            for (InputNode n : sourceNodes) {
-                int id = n.getId();
-                //if(id < 0) id = -id;
-                set.add(id);
-            }
-        }
-        return set;
-    }
-
-    public void addSourceNode(InputNode n) {
-        sourceNodes.add(n);
-        set = null;
-    }
-
-    public void removeSourceNode(InputNode n) {
-        sourceNodes.remove(n);
-        set = null;
-    }
-
-    public interface Provider {
-
-        public Source getSource();
-    }
-
-    public void setSourceNodes(List<InputNode> sourceNodes) {
-        this.sourceNodes = sourceNodes;
-        set = null;
-    }
-
-    public void addSourceNodes(Source s) {
-        for (InputNode n : s.getSourceNodes()) {
-            sourceNodes.add(n);
-        }
-        set = null;
-    }
-
-    public boolean isInBlock(InputGraph g, InputBlock blockNode) {
-
-        for (InputNode n : this.getSourceNodes()) {
-            if (g.getBlock(n) == blockNode) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/SuccessorSelector.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/SuccessorSelector.java	Mon Feb 27 13:10:13 2012 +0100
@@ -38,9 +38,10 @@
         this.innerSelector = innerSelector;
     }
 
+    @Override
     public List<Figure> selected(Diagram d) {
         List<Figure> inner = innerSelector.selected(d);
-        List<Figure> result = new ArrayList<Figure>();
+        List<Figure> result = new ArrayList<>();
         for (Figure f : d.getFigures()) {
             boolean saved = false;
             for (Figure f2 : f.getPredecessors()) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/services/DiagramProvider.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.graph.services;
+
+import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.graph.Diagram;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface DiagramProvider {
+    Diagram getDiagram();
+    ChangedEvent<DiagramProvider> getChangedEvent();
+
+}
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/nbproject/project.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterEdge.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.hierarchicallayout;
-
-import com.sun.hotspot.igv.layout.Link;
-import com.sun.hotspot.igv.layout.Port;
-import java.awt.Point;
-import java.util.List;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class ClusterEdge implements Link {
-
-    private ClusterNode from;
-    private ClusterNode to;
-    private List<Point> points;
-
-    public ClusterEdge(ClusterNode from, ClusterNode to) {
-        assert from != null;
-        assert to != null;
-        this.from = from;
-        this.to = to;
-    }
-
-    public Port getTo() {
-        return to.getInputSlot();
-    }
-
-    public Port getFrom() {
-        return from.getInputSlot();
-    }
-
-    public void setControlPoints(List<Point> p) {
-        this.points = p;
-    }
-
-    public List<Point> getControlPoints() {
-        return points;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterIngoingConnection.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.hierarchicallayout;
-
-import com.sun.hotspot.igv.layout.Link;
-import com.sun.hotspot.igv.layout.Port;
-import java.awt.Point;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class ClusterIngoingConnection implements Link {
-
-    private List<Point> controlPoints;
-    private ClusterInputSlotNode inputSlotNode;
-    private Link connection;
-    private Port inputSlot;
-    private Port outputSlot;
-
-    public ClusterIngoingConnection(ClusterInputSlotNode inputSlotNode, Link c) {
-        this.inputSlotNode = inputSlotNode;
-        this.connection = c;
-        this.controlPoints = new ArrayList<Point>();
-
-        inputSlot = c.getTo();
-        outputSlot = inputSlotNode.getOutputSlot();
-    }
-
-    public Link getConnection() {
-        return connection;
-    }
-
-    public ClusterInputSlotNode getInputSlotNode() {
-        return inputSlotNode;
-    }
-
-    public Port getTo() {
-        return inputSlot;
-    }
-
-    public Port getFrom() {
-        return outputSlot;
-    }
-
-    public void setControlPoints(List<Point> p) {
-        this.controlPoints = p;
-    }
-
-    public List<Point> getControlPoints() {
-        return controlPoints;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterInputSlotNode.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.hierarchicallayout;
-
-import com.sun.hotspot.igv.layout.Cluster;
-import com.sun.hotspot.igv.layout.Port;
-import com.sun.hotspot.igv.layout.Vertex;
-import java.awt.Dimension;
-import java.awt.Point;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class ClusterInputSlotNode implements Vertex {
-
-    private final int SIZE = 0;
-    private Point position;
-    private Port inputSlot;
-    private Port outputSlot;
-    private ClusterNode blockNode;
-    private InterClusterConnection interBlockConnection;
-    private Cluster cluster;
-    private ClusterIngoingConnection conn;
-
-    public void setIngoingConnection(ClusterIngoingConnection c) {
-        conn = c;
-    }
-
-    public ClusterIngoingConnection getIngoingConnection() {
-        return conn;
-    }
-    private String id;
-
-    @Override
-    public String toString() {
-        return id;
-    }
-
-    public ClusterInputSlotNode(ClusterNode n, String id) {
-        this.blockNode = n;
-        this.id = id;
-
-        n.addSubNode(this);
-
-        final Vertex thisNode = this;
-        final ClusterNode thisBlockNode = blockNode;
-
-        outputSlot = new Port() {
-
-            public Point getRelativePosition() {
-                return new Point(0, 0);
-            }
-
-            public Vertex getVertex() {
-                return thisNode;
-            }
-
-            @Override
-            public String toString() {
-                return "OutPort of " + thisNode.toString();
-            }
-        };
-
-        inputSlot = new Port() {
-
-            public Point getRelativePosition() {
-                Point p = new Point(thisNode.getPosition());
-                p.x += ClusterNode.BORDER;
-                p.y = 0;
-                return p;
-            }
-
-            public Vertex getVertex() {
-                return thisBlockNode;
-            }
-
-            @Override
-            public String toString() {
-                return "InPort of " + thisNode.toString();
-            }
-        };
-    }
-
-    public Port getInputSlot() {
-        return inputSlot;
-    }
-
-    public InterClusterConnection getInterBlockConnection() {
-        return interBlockConnection;
-    }
-
-    public Port getOutputSlot() {
-        return outputSlot;
-    }
-
-    public Dimension getSize() {
-        return new Dimension(SIZE, SIZE);
-    }
-
-    public void setPosition(Point p) {
-        this.position = p;
-    }
-
-    public Point getPosition() {
-        return position;
-    }
-
-    public void setInterBlockConnection(InterClusterConnection interBlockConnection) {
-        this.interBlockConnection = interBlockConnection;
-    }
-
-    public Cluster getCluster() {
-        return cluster;
-    }
-
-    public boolean isRoot() {
-        return true;
-    }
-
-    public int compareTo(Vertex o) {
-        return toString().compareTo(o.toString());
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,233 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.hierarchicallayout;
-
-import com.sun.hotspot.igv.layout.Cluster;
-import com.sun.hotspot.igv.layout.Link;
-import com.sun.hotspot.igv.layout.Port;
-import com.sun.hotspot.igv.layout.Vertex;
-import java.awt.Dimension;
-import java.awt.Point;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class ClusterNode implements Vertex {
-
-    private Cluster cluster;
-    private Port inputSlot;
-    private Port outputSlot;
-    private Set<Vertex> subNodes;
-    private Dimension size;
-    private Point position;
-    private Set<Link> subEdges;
-    private boolean dirty;
-    private boolean root;
-    private String name;
-    public static final int BORDER = 20;
-
-    public ClusterNode(Cluster cluster, String name) {
-        this.subNodes = new HashSet<Vertex>();
-        this.subEdges = new HashSet<Link>();
-        this.cluster = cluster;
-        position = new Point(0, 0);
-        this.name = name;
-    }
-
-    public void addSubNode(Vertex v) {
-        subNodes.add(v);
-    }
-
-    public void addSubEdge(Link l) {
-        subEdges.add(l);
-    }
-
-    public Set<Link> getSubEdges() {
-        return Collections.unmodifiableSet(subEdges);
-    }
-
-    public void updateSize() {
-
-
-        calculateSize();
-
-        final ClusterNode widget = this;
-        inputSlot = new Port() {
-
-            public Point getRelativePosition() {
-                return new Point(size.width / 2, 0);
-            }
-
-            public Vertex getVertex() {
-                return widget;
-            }
-        };
-
-        outputSlot = new Port() {
-
-            public Point getRelativePosition() {
-                return new Point(size.width / 2, size.height);
-            }
-
-            public Vertex getVertex() {
-                return widget;
-            }
-        };
-    }
-
-    private void calculateSize() {
-
-        if (subNodes.size() == 0) {
-            size = new Dimension(0, 0);
-        }
-
-        int minX = Integer.MAX_VALUE;
-        int maxX = Integer.MIN_VALUE;
-        int minY = Integer.MAX_VALUE;
-        int maxY = Integer.MIN_VALUE;
-
-
-        for (Vertex n : subNodes) {
-            Point p = n.getPosition();
-            minX = Math.min(minX, p.x);
-            minY = Math.min(minY, p.y);
-            maxX = Math.max(maxX, p.x + n.getSize().width);
-            maxY = Math.max(maxY, p.y + n.getSize().height);
-        }
-
-        for (Link l : subEdges) {
-            List<Point> points = l.getControlPoints();
-            for (Point p : points) {
-                if (p != null) {
-                    minX = Math.min(minX, p.x);
-                    maxX = Math.max(maxX, p.x);
-                    minY = Math.min(minY, p.y);
-                    maxY = Math.max(maxY, p.y);
-                }
-            }
-        }
-
-        size = new Dimension(maxX - minX, maxY - minY);
-
-        // Normalize coordinates
-        for (Vertex n : subNodes) {
-            n.setPosition(new Point(n.getPosition().x - minX, n.getPosition().y - minY));
-        }
-
-        for (Link l : subEdges) {
-            List<Point> points = new ArrayList<Point>(l.getControlPoints());
-            for (Point p : points) {
-                p.x -= minX;
-                p.y -= minY;
-            }
-            l.setControlPoints(points);
-
-        }
-
-        size.width += 2 * BORDER;
-        size.height += 2 * BORDER;
-    }
-
-    public Port getInputSlot() {
-        return inputSlot;
-
-    }
-
-    public Port getOutputSlot() {
-        return outputSlot;
-    }
-
-    public Dimension getSize() {
-        return size;
-    }
-
-    public Point getPosition() {
-        return position;
-    }
-
-    public void setPosition(Point pos) {
-
-        this.position = pos;
-        for (Vertex n : subNodes) {
-            Point cur = new Point(n.getPosition());
-            cur.translate(pos.x + BORDER, pos.y + BORDER);
-            n.setPosition(cur);
-        }
-
-        for (Link e : subEdges) {
-            List<Point> arr = e.getControlPoints();
-            ArrayList<Point> newArr = new ArrayList<Point>();
-            for (Point p : arr) {
-                if (p != null) {
-                    Point p2 = new Point(p);
-                    p2.translate(pos.x + BORDER, pos.y + BORDER);
-                    newArr.add(p2);
-                } else {
-                    newArr.add(null);
-                }
-            }
-
-            e.setControlPoints(newArr);
-        }
-    }
-
-    public Cluster getCluster() {
-        return cluster;
-    }
-
-    public void setCluster(Cluster c) {
-        cluster = c;
-    }
-
-    public void setDirty(boolean b) {
-        dirty = b;
-    }
-
-    public void setRoot(boolean b) {
-        root = b;
-    }
-
-    public boolean isRoot() {
-        return root;
-    }
-
-    public int compareTo(Vertex o) {
-        return toString().compareTo(o.toString());
-    }
-
-    @Override
-    public String toString() {
-        return name;
-    }
-
-    public Set<? extends Vertex> getSubNodes() {
-        return subNodes;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterOutgoingConnection.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.hierarchicallayout;
-
-import com.sun.hotspot.igv.layout.Link;
-import com.sun.hotspot.igv.layout.Port;
-import java.awt.Point;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class ClusterOutgoingConnection implements Link {
-
-    private List<Point> intermediatePoints;
-    private ClusterOutputSlotNode outputSlotNode;
-    private Link connection;
-    private Port inputSlot;
-    private Port outputSlot;
-
-    public ClusterOutgoingConnection(ClusterOutputSlotNode outputSlotNode, Link c) {
-        this.outputSlotNode = outputSlotNode;
-        this.connection = c;
-        this.intermediatePoints = new ArrayList<Point>();
-
-        outputSlot = c.getFrom();
-        inputSlot = outputSlotNode.getInputSlot();
-    }
-
-    public Port getTo() {
-        return inputSlot;
-    }
-
-    public Port getFrom() {
-        return outputSlot;
-    }
-
-    public void setControlPoints(List<Point> p) {
-        this.intermediatePoints = p;
-    }
-
-    public List<Point> getControlPoints() {
-        return intermediatePoints;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterOutputSlotNode.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.hierarchicallayout;
-
-import com.sun.hotspot.igv.layout.Cluster;
-import com.sun.hotspot.igv.layout.Port;
-import com.sun.hotspot.igv.layout.Vertex;
-import java.awt.Dimension;
-import java.awt.Point;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class ClusterOutputSlotNode implements Vertex {
-
-    private final int SIZE = 0;
-    private Point position;
-    private Port inputSlot;
-    private Port outputSlot;
-    private ClusterNode blockNode;
-    private boolean root;
-    private Cluster cluster;
-    private ClusterOutgoingConnection conn;
-    private String id;
-
-    public void setOutgoingConnection(ClusterOutgoingConnection c) {
-        this.conn = c;
-    }
-
-    public ClusterOutgoingConnection getOutgoingConnection() {
-        return conn;
-    }
-
-    @Override
-    public String toString() {
-        return id;
-    }
-
-    public ClusterOutputSlotNode(ClusterNode n, String id) {
-        this.blockNode = n;
-        this.id = id;
-
-        n.addSubNode(this);
-
-        final Vertex thisNode = this;
-        final ClusterNode thisBlockNode = blockNode;
-
-        inputSlot = new Port() {
-
-            public Point getRelativePosition() {
-                return new Point(0, 0);
-            }
-
-            public Vertex getVertex() {
-                return thisNode;
-            }
-
-            @Override
-            public String toString() {
-                return "InPort of " + thisNode.toString();
-            }
-        };
-
-        outputSlot = new Port() {
-
-            public Point getRelativePosition() {
-                Point p = new Point(thisNode.getPosition());
-                p.x += ClusterNode.BORDER;
-                p.y = thisBlockNode.getSize().height;
-                return p;
-            }
-
-            public Vertex getVertex() {
-                return thisBlockNode;
-            }
-
-            @Override
-            public String toString() {
-                return "OutPort of " + thisNode.toString();
-            }
-        };
-    }
-
-    public Dimension getSize() {
-        return new Dimension(SIZE, SIZE);
-    }
-
-    public void setPosition(Point p) {
-        this.position = p;
-    }
-
-    public Point getPosition() {
-        return position;
-    }
-
-    public Port getInputSlot() {
-        return inputSlot;
-    }
-
-    public Port getOutputSlot() {
-        return outputSlot;
-    }
-
-    public void setCluster(Cluster c) {
-        cluster = c;
-    }
-
-    public void setRoot(boolean b) {
-        root = b;
-    }
-
-    public Cluster getCluster() {
-        return cluster;
-    }
-
-    public boolean isRoot() {
-        return root;
-    }
-
-    public int compareTo(Vertex o) {
-        return toString().compareTo(o.toString());
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Edge.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Edge.java	Mon Feb 27 13:10:13 2012 +0100
@@ -83,6 +83,7 @@
         dest.addInEdge(this);
     }
 
+    @Override
     public String toString() {
         return "Edge (" + source + " -- " + dest + "): " + data;
     }
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Graph.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Graph.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,13 +23,7 @@
  */
 package com.sun.hotspot.igv.hierarchicallayout;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
+import java.util.*;
 
 /**
  *
@@ -42,13 +36,13 @@
     private List<Node<N, E>> nodeList;
 
     public Graph() {
-        nodes = new HashMap<Object, Node<N, E>>();
-        edges = new HashMap<Object, Edge<N, E>>();
-        nodeList = new ArrayList<Node<N, E>>();
+        nodes = new HashMap<>();
+        edges = new HashMap<>();
+        nodeList = new ArrayList<>();
     }
 
     public Node<N, E> createNode(N data, Object key) {
-        Node<N, E> n = new Node<N, E>(this, data);
+        Node<N, E> n = new Node<>(this, data);
         assert key == null || !nodes.containsKey(key);
         if (key != null) {
             nodes.put(key, n);
@@ -58,7 +52,7 @@
     }
 
     public Edge<N, E> createEdge(Node<N, E> source, Node<N, E> dest, E data, Object key) {
-        Edge<N, E> e = new Edge<N, E>(this, source, dest, data);
+        Edge<N, E> e = new Edge<>(this, source, dest, data);
         source.addOutEdge(e);
         dest.addInEdge(e);
         if (key != null) {
@@ -114,7 +108,7 @@
 
     public List<Node<N, E>> getNodesWithInDegree(int x, boolean countSelfLoops) {
 
-        List<Node<N, E>> result = new ArrayList<Node<N, E>>();
+        List<Node<N, E>> result = new ArrayList<>();
         for (Node<N, E> n : getNodes()) {
             if (n.getInDegree(countSelfLoops) == x) {
                 result.add(n);
@@ -126,7 +120,7 @@
     }
 
     private void markReachable(Node<N, E> startingNode) {
-        ArrayList<Node<N, E>> arr = new ArrayList<Node<N, E>>();
+        ArrayList<Node<N, E>> arr = new ArrayList<>();
         arr.add(startingNode);
         for (Node<N, E> n : getNodes()) {
             n.setReachable(false);
@@ -151,7 +145,7 @@
             n.setActive(false);
         }
 
-        Queue<Node<N, E>> queue = new LinkedList<Node<N, E>>();
+        Queue<Node<N, E>> queue = new LinkedList<>();
         queue.add(startingNode);
         startingNode.setVisited(true);
         int layer = 0;
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalClusterLayoutManager.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,247 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.hierarchicallayout;
-
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Set;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.TreeSet;
-import com.sun.hotspot.igv.layout.Cluster;
-import com.sun.hotspot.igv.layout.LayoutGraph;
-import com.sun.hotspot.igv.layout.LayoutManager;
-import com.sun.hotspot.igv.layout.Link;
-import com.sun.hotspot.igv.layout.Port;
-import com.sun.hotspot.igv.layout.Vertex;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class HierarchicalClusterLayoutManager implements LayoutManager {
-
-    private OldHierarchicalLayoutManager.Combine combine;
-    private LayoutManager subManager = new OldHierarchicalLayoutManager(combine);
-    private LayoutManager manager = new OldHierarchicalLayoutManager(combine, 150);
-    private static final boolean TRACE = false;
-
-    public HierarchicalClusterLayoutManager(OldHierarchicalLayoutManager.Combine combine) {
-        this.combine = combine;
-    }
-
-    public void doLayout(LayoutGraph graph) {
-        doLayout(graph, new HashSet<Vertex>(), new HashSet<Vertex>(), new HashSet<Link>());
-    }
-
-    public void setSubManager(LayoutManager manager) {
-        this.subManager = manager;
-    }
-
-    public void setManager(LayoutManager manager) {
-        this.manager = manager;
-    }
-
-    public void doLayout(LayoutGraph graph, Set<? extends Vertex> firstLayerHint, Set<? extends Vertex> lastLayerHint, Set<? extends Link> importantLinks) {
-
-        assert graph.verify();
-
-        HashMap<Cluster, List<Vertex>> lists = new HashMap<Cluster, List<Vertex>>();
-        HashMap<Cluster, List<Link>> listsConnection = new HashMap<Cluster, List<Link>>();
-        HashMap<Cluster, HashMap<Port, ClusterInputSlotNode>> clusterInputSlotHash = new HashMap<Cluster, HashMap<Port, ClusterInputSlotNode>>();
-        HashMap<Cluster, HashMap<Port, ClusterOutputSlotNode>> clusterOutputSlotHash = new HashMap<Cluster, HashMap<Port, ClusterOutputSlotNode>>();
-
-        HashMap<Cluster, ClusterNode> clusterNodes = new HashMap<Cluster, ClusterNode>();
-        HashMap<Cluster, Set<ClusterInputSlotNode>> clusterInputSlotSet = new HashMap<Cluster, Set<ClusterInputSlotNode>>();
-        HashMap<Cluster, Set<ClusterOutputSlotNode>> clusterOutputSlotSet = new HashMap<Cluster, Set<ClusterOutputSlotNode>>();
-        Set<Link> clusterEdges = new HashSet<Link>();
-        Set<Link> interClusterEdges = new HashSet<Link>();
-        HashMap<Link, ClusterOutgoingConnection> linkClusterOutgoingConnection = new HashMap<Link, ClusterOutgoingConnection>();
-        HashMap<Link, InterClusterConnection> linkInterClusterConnection = new HashMap<Link, InterClusterConnection>();
-        HashMap<Link, ClusterIngoingConnection> linkClusterIngoingConnection = new HashMap<Link, ClusterIngoingConnection>();
-        Set<ClusterNode> clusterNodeSet = new HashSet<ClusterNode>();
-
-        Set<Cluster> cluster = graph.getClusters();
-        int z = 0;
-        for (Cluster c : cluster) {
-            lists.put(c, new ArrayList<Vertex>());
-            listsConnection.put(c, new ArrayList<Link>());
-            clusterInputSlotHash.put(c, new HashMap<Port, ClusterInputSlotNode>());
-            clusterOutputSlotHash.put(c, new HashMap<Port, ClusterOutputSlotNode>());
-            clusterOutputSlotSet.put(c, new TreeSet<ClusterOutputSlotNode>());
-            clusterInputSlotSet.put(c, new TreeSet<ClusterInputSlotNode>());
-            ClusterNode cn = new ClusterNode(c, "" + z);
-            clusterNodes.put(c, cn);
-            clusterNodeSet.add(cn);
-            z++;
-        }
-
-        // Add cluster edges
-        for (Cluster c : cluster) {
-
-            ClusterNode start = clusterNodes.get(c);
-
-            for (Cluster succ : c.getSuccessors()) {
-                ClusterNode end = clusterNodes.get(succ);
-                if (end != null && start != end) {
-                    ClusterEdge e = new ClusterEdge(start, end);
-                    clusterEdges.add(e);
-                    interClusterEdges.add(e);
-                }
-            }
-        }
-
-        for (Vertex v : graph.getVertices()) {
-            Cluster c = v.getCluster();
-            assert c != null;
-            clusterNodes.get(c).addSubNode(v);
-        }
-
-        for (Link l : graph.getLinks()) {
-
-            Port fromPort = l.getFrom();
-            Port toPort = l.getTo();
-            Vertex fromVertex = fromPort.getVertex();
-            Vertex toVertex = toPort.getVertex();
-            Cluster fromCluster = fromVertex.getCluster();
-            Cluster toCluster = toVertex.getCluster();
-
-            Port samePort = null;
-            if (combine == OldHierarchicalLayoutManager.Combine.SAME_INPUTS) {
-                samePort = toPort;
-            } else if (combine == OldHierarchicalLayoutManager.Combine.SAME_OUTPUTS) {
-                samePort = fromPort;
-            }
-
-            assert listsConnection.containsKey(fromCluster);
-            assert listsConnection.containsKey(toCluster);
-
-            if (fromCluster == toCluster) {
-                listsConnection.get(fromCluster).add(l);
-                clusterNodes.get(fromCluster).addSubEdge(l);
-            } else {
-                ClusterInputSlotNode inputSlotNode = null;
-                ClusterOutputSlotNode outputSlotNode = null;
-
-                if (samePort != null) {
-                    outputSlotNode = clusterOutputSlotHash.get(fromCluster).get(samePort);
-                    inputSlotNode = clusterInputSlotHash.get(toCluster).get(samePort);
-                }
-
-                if (outputSlotNode == null) {
-                    outputSlotNode = new ClusterOutputSlotNode(clusterNodes.get(fromCluster), "Out " + fromCluster.toString() + " " + samePort.toString());
-                    clusterOutputSlotSet.get(fromCluster).add(outputSlotNode);
-                    ClusterOutgoingConnection conn = new ClusterOutgoingConnection(outputSlotNode, l);
-                    outputSlotNode.setOutgoingConnection(conn);
-                    clusterNodes.get(fromCluster).addSubEdge(conn);
-                    if (samePort != null) {
-                        clusterOutputSlotHash.get(fromCluster).put(samePort, outputSlotNode);
-                    }
-
-                    linkClusterOutgoingConnection.put(l, conn);
-                } else {
-                    linkClusterOutgoingConnection.put(l, outputSlotNode.getOutgoingConnection());
-                }
-
-                if (inputSlotNode == null) {
-                    inputSlotNode = new ClusterInputSlotNode(clusterNodes.get(toCluster), "In " + toCluster.toString() + " " + samePort.toString());
-                    clusterInputSlotSet.get(toCluster).add(inputSlotNode);
-                }
-
-                ClusterIngoingConnection conn = new ClusterIngoingConnection(inputSlotNode, l);
-                inputSlotNode.setIngoingConnection(conn);
-                clusterNodes.get(toCluster).addSubEdge(conn);
-                if (samePort != null) {
-                    clusterInputSlotHash.get(toCluster).put(samePort, inputSlotNode);
-                }
-
-                linkClusterIngoingConnection.put(l, conn);
-
-
-                InterClusterConnection interConn = new InterClusterConnection(outputSlotNode, inputSlotNode);
-                linkInterClusterConnection.put(l, interConn);
-                clusterEdges.add(interConn);
-            }
-        }
-
-        Timing t = null;
-
-        if (TRACE) {
-            new Timing("Child timing");
-            t.start();
-        }
-
-        for (Cluster c : cluster) {
-            ClusterNode n = clusterNodes.get(c);
-            subManager.doLayout(new LayoutGraph(n.getSubEdges(), n.getSubNodes()), clusterInputSlotSet.get(c), clusterOutputSlotSet.get(c), new HashSet<Link>());
-            n.updateSize();
-        }
-
-        Set<Vertex> roots = new LayoutGraph(interClusterEdges).findRootVertices();
-        for (Vertex v : roots) {
-            assert v instanceof ClusterNode;
-            ((ClusterNode) v).setRoot(true);
-        }
-
-        manager.doLayout(new LayoutGraph(clusterEdges, clusterNodeSet), new HashSet<Vertex>(), new HashSet<Vertex>(), interClusterEdges);
-
-        for (Cluster c : cluster) {
-            ClusterNode n = clusterNodes.get(c);
-            c.setBounds(new Rectangle(n.getPosition(), n.getSize()));
-        }
-
-        // TODO: handle case where blocks are not fully connected
-
-        if (TRACE) {
-            t.stop();
-            t.print();
-        }
-
-        for (Link l : graph.getLinks()) {
-
-            if (linkInterClusterConnection.containsKey(l)) {
-                ClusterOutgoingConnection conn1 = linkClusterOutgoingConnection.get(l);
-                InterClusterConnection conn2 = linkInterClusterConnection.get(l);
-                ClusterIngoingConnection conn3 = linkClusterIngoingConnection.get(l);
-
-                assert conn1 != null;
-                assert conn2 != null;
-                assert conn3 != null;
-
-                List<Point> points = new ArrayList<Point>();
-
-                points.addAll(conn1.getControlPoints());
-                points.addAll(conn2.getControlPoints());
-                points.addAll(conn3.getControlPoints());
-
-                l.setControlPoints(points);
-            }
-        }
-    }
-
-    public void doRouting(LayoutGraph graph) {
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java	Mon Feb 27 13:10:13 2012 +0100
@@ -29,18 +29,7 @@
 import com.sun.hotspot.igv.layout.Vertex;
 import java.awt.Dimension;
 import java.awt.Point;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.Stack;
-import java.util.TreeSet;
+import java.util.*;
 
 /**
  *
@@ -58,6 +47,7 @@
     public static final int LAYER_OFFSET = 30;
     public static final int MAX_LAYER_LENGTH = -1;
     public static final int MIN_LAYER_DIFFERENCE = 1;
+    public static final int VIP_BONUS = 10;
 
     public enum Combine {
 
@@ -101,11 +91,13 @@
         public int yOffset;
         public int bottomYOffset;
         public Vertex vertex; // Only used for non-dummy nodes, otherwise null
-        public List<LayoutEdge> preds = new ArrayList<LayoutEdge>();
-        public List<LayoutEdge> succs = new ArrayList<LayoutEdge>();
-        public HashMap<Integer, Integer> outOffsets = new HashMap<Integer, Integer>();
-        public HashMap<Integer, Integer> inOffsets = new HashMap<Integer, Integer>();
+
+        public List<LayoutEdge> preds = new ArrayList<>();
+        public List<LayoutEdge> succs = new ArrayList<>();
+        public HashMap<Integer, Integer> outOffsets = new HashMap<>();
+        public HashMap<Integer, Integer> inOffsets = new HashMap<>();
         public int pos = -1; // Position within layer
+
         public int crossingNumber;
 
         @Override
@@ -121,6 +113,7 @@
         public int relativeFrom;
         public int relativeTo;
         public Link link;
+        public boolean vip;
     }
 
     private abstract class AlgorithmPart {
@@ -171,7 +164,7 @@
         this.layerOffset = LAYER_OFFSET;
         this.maxLayerLength = MAX_LAYER_LENGTH;
         this.minLayerDifference = MIN_LAYER_DIFFERENCE;
-        this.linksToFollow = new HashSet<Link>();
+        this.linksToFollow = new HashSet<>();
     }
 
     public int getMaxLayerLength() {
@@ -186,11 +179,13 @@
         minLayerDifference = v;
     }
 
+    @Override
     public void doLayout(LayoutGraph graph) {
         doLayout(graph, new HashSet<Vertex>(), new HashSet<Vertex>(), new HashSet<Link>());
 
     }
 
+    @Override
     public void doLayout(LayoutGraph graph, Set<? extends Vertex> firstLayerHint, Set<? extends Vertex> lastLayerHint, Set<? extends Link> importantLinks) {
 
         this.importantLinks = importantLinks;
@@ -198,14 +193,14 @@
         this.firstLayerHint = firstLayerHint;
         this.lastLayerHint = lastLayerHint;
 
-        vertexToLayoutNode = new HashMap<Vertex, LayoutNode>();
-        reversedLinks = new HashSet<Link>();
-        reversedLinkStartPoints = new HashMap<Link, List<Point>>();
-        reversedLinkEndPoints = new HashMap<Link, List<Point>>();
-        bottomEdgeHash = new HashMap<LayoutEdge, LayoutEdge>();
-        nodes = new ArrayList<LayoutNode>();
-        splitStartPoints = new HashMap<Link, List<Point>>();
-        splitEndPoints = new HashMap<Link, List<Point>>();
+        vertexToLayoutNode = new HashMap<>();
+        reversedLinks = new HashSet<>();
+        reversedLinkStartPoints = new HashMap<>();
+        reversedLinkEndPoints = new HashMap<>();
+        bottomEdgeHash = new HashMap<>();
+        nodes = new ArrayList<>();
+        splitStartPoints = new HashMap<>();
+        splitEndPoints = new HashMap<>();
 
         // #############################################################
         // Step 1: Build up data structure
@@ -216,7 +211,7 @@
         new ReverseEdges().start();
 
         for (LayoutNode n : nodes) {
-            ArrayList<LayoutEdge> tmpArr = new ArrayList<LayoutEdge>();
+            ArrayList<LayoutEdge> tmpArr = new ArrayList<>();
             for (LayoutEdge e : n.succs) {
                 if (importantLinks.contains(e.link)) {
                     tmpArr.add(e);
@@ -244,8 +239,7 @@
 
         // #############################################################
         // STEP 7: Assign X coordinates
-        //new AssignXCoordinates().start();
-        new AssignXCoordinates2().start();
+        new AssignXCoordinates().start();
 
         // #############################################################
         // STEP 6: Assign Y coordinates
@@ -260,10 +254,11 @@
 
         private int pointCount;
 
+        @Override
         protected void run() {
 
-            HashMap<Vertex, Point> vertexPositions = new HashMap<Vertex, Point>();
-            HashMap<Link, List<Point>> linkPositions = new HashMap<Link, List<Point>>();
+            HashMap<Vertex, Point> vertexPositions = new HashMap<>();
+            HashMap<Link, List<Point>> linkPositions = new HashMap<>();
             for (Vertex v : graph.getVertices()) {
                 LayoutNode n = vertexToLayoutNode.get(v);
                 assert !vertexPositions.containsKey(v);
@@ -274,12 +269,12 @@
 
                 for (LayoutEdge e : n.preds) {
                     if (e.link != null) {
-                        ArrayList<Point> points = new ArrayList<Point>();
+                        ArrayList<Point> points = new ArrayList<>();
 
-                        Point p = new Point(e.to.x + e.relativeTo, e.to.y + e.to.yOffset);
+                        Point p = new Point(e.to.x + e.relativeTo, e.to.y + e.to.yOffset + e.link.getTo().getRelativePosition().y);
                         points.add(p);
                         if (e.to.inOffsets.containsKey(e.relativeTo)) {
-                            points.add(new Point(p.x, p.y + e.to.inOffsets.get(e.relativeTo)));
+                            points.add(new Point(p.x, p.y + e.to.inOffsets.get(e.relativeTo) + e.link.getTo().getRelativePosition().y));
                         }
 
                         LayoutNode cur = e.from;
@@ -299,9 +294,9 @@
                             cur = curEdge.from;
                         }
 
-                        p = new Point(cur.x + curEdge.relativeFrom, cur.y + cur.height - cur.bottomYOffset);
+                        p = new Point(cur.x + curEdge.relativeFrom, cur.y + cur.height - cur.bottomYOffset + (curEdge.link == null ? 0 : curEdge.link.getFrom().getRelativePosition().y));
                         if (curEdge.from.outOffsets.containsKey(curEdge.relativeFrom)) {
-                            points.add(new Point(p.x, p.y + curEdge.from.outOffsets.get(curEdge.relativeFrom)));
+                            points.add(new Point(p.x, p.y + curEdge.from.outOffsets.get(curEdge.relativeFrom) + (curEdge.link == null ? 0 : curEdge.link.getFrom().getRelativePosition().y)));
                         }
                         points.add(p);
 
@@ -359,11 +354,11 @@
 
                 for (LayoutEdge e : n.succs) {
                     if (e.link != null) {
-                        ArrayList<Point> points = new ArrayList<Point>();
-                        Point p = new Point(e.from.x + e.relativeFrom, e.from.y + e.from.height - e.from.bottomYOffset);
+                        ArrayList<Point> points = new ArrayList<>();
+                        Point p = new Point(e.from.x + e.relativeFrom, e.from.y + e.from.height - e.from.bottomYOffset + e.link.getFrom().getRelativePosition().y);
                         points.add(p);
                         if (e.from.outOffsets.containsKey(e.relativeFrom)) {
-                            points.add(new Point(p.x, p.y + e.from.outOffsets.get(e.relativeFrom)));
+                            points.add(new Point(p.x, p.y + e.from.outOffsets.get(e.relativeFrom) + e.link.getFrom().getRelativePosition().y));
                         }
 
                         LayoutNode cur = e.to;
@@ -387,10 +382,10 @@
                         }
 
 
-                        p = new Point(cur.x + curEdge.relativeTo, cur.y + cur.yOffset);
+                        p = new Point(cur.x + curEdge.relativeTo, cur.y + cur.yOffset + ((curEdge.link == null) ? 0 : curEdge.link.getTo().getRelativePosition().y));
                         points.add(p);
                         if (curEdge.to.inOffsets.containsKey(curEdge.relativeTo)) {
-                            points.add(new Point(p.x, p.y + curEdge.to.inOffsets.get(curEdge.relativeTo)));
+                            points.add(new Point(p.x, p.y + curEdge.to.inOffsets.get(curEdge.relativeTo) + ((curEdge.link == null) ? 0 : curEdge.link.getTo().getRelativePosition().y)));
                         }
 
 
@@ -495,13 +490,14 @@
 
         public float d;
         public int orderNumber = -1;
-        public ArrayList<LayoutNode> nodes = new ArrayList<LayoutNode>();
-        public HashSet<Segment> succs = new HashSet<Segment>();
-        public HashSet<Segment> preds = new HashSet<Segment>();
+        public ArrayList<LayoutNode> nodes = new ArrayList<>();
+        public HashSet<Segment> succs = new HashSet<>();
+        public HashSet<Segment> preds = new HashSet<>();
         public Region region;
     }
     private static final Comparator<Segment> segmentComparator = new Comparator<Segment>() {
 
+        @Override
         public int compare(Segment s1, Segment s2) {
             return s1.orderNumber - s2.orderNumber;
         }
@@ -511,26 +507,31 @@
 
         public float d;
         public int minOrderNumber;
-        public SortedSet<Segment> segments = new TreeSet<Segment>(segmentComparator);
-        public HashSet<Region> succs = new HashSet<Region>(4);
-        public HashSet<Region> preds = new HashSet<Region>(4);
+        public SortedSet<Segment> segments = new TreeSet<>(segmentComparator);
+        public HashSet<Region> succs = new HashSet<>(4);
+        public HashSet<Region> preds = new HashSet<>(4);
     }
     private static final Comparator<Region> regionComparator = new Comparator<Region>() {
 
+        @Override
         public int compare(Region r1, Region r2) {
             return r1.minOrderNumber - r2.minOrderNumber;
         }
     };
     private static final Comparator<LayoutNode> nodePositionComparator = new Comparator<LayoutNode>() {
 
+        @Override
         public int compare(LayoutNode n1, LayoutNode n2) {
             return n1.pos - n2.pos;
         }
     };
     private static final Comparator<LayoutNode> nodeProcessingDownComparator = new Comparator<LayoutNode>() {
-
+        @Override
         public int compare(LayoutNode n1, LayoutNode n2) {
             if (n1.vertex == null) {
+                if (n2.vertex == null) {
+                    return 0;
+                }
                 return -1;
             }
             if (n2.vertex == null) {
@@ -541,8 +542,12 @@
     };
     private static final Comparator<LayoutNode> nodeProcessingUpComparator = new Comparator<LayoutNode>() {
 
+        @Override
         public int compare(LayoutNode n1, LayoutNode n2) {
             if (n1.vertex == null) {
+                if (n2.vertex == null) {
+                    return 0;
+                }
                 return -1;
             }
             if (n2.vertex == null) {
@@ -552,7 +557,7 @@
         }
     };
 
-    private class AssignXCoordinates2 extends AlgorithmPart {
+    private class AssignXCoordinates extends AlgorithmPart {
 
         private ArrayList<Integer>[] space;
         private ArrayList<LayoutNode>[] downProcessingOrder;
@@ -563,17 +568,22 @@
                 n.x = space[n.layer].get(n.pos);
             }
         }
-
-        protected void run() {
-
+        
+        @SuppressWarnings("unchecked")
+        private void createArrays() {
             space = new ArrayList[layers.length];
             downProcessingOrder = new ArrayList[layers.length];
             upProcessingOrder = new ArrayList[layers.length];
+        }
+
+        @Override
+        protected void run() {
+            createArrays();
 
             for (int i = 0; i < layers.length; i++) {
-                space[i] = new ArrayList<Integer>();
-                downProcessingOrder[i] = new ArrayList<LayoutNode>();
-                upProcessingOrder[i] = new ArrayList<LayoutNode>();
+                space[i] = new ArrayList<>();
+                downProcessingOrder[i] = new ArrayList<>();
+                upProcessingOrder[i] = new ArrayList<>();
 
                 int curX = 0;
                 for (LayoutNode n : layers[i]) {
@@ -592,66 +602,72 @@
                 sweepDown();
                 sweepUp();
             }
-
-            for (int i = 0; i < SWEEP_ITERATIONS; i++) {
-                doubleSweep();
-            }
+ 
+            sweepDown();
+            //for (int i = 0; i < SWEEP_ITERATIONS; i++) {
+            //    doubleSweep();
+            //}            
         }
 
         private int calculateOptimalDown(LayoutNode n) {
-
-            List<Integer> values = new ArrayList<Integer>();
-            if (n.preds.size() == 0) {
+            int size = n.preds.size();
+            if (size == 0) {
                 return n.x;
             }
-            for (LayoutEdge e : n.preds) {
-                int cur = e.from.x + e.relativeFrom - e.relativeTo;
-                values.add(cur);
+            int[] values = new int[size];
+            for (int i = 0; i < size; i++) {
+                LayoutEdge e = n.preds.get(i);
+                values[i] = e.from.x + e.relativeFrom - e.relativeTo;
+                if (e.vip) {
+                    return values[i];
+                }
             }
             return median(values);
         }
 
         private int calculateOptimalBoth(LayoutNode n) {
-
-            List<Integer> values = new ArrayList<Integer>();
-            if (n.preds.size() == 0 + n.succs.size()) {
+            if (n.preds.size() == n.succs.size()) {
                 return n.x;
             }
+            
+            int[] values = new int[n.preds.size() + n.succs.size()];
+            int i = 0;
+
             for (LayoutEdge e : n.preds) {
-                int cur = e.from.x + e.relativeFrom - e.relativeTo;
-                values.add(cur);
+                values[i] = e.from.x + e.relativeFrom - e.relativeTo;
+                i++;
             }
 
             for (LayoutEdge e : n.succs) {
-                int cur = e.to.x + e.relativeTo - e.relativeFrom;
-                values.add(cur);
+                values[i] = e.to.x + e.relativeTo - e.relativeFrom;
+                i++;
             }
 
             return median(values);
         }
 
         private int calculateOptimalUp(LayoutNode n) {
-
-            //List<Integer> values = new ArrayList<Integer>();
             int size = n.succs.size();
             if (size == 0) {
                 return n.x;
-            } else {
-                int result = 0;
-                for (LayoutEdge e : n.succs) {
-                    int cur = e.to.x + e.relativeTo - e.relativeFrom;
-                    result += cur;
+            }
+            int[] values = new int[size];
+            for (int i = 0; i < size; i++) {
+                LayoutEdge e = n.succs.get(i);
+                values[i] = e.to.x + e.relativeTo - e.relativeFrom;
+                if (e.vip) {
+                    return values[i];
                 }
-                return result / size; //median(values);
             }
+            return median(values);
         }
 
-        private int median(List<Integer> values) {
-            Collections.sort(values);
-            if (values.size() % 2 == 0) {
-                return (values.get(values.size() / 2 - 1) + values.get(values.size() / 2)) / 2;
+        private int median(int[] values) {
+            Arrays.sort(values);
+            if (values.length % 2 == 0) {
+                return (values[values.length / 2 - 1] + values[values.length / 2]) / 2;
             } else {
-                return values.get(values.size() / 2);
+                return values[values.length / 2];
             }
         }
 
@@ -663,14 +679,6 @@
                     r.insert(n, optimal);
                 }
             }
-        /*
-        for(int i=0; i<layers.length; i++) {
-        NodeRow r = new NodeRow(space[i]);
-        for(LayoutNode n : upProcessingOrder[i]) {
-        int optimal = calculateOptimalUp(n);
-        r.insert(n, optimal);
-        }
-        }*/
         }
 
         private void doubleSweep() {
@@ -700,7 +708,7 @@
         private ArrayList<Integer> space;
 
         public NodeRow(ArrayList<Integer> space) {
-            treeSet = new TreeSet<LayoutNode>(nodePositionComparator);
+            treeSet = new TreeSet<>(nodePositionComparator);
             this.space = space;
         }
 
@@ -745,351 +753,9 @@
             treeSet.add(n);
         }
     }
-
-    private class AssignXCoordinates extends AlgorithmPart {
-
-        HashMap<LayoutNode, Segment> hashMap = new HashMap<LayoutNode, Segment>();
-        ArrayList<Segment> segments = new ArrayList<Segment>();
-
-        private void generateSegments() {
-
-            for (int i = 0; i < layerCount; i++) {
-                for (LayoutNode n : layers[i]) {
-                    if (!hashMap.containsKey(n)) {
-                        Segment s = new Segment();
-                        segments.add(s);
-                        LayoutNode curNode = n;
-
-                        int maxLength = 0;
-                        while (curNode.succs.size() == 1 && curNode.preds.size() == 1) {
-                            s.nodes.add(curNode);
-                            assert !hashMap.containsKey(curNode);
-                            hashMap.put(curNode, s);
-                            curNode = curNode.succs.get(0).to;
-                            maxLength++;
-                        //if(maxLength > 10) break;
-                        }
-
-                        if (s.nodes.size() > 0 && curNode.preds.size() == 1 && curNode.vertex == null) {
-                            s.nodes.add(curNode);
-                            assert !hashMap.containsKey(curNode);
-                            hashMap.put(curNode, s);
-                        }
-
-                        if (s.nodes.size() == 0) {
-                            // Simple segment with a single node
-                            s.nodes.add(n);
-                            hashMap.put(n, s);
-                        }
-                    }
-                }
-            }
-        }
-
-        private void addEdges() {
-
-            for (int i = 0; i < layerCount; i++) {
-                LayoutNode prev = null;
-                for (LayoutNode n : layers[i]) {
-
-                    if (prev != null) {
-                        Segment s1 = hashMap.get(prev);
-                        Segment s2 = hashMap.get(n);
-
-                        if (s1 != s2) {
-                            s1.succs.add(s2);
-                            s2.preds.add(s1);
-                        }
-                    }
-                    prev = n;
-
-                }
-            }
-        }
-
-        private void topologicalSorting() {
-
-            Queue<Segment> queue = new LinkedList<Segment>();
-
-            int index = 0;
-            ArrayList<Segment> newList = new ArrayList<Segment>();
-            for (Segment s : segments) {
-                if (s.preds.size() == 0) {
-                    s.orderNumber = index;
-                    newList.add(s);
-                    index++;
-                    queue.add(s);
-                }
-            }
-
-            while (!queue.isEmpty()) {
-                Segment s = queue.remove();
-
-                for (Segment succ : s.succs) {
-                    succ.preds.remove(s);
-                    if (succ.preds.size() == 0) {
-                        queue.add(succ);
-                        succ.orderNumber = index;
-                        newList.add(succ);
-                        index++;
-                    }
-                }
-            }
-
-            segments = newList;
-        }
-
-        private void initialPositions() {
-
-            int[] minPos = new int[layers.length];
-
-            for (Segment s : segments) {
-                int max = 0;
-                for (LayoutNode n : s.nodes) {
-                    int x = minPos[n.layer];
-                    if (x > max) {
-                        max = x;
-                    }
-                }
-
-                for (LayoutNode n : s.nodes) {
-                    minPos[n.layer] = max + n.width + xOffset;
-                    n.x = max;
-                }
-            }
-        }
-
-        private int predSum(LayoutNode n) {
-            int sum = 0;
-            for (LayoutEdge e : n.preds) {
-                assert e.to == n;
-                //sum += (e.from.x + e.relativeFrom + (int)hashMap.get(e.from).d) - (e.to.x + e.relativeTo + (int)hashMap.get(e.to).d);
-                sum += (e.from.x + e.relativeFrom) - (e.to.x + e.relativeTo);
-            }
-
-            return sum;
-        }
-
-        private int succSum(LayoutNode n) {
-            int sum = 0;
-            for (LayoutEdge e : n.succs) {
-
-                assert e.from == n;
-                sum += (e.to.x + e.relativeTo) - (e.from.x + e.relativeFrom);
-            //sum += (e.to.x + e.relativeTo + (int)hashMap.get(e.to).d) - (e.from.x + e.relativeFrom + (int)hashMap.get(e.from).d);
-            }
-
-            return sum;
-
-        }
-
-        private void downValues() {
-
-            for (Segment s : segments) {
-                downValues(s);
-
-            }
-
-        }
-
-        private void downValues(Segment s) {
-            LayoutNode n = s.nodes.get(0); // Only first node needed, all other have same coordinate
-
-            if (n.preds.size() == 0) {
-                // Value is 0.0;
-                if (n.succs.size() == 0) {
-                    s.d = 0.0f;
-                } else {
-                    s.d = (((float) succSum(n) / (float) n.succs.size())) / 2;
-                }
-            } else {
-                s.d = (float) predSum(n) / (float) n.preds.size();
-            }
-        }
-
-        private void upValues() {
-            for (Segment s : segments) {
-                upValues(s);
-            }
-        }
-
-        private void upValues(Segment s) {
-            LayoutNode n = s.nodes.get(0); // Only first node needed, all other have same coordinate
-
-            if (n.succs.size() == 0) {
-                // Value is 0.0;
-                if (n.preds.size() == 0) {
-                    s.d = 0.0f;
-                } else {
-                    s.d = (float) predSum(n) / (float) n.preds.size();
-                }
-            } else {
-                s.d = ((float) succSum(n) / (float) n.succs.size()) / 2;
-            }
-        }
-
-        private void sweep(boolean down) {
-
-            if (down) {
-                downValues();
-            } else {
-                upValues();
-            }
-
-            SortedSet<Region> regions = new TreeSet<Region>(regionComparator);
-            for (Segment s : segments) {
-                s.region = new Region();
-                s.region.minOrderNumber = s.orderNumber;
-                s.region.segments.add(s);
-                s.region.d = s.d;
-                regions.add(s.region);
-            }
-
-            for (Segment s : segments) {
-                for (LayoutNode n : s.nodes) {
-                    if (n.pos != 0) {
-                        LayoutNode prevNode = layers[n.layer].get(n.pos - 1);
-                        if (prevNode.x + prevNode.width + xOffset == n.x) {
-                            Segment other = hashMap.get(prevNode);
-                            Region r1 = s.region;
-                            Region r2 = other.region;
-                            // They are close together
-                            if (r1 != r2 && r2.d >= r1.d) {
-
-                                if (r2.segments.size() < r1.segments.size()) {
-
-                                    r1.d = (r1.d * r1.segments.size() + r2.d * r2.segments.size()) / (r1.segments.size() + r2.segments.size());
-
-                                    for (Segment tempS : r2.segments) {
-                                        r1.segments.add(tempS);
-                                        tempS.region = r1;
-                                        r1.minOrderNumber = Math.min(r1.minOrderNumber, tempS.orderNumber);
-                                    }
-
-                                    regions.remove(r2);
-                                } else {
-
-                                    r2.d = (r1.d * r1.segments.size() + r2.d * r2.segments.size()) / (r1.segments.size() + r2.segments.size());
-
-                                    for (Segment tempS : r1.segments) {
-                                        r2.segments.add(tempS);
-                                        tempS.region = r2;
-                                        r2.minOrderNumber = Math.min(r2.minOrderNumber, tempS.orderNumber);
-                                    }
-
-                                    regions.remove(r1);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
-
-
-            ArrayList<Region> reversedRegions = new ArrayList<Region>();
-            for (Region r : regions) {
-                if (r.d < 0) {
-                    processRegion(r, down);
-                } else {
-                    reversedRegions.add(0, r);
-                }
-            }
-
-            for (Region r : reversedRegions) {
-                processRegion(r, down);
-            }
-
-        }
-
-        private void processRegion(Region r, boolean down) {
-
-            // Do not move
-            if ((int) r.d == 0) {
-                return;
-            }
-
-            ArrayList<Segment> arr = new ArrayList<Segment>();
-            for (Segment s : r.segments) {
-                arr.add(s);
-            }
-
-            if (r.d > 0) {
-                Collections.reverse(arr);
-            }
-
-            for (Segment s : arr) {
-
-
-                int min = (int) r.d;
-                if (min < 0) {
-                    min = -min;
-                }
-
-                for (LayoutNode n : s.nodes) {
-
-                    int layer = n.layer;
-                    int pos = n.pos;
-
-
-                    if (r.d > 0) {
-
-                        if (pos != layers[layer].size() - 1) {
-
-                            int off = layers[layer].get(pos + 1).x - n.x - xOffset - n.width;
-                            assert off >= 0;
-                            if (off < min) {
-                                min = off;
-                            }
-                        }
-
-                    } else {
-
-                        if (pos != 0) {
-
-                            int off = n.x - xOffset - layers[layer].get(pos - 1).x - layers[layer].get(pos - 1).width;
-                            assert off >= 0;
-                            if (off < min) {
-                                min = off;
-                            }
-                        }
-                    }
-                }
-
-                assert min >= 0;
-                if (min != 0) {
-                    for (LayoutNode n : s.nodes) {
-                        if (r.d > 0) {
-                            n.x += min;
-                        } else {
-                            n.x -= min;
-                        }
-
-                    }
-                }
-            }
-        }
-
-        protected void run() {
-
-            generateSegments();
-            addEdges();
-            topologicalSorting();
-            initialPositions();
-            for (int i = 0; i < SWEEP_ITERATIONS; i++) {
-
-                sweep(true);
-                sweep(true);
-                sweep(false);
-                sweep(false);
-            }
-
-            sweep(true);
-            sweep(true);
-        }
-    }
     private static Comparator<LayoutNode> crossingNodeComparator = new Comparator<LayoutNode>() {
 
+        @Override
         public int compare(LayoutNode n1, LayoutNode n2) {
             return n1.crossingNumber - n2.crossingNumber;
         }
@@ -1103,18 +769,22 @@
                 assert n.layer < layerCount;
             }
         }
-
-        protected void run() {
-
+        
+        @SuppressWarnings("unchecked")
+        private void createLayers() {
             layers = new List[layerCount];
 
             for (int i = 0; i < layerCount; i++) {
-                layers[i] = new ArrayList<LayoutNode>();
+                layers[i] = new ArrayList<>();
             }
+        }
 
+        @Override
+        protected void run() {
+            createLayers();
 
             // Generate initial ordering
-            HashSet<LayoutNode> visited = new HashSet<LayoutNode>();
+            HashSet<LayoutNode> visited = new HashSet<>();
             for (LayoutNode n : nodes) {
                 if (n.layer == 0) {
                     layers[0].add(n);
@@ -1146,10 +816,11 @@
                 downSweep();
                 upSweep();
             }
-
-        /*for(int i=0; i<CROSSING_ITERATIONS; i++) {
-        doubleSweep();
-        }*/
+            if (reversedLinks.isEmpty()) {
+                // This graph seems to be a tree or forest.
+                // A final down-sweep will usually give us a better layout.
+                downSweep();
+            }
         }
 
         private void initX() {
@@ -1191,21 +862,20 @@
                 for (LayoutNode n : layers[i]) {
 
                     int sum = 0;
+                    int count = 0;
                     for (LayoutEdge e : n.preds) {
                         int cur = e.from.x + e.relativeFrom;
-
-                        /*pos;
-                        if(e.from.width != 0 && e.relativeFrom != 0) {
-                        cur += (float)e.relativeFrom / (float)(e.from.width);
-                        }*/
-
-                        sum += cur;
+                        int factor = 1;
+                        if (e.vip) {
+                            factor = VIP_BONUS;
+                        }
+                        sum += cur*factor;
+                        count+=factor;
                     }
 
-                    if (n.preds.size() > 0) {
-                        sum /= n.preds.size();
+                    if (count > 0) {
+                        sum /= count;
                         n.crossingNumber = sum;
-                    //if(n.vertex == null) n.crossingNumber += layers[i].size();
                     }
                 }
 
@@ -1234,9 +904,9 @@
                     next = layers[index].get(i + 1);
                 }
 
-                boolean cond = (n.succs.size() == 0);
+                boolean cond = n.succs.isEmpty();
                 if (down) {
-                    cond = (n.preds.size() == 0);
+                    cond = n.preds.isEmpty();
                 }
 
                 if (cond) {
@@ -1251,44 +921,6 @@
                 }
             }
         }
-        /*
-        private void doubleSweep() {
-        // Downsweep
-        for(int i=0; i<layerCount*2; i++) {
-        int index = i;
-        if(index >= layerCount) {
-        index = 2*layerCount - i - 1;
-        }
-        for(LayoutNode n : layers[index]) {
-        float sum = 0.0f;
-        for(LayoutEdge e : n.preds) {
-        float cur = e.from.pos;
-        if(e.from.width != 0 && e.relativeFrom != 0) {
-        cur += (float)e.relativeFrom / (float)(e.from.width);
-        }
-        sum += cur;
-        }
-        for(LayoutEdge e : n.succs) {
-        float cur = e.to.pos;
-        if(e.to.width != 0 && e.relativeTo != 0) {
-        cur += (float)e.relativeTo / (float)(e.to.width);
-        }
-        sum += cur;
-        }
-        if(n.preds.size() + n.succs.size() > 0) {
-        sum /= n.preds.size() + n.succs.size();
-        n.crossingNumber = sum;
-        }
-        }
-        Collections.sort(layers[index], crossingNodeComparator);
-        updateXOfLayer(index);
-        int z = 0;
-        for(LayoutNode n : layers[index]) {
-        n.pos = z;
-        z++;
-        }
-        }
-        }*/
 
         private void upSweep() {
             // Upsweep
@@ -1300,21 +932,21 @@
 
                 for (LayoutNode n : layers[i]) {
 
+                    int count = 0;
                     int sum = 0;
                     for (LayoutEdge e : n.succs) {
-                        int cur = e.to.x + e.relativeTo;//pos;
-                                                /*
-                        if(e.to.width != 0 && e.relativeTo != 0) {
-                        cur += (float)e.relativeTo / (float)(e.to.width);
-                        }*/
-
-                        sum += cur;
+                        int cur = e.to.x + e.relativeTo;
+                        int factor = 1;
+                        if (e.vip) {
+                            factor = VIP_BONUS;
+                        }
+                        sum += cur*factor;
+                        count+=factor;
                     }
 
-                    if (n.succs.size() > 0) {
-                        sum /= n.succs.size();
+                    if (count > 0) {
+                        sum /= count;
                         n.crossingNumber = sum;
-                    //if(n.vertex == null) n.crossingNumber += layers[i].size();
                     }
 
                 }
@@ -1331,15 +963,10 @@
             }
         }
 
-        private int evaluate() {
-            // TODO: Implement efficient evaluate / crossing min
-            return 0;
-        }
-
         @Override
         public void postCheck() {
 
-            HashSet<LayoutNode> visited = new HashSet<LayoutNode>();
+            HashSet<LayoutNode> visited = new HashSet<>();
             for (int i = 0; i < layers.length; i++) {
                 for (LayoutNode n : layers[i]) {
                     assert !visited.contains(n);
@@ -1353,9 +980,10 @@
 
     private class AssignYCoordinates extends AlgorithmPart {
 
+        @Override
         protected void run() {
             int curY = 0;
-            //maxLayerHeight = new int[layers.length];
+
             for (int i = 0; i < layers.length; i++) {
                 int maxHeight = 0;
                 int baseLine = 0;
@@ -1383,8 +1011,6 @@
                     }
                 }
 
-                //maxLayerHeight[i] = maxHeight + baseLine + bottomBaseLine;
-
                 curY += maxHeight + baseLine + bottomBaseLine;
                 curY += layerOffset + (int) Math.sqrt(maxXOffset);
             }
@@ -1411,6 +1037,7 @@
             }
         }
 
+        @Override
         protected void run() {
             oldNodeCount = nodes.size();
 
@@ -1419,18 +1046,19 @@
 
                 Comparator<LayoutEdge> comparator = new Comparator<LayoutEdge>() {
 
+                    @Override
                     public int compare(LayoutEdge e1, LayoutEdge e2) {
                         return e1.to.layer - e2.to.layer;
                     }
                 };
-                HashMap<Integer, List<LayoutEdge>> portHash = new HashMap<Integer, List<LayoutEdge>>();
-                ArrayList<LayoutNode> currentNodes = new ArrayList<LayoutNode>(nodes);
+                HashMap<Integer, List<LayoutEdge>> portHash = new HashMap<>();
+                ArrayList<LayoutNode> currentNodes = new ArrayList<>(nodes);
                 for (LayoutNode n : currentNodes) {
                     portHash.clear();
 
-                    ArrayList<LayoutEdge> succs = new ArrayList<LayoutEdge>(n.succs);
-                    HashMap<Integer, LayoutNode> topNodeHash = new HashMap<Integer, LayoutNode>();
-                    HashMap<Integer, HashMap<Integer, LayoutNode>> bottomNodeHash = new HashMap<Integer, HashMap<Integer, LayoutNode>>();
+                    ArrayList<LayoutEdge> succs = new ArrayList<>(n.succs);
+                    HashMap<Integer, LayoutNode> topNodeHash = new HashMap<>();
+                    HashMap<Integer, HashMap<Integer, LayoutNode>> bottomNodeHash = new HashMap<>();
                     for (LayoutEdge e : succs) {
                         assert e.from.layer < e.to.layer;
                         if (e.from.layer != e.to.layer - 1) {
@@ -1449,6 +1077,7 @@
                                     topEdge.relativeTo = topNode.width / 2;
                                     topEdge.to = topNode;
                                     topEdge.link = e.link;
+                                    topEdge.vip = e.vip;
                                     e.from.succs.add(topEdge);
                                     topNode.preds.add(topEdge);
                                 } else {
@@ -1464,6 +1093,7 @@
                                     topEdge.relativeTo = topNode.width / 2;
                                     topEdge.to = topNode;
                                     topEdge.link = e.link;
+                                    topEdge.vip = e.vip;
                                     e.from.succs.add(topEdge);
                                     topNode.preds.add(topEdge);
                                     topNodeHash.put(e.relativeFrom, topNode);
@@ -1491,6 +1121,7 @@
                                 bottomEdge.relativeFrom = bottomNode.width / 2;
                                 bottomEdge.from = bottomNode;
                                 bottomEdge.link = e.link;
+                                bottomEdge.vip = e.vip;
                                 e.to.preds.add(bottomEdge);
                                 bottomEdgeHash.put(topEdge, bottomEdge);
                                 bottomNode.succs.add(bottomEdge);
@@ -1500,17 +1131,12 @@
                                 if (!portHash.containsKey(i)) {
                                     portHash.put(i, new ArrayList<LayoutEdge>());
                                 }
-
-                                if (n.vertex.toString().equals("1012 CastPP")) {
-                                    int x = 0;
-                                }
-
                                 portHash.get(i).add(e);
                             }
                         }
                     }
 
-                    succs = new ArrayList<LayoutEdge>(n.succs);
+                    succs = new ArrayList<>(n.succs);
                     for (LayoutEdge e : succs) {
 
                         Integer i = e.relativeFrom;
@@ -1535,6 +1161,7 @@
                                 edges[0] = new LayoutEdge();
                                 edges[0].from = n;
                                 edges[0].relativeFrom = i;
+                                edges[0].vip = e.vip;
                                 n.succs.add(edges[0]);
 
                                 nodes[0] = new LayoutNode();
@@ -1546,6 +1173,7 @@
                                 edges[0].relativeTo = nodes[0].width / 2;
                                 for (int j = 1; j < cnt; j++) {
                                     edges[j] = new LayoutEdge();
+                                    edges[j].vip = e.vip;
                                     edges[j].from = nodes[j - 1];
                                     edges[j].relativeFrom = nodes[j - 1].width / 2;
                                     nodes[j - 1].succs.add(edges[j]);
@@ -1577,7 +1205,7 @@
             } else if (combine == Combine.SAME_INPUTS) {
                 throw new UnsupportedOperationException("Currently not supported");
             } else {
-                ArrayList<LayoutNode> currentNodes = new ArrayList<LayoutNode>(nodes);
+                ArrayList<LayoutNode> currentNodes = new ArrayList<>(nodes);
                 for (LayoutNode n : currentNodes) {
                     for (LayoutEdge e : n.succs) {
                         processSingleEdge(e);
@@ -1604,6 +1232,7 @@
             n.preds.add(e);
             nodes.add(n);
             LayoutEdge result = new LayoutEdge();
+            result.vip = e.vip;
             n.succs.add(result);
             result.from = n;
             result.relativeFrom = n.width / 2;
@@ -1623,7 +1252,7 @@
 
         @Override
         public void postCheck() {
-            ArrayList<LayoutNode> currentNodes = new ArrayList<LayoutNode>(nodes);
+            ArrayList<LayoutNode> currentNodes = new ArrayList<>(nodes);
             for (LayoutNode n : currentNodes) {
                 for (LayoutEdge e : n.succs) {
                     assert e.from.layer == e.to.layer - 1;
@@ -1648,18 +1277,23 @@
             }
         }
 
+        @Override
         protected void run() {
-            HashSet<LayoutNode> set = new HashSet<LayoutNode>();
+
+            List<LayoutNode> insertOrder = new ArrayList<>();
+
+            HashSet<LayoutNode> set = new HashSet<>();
             for (LayoutNode n : nodes) {
                 if (n.preds.size() == 0) {
                     set.add(n);
+                    insertOrder.add(n);
                     n.layer = 0;
                 }
             }
 
             int z = minLayerDifference;
-            HashSet<LayoutNode> newSet = new HashSet<LayoutNode>();
-            HashSet<LayoutNode> failed = new HashSet<LayoutNode>();
+            HashSet<LayoutNode> newSet = new HashSet<>();
+            HashSet<LayoutNode> failed = new HashSet<>();
             while (!set.isEmpty()) {
 
                 newSet.clear();
@@ -1691,6 +1325,7 @@
 
                 for (LayoutNode n : newSet) {
                     n.layer = z;
+                    insertOrder.add(n);
                 }
 
                 // Swap sets
@@ -1700,7 +1335,7 @@
                 z += minLayerDifference;
             }
 
-            optimize(set);
+            optimize(insertOrder);
 
             layerCount = z - minLayerDifference;
 
@@ -1714,23 +1349,22 @@
             for (Vertex v : firstLayerHint) {
                 LayoutNode n = vertexToLayoutNode.get(v);
                 assert n.preds.size() == 0;
+                n.layer = 0;
                 assert n.layer == 0;
             }
         }
 
-        public void optimize(HashSet<LayoutNode> set) {
-
-            for (LayoutNode n : set) {
-                if (n.preds.size() == 0 && n.succs.size() > 0) {
-                    int minLayer = n.succs.get(0).to.layer;
-                    for (LayoutEdge e : n.succs) {
+        public void optimize(List<LayoutNode> insertOrder) {
+            for (int i = insertOrder.size() - 1; i >= 0; i--) {
+                LayoutNode cur = insertOrder.get(i);
+                if (cur.succs.size() > cur.preds.size()) {
+                    int minLayer = cur.succs.get(0).to.layer;
+                    for (LayoutEdge e : cur.succs) {
                         minLayer = Math.min(minLayer, e.to.layer);
                     }
-
-                    n.layer = minLayer - 1;
+                    cur.layer = minLayer - 1;
                 }
             }
-
         }
 
         @Override
@@ -1750,11 +1384,12 @@
         private HashSet<LayoutNode> visited;
         private HashSet<LayoutNode> active;
 
+        @Override
         protected void run() {
 
-            // Remove self-edges, TODO: Special treatment
+            // Remove self-edges
             for (LayoutNode node : nodes) {
-                ArrayList<LayoutEdge> succs = new ArrayList<LayoutEdge>(node.succs);
+                ArrayList<LayoutEdge> succs = new ArrayList<>(node.succs);
                 for (LayoutEdge e : succs) {
                     assert e.from == node;
                     if (e.to == node) {
@@ -1782,8 +1417,8 @@
 
 
             // Start DFS and reverse back edges
-            visited = new HashSet<LayoutNode>();
-            active = new HashSet<LayoutNode>();
+            visited = new HashSet<>();
+            active = new HashSet<>();
             for (LayoutNode node : nodes) {
                 DFS(node);
             }
@@ -1791,7 +1426,7 @@
 
             for (LayoutNode node : nodes) {
 
-                SortedSet<Integer> reversedDown = new TreeSet<Integer>();
+                SortedSet<Integer> reversedDown = new TreeSet<>();
 
                 for (LayoutEdge e : node.succs) {
                     if (reversedLinks.contains(e.link)) {
@@ -1802,9 +1437,9 @@
 
                 SortedSet<Integer> reversedUp = null;
                 if (reversedDown.size() == 0) {
-                    reversedUp = new TreeSet<Integer>(Collections.reverseOrder());
+                    reversedUp = new TreeSet<>(Collections.reverseOrder());
                 } else {
-                    reversedUp = new TreeSet<Integer>();
+                    reversedUp = new TreeSet<>();
                 }
 
                 for (LayoutEdge e : node.preds) {
@@ -1818,7 +1453,7 @@
                 int curX = 0;
                 int curWidth = node.width + reversedDown.size() * offset;
                 for (int pos : reversedDown) {
-                    ArrayList<LayoutEdge> reversedSuccs = new ArrayList<LayoutEdge>();
+                    ArrayList<LayoutEdge> reversedSuccs = new ArrayList<>();
                     for (LayoutEdge e : node.succs) {
                         if (e.relativeFrom == pos && reversedLinks.contains(e.link)) {
                             reversedSuccs.add(e);
@@ -1826,7 +1461,7 @@
                         }
                     }
 
-                    ArrayList<Point> startPoints = new ArrayList<Point>();
+                    ArrayList<Point> startPoints = new ArrayList<>();
                     startPoints.add(new Point(curWidth, curX));
                     startPoints.add(new Point(pos, curX));
                     startPoints.add(new Point(pos, reversedDown.size() * offset));
@@ -1856,7 +1491,7 @@
 
                 int oldNodeHeight = node.height;
                 for (int pos : reversedUp) {
-                    ArrayList<LayoutEdge> reversedPreds = new ArrayList<LayoutEdge>();
+                    ArrayList<LayoutEdge> reversedPreds = new ArrayList<>();
                     for (LayoutEdge e : node.preds) {
                         if (e.relativeTo == pos && reversedLinks.contains(e.link)) {
                             if (reversedDown.size() == 0) {
@@ -1869,7 +1504,7 @@
                         }
                     }
                     node.height += offset;
-                    ArrayList<Point> endPoints = new ArrayList<Point>();
+                    ArrayList<Point> endPoints = new ArrayList<>();
 
                     if (reversedDown.size() == 0) {
 
@@ -1917,7 +1552,7 @@
                 return;
             }
 
-            Stack<LayoutNode> stack = new Stack<LayoutNode>();
+            Stack<LayoutNode> stack = new Stack<>();
             stack.push(startNode);
 
             while (!stack.empty()) {
@@ -1934,7 +1569,7 @@
                 visited.add(node);
                 active.add(node);
 
-                ArrayList<LayoutEdge> succs = new ArrayList<LayoutEdge>(node.succs);
+                ArrayList<LayoutEdge> succs = new ArrayList<>(node.succs);
                 for (LayoutEdge e : succs) {
                     if (active.contains(e.to)) {
                         assert visited.contains(e.to);
@@ -1989,8 +1624,8 @@
 
             for (LayoutNode n : nodes) {
 
-                HashSet<LayoutNode> curVisited = new HashSet<LayoutNode>();
-                Queue<LayoutNode> queue = new LinkedList<LayoutNode>();
+                HashSet<LayoutNode> curVisited = new HashSet<>();
+                Queue<LayoutNode> queue = new LinkedList<>();
                 for (LayoutEdge e : n.succs) {
                     LayoutNode s = e.to;
                     queue.add(s);
@@ -2013,6 +1648,7 @@
     }
     private Comparator<Link> linkComparator = new Comparator<Link>() {
 
+        @Override
         public int compare(Link l1, Link l2) {
 
             int result = l1.getFrom().getVertex().compareTo(l2.getFrom().getVertex());
@@ -2034,9 +1670,10 @@
 
     private class BuildDatastructure extends AlgorithmPart {
 
+        @Override
         protected void run() {
             // Set up nodes
-            List<Vertex> vertices = new ArrayList<Vertex>(graph.getVertices());
+            List<Vertex> vertices = new ArrayList<>(graph.getVertices());
             Collections.sort(vertices);
 
             for (Vertex v : vertices) {
@@ -2050,7 +1687,7 @@
             }
 
             // Set up edges
-            List<Link> links = new ArrayList<Link>(graph.getLinks());
+            List<Link> links = new ArrayList<>(graph.getLinks());
             Collections.sort(links, linkComparator);
             for (Link l : links) {
                 LayoutEdge edge = new LayoutEdge();
@@ -2063,6 +1700,7 @@
                 edge.link = l;
                 edge.from.succs.add(edge);
                 edge.to.preds.add(edge);
+                edge.vip = l.isVIP();
             //assert edge.from != edge.to; // No self-loops allowed
             }
 
@@ -2104,7 +1742,8 @@
         }
     }
 
+    @Override
     public void doRouting(LayoutGraph graph) {
-    // Do nothing for now
+        // Do nothing for now
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/InterClusterConnection.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.hierarchicallayout;
-
-import com.sun.hotspot.igv.layout.Link;
-import com.sun.hotspot.igv.layout.Port;
-import java.awt.Point;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class InterClusterConnection implements Link {
-
-    private Port inputSlot;
-    private Port outputSlot;
-    private List<Point> intermediatePoints;
-    private ClusterInputSlotNode inputSlotNode;
-    private ClusterOutputSlotNode outputSlotNode;
-
-    public InterClusterConnection(ClusterOutputSlotNode outputSlotNode, ClusterInputSlotNode inputSlotNode) {
-        this.outputSlotNode = outputSlotNode;
-        this.inputSlotNode = inputSlotNode;
-        this.inputSlot = inputSlotNode.getInputSlot();
-        this.outputSlot = outputSlotNode.getOutputSlot();
-        intermediatePoints = new ArrayList<Point>();
-    }
-
-    public ClusterOutputSlotNode getOutputSlotNode() {
-        return outputSlotNode;
-    }
-
-    public Port getTo() {
-        return inputSlot;
-    }
-
-    public Port getFrom() {
-        return outputSlot;
-    }
-
-    public void setControlPoints(List<Point> p) {
-        this.intermediatePoints = p;
-    }
-
-    public List<Point> getControlPoints() {
-        return intermediatePoints;
-    }
-
-    @Override
-    public String toString() {
-        return "InterClusterConnection[from=" + getFrom() + ", to=" + getTo() + "]";
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Node.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Node.java	Mon Feb 27 13:10:13 2012 +0100
@@ -90,8 +90,8 @@
     protected Node(Graph<N, E> graph, N data) {
         setData(data);
         this.graph = graph;
-        inEdges = new ArrayList<Edge<N, E>>();
-        outEdges = new ArrayList<Edge<N, E>>();
+        inEdges = new ArrayList<>();
+        outEdges = new ArrayList<>();
     }
 
     protected void addInEdge(Edge<N, E> e) {
@@ -125,7 +125,7 @@
     }
 
     public List<Node<N, E>> getSuccessors() {
-        ArrayList<Node<N, E>> succ = new ArrayList<Node<N, E>>();
+        ArrayList<Node<N, E>> succ = new ArrayList<>();
         for (Edge<N, E> e : getOutEdges()) {
             Node<N, E> n = e.getDest();
             if (!succ.contains(n)) {
@@ -136,7 +136,7 @@
     }
 
     public List<Node<N, E>> getPredecessors() {
-        ArrayList<Node<N, E>> pred = new ArrayList<Node<N, E>>();
+        ArrayList<Node<N, E>> pred = new ArrayList<>();
         for (Edge<N, E> e : getInEdges()) {
             Node<N, E> n = e.getSource();
             if (!pred.contains(n)) {
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/OldHierarchicalLayoutManager.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1222 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.hierarchicallayout;
-
-import java.awt.Point;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import com.sun.hotspot.igv.layout.LayoutGraph;
-import com.sun.hotspot.igv.layout.LayoutManager;
-import com.sun.hotspot.igv.layout.Link;
-import com.sun.hotspot.igv.layout.Port;
-import com.sun.hotspot.igv.layout.Vertex;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class OldHierarchicalLayoutManager implements LayoutManager {
-
-    public static final int DUMMY_WIDTH = 0;
-    public static final int DUMMY_HEIGHT = 0;
-    public static final int LAYER_OFFSET = 50;
-    public static final int OFFSET = 8;
-    public static final boolean VERTICAL_LAYOUT = true;
-    public static final boolean ASSERT = false;
-    public static final boolean TRACE = false;
-    public static final Timing initTiming = new Timing("init");
-    public static final Timing removeCyclesTiming = new Timing("removeCycles");
-    public static final Timing reversedEdgesTiming = new Timing("reversedEdges");
-    public static final Timing assignLayersTiming = new Timing("assignLayers");
-    public static final Timing dummyNodesTiming = new Timing("dummyNodes");
-    public static final Timing crossingReductionTiming = new Timing("crossingReduction");
-    public static final Timing assignCoordinatesTiming = new Timing("assignCoordinates");
-    public static final Timing assignRealTiming = new Timing("assignReal");
-    public static final Timing rootVertexTiming = new Timing("rootVertex");
-    public static final Timing createEdgesTiming = new Timing("createEdges");
-    public static final Timing optimizeMedianTiming = new Timing("optimizeMedian");
-    private Combine combine;
-
-    public enum Combine {
-
-        NONE,
-        SAME_INPUTS,
-        SAME_OUTPUTS
-    }
-
-    private class NodeData {
-
-        private Map<Port, Integer> reversePositions;
-        private Vertex node;
-        private Link edge;
-        private int layer;
-        private int x;
-        private int y;
-        private int width;
-
-        public NodeData(Vertex node) {
-            reversePositions = new HashMap<Port, Integer>();
-            layer = -1;
-            this.node = node;
-            assert node != null;
-
-            if (VERTICAL_LAYOUT) {
-                width = node.getSize().width;
-            } else {
-                width = node.getSize().height;
-            }
-        }
-
-        public NodeData(Link edge) {
-            layer = -1;
-            this.edge = edge;
-            assert edge != null;
-
-            if (VERTICAL_LAYOUT) {
-                width = DUMMY_WIDTH;
-            } else {
-                width = DUMMY_HEIGHT;
-            }
-        }
-
-        public Vertex getNode() {
-            return node;
-        }
-
-        public Link getEdge() {
-            return edge;
-        }
-
-        public int getCoordinate() {
-            return x;
-        }
-
-        public void setCoordinate(int x) {
-            this.x = x;
-        }
-
-        public int getX() {
-            if (VERTICAL_LAYOUT) {
-                return x;
-            } else {
-                return y;
-            }
-        }
-
-        public int getY() {
-            if (VERTICAL_LAYOUT) {
-                return y;
-            } else {
-                return x;
-            }
-        }
-
-        public void setLayerCoordinate(int y) {
-            this.y = y;
-        }
-
-        public void setLayer(int x) {
-            layer = x;
-        }
-
-        public int getLayer() {
-            return layer;
-        }
-
-        public boolean isDummy() {
-            return edge != null;
-        }
-
-        public int getWidth() {
-            return width;
-        }
-
-        public void addReversedStartEdge(Edge<NodeData, EdgeData> e) {
-            assert e.getData().isReversed();
-            Port port = e.getData().getEdge().getTo();
-            int pos = addReversedPort(port);
-            Point start = e.getData().getRelativeStart();
-            e.getData().addStartPoint(start);
-            int yCoord = node.getSize().height + width - node.getSize().width;
-            e.getData().addStartPoint(new Point(start.x, yCoord));
-            e.getData().addStartPoint(new Point(pos, yCoord));
-            e.getData().setRelativeStart(new Point(pos, 0));
-        }
-
-        private int addReversedPort(Port p) {
-            if (reversePositions.containsKey(p)) {
-                return reversePositions.get(p);
-            } else {
-                width += OFFSET;
-                reversePositions.put(p, width);
-                return width;
-            }
-        }
-
-        public void addReversedEndEdge(Edge<NodeData, EdgeData> e) {
-            assert e.getData().isReversed();
-            int pos = addReversedPort(e.getData().getEdge().getFrom());
-            Point end = e.getData().getRelativeEnd();
-            e.getData().setRelativeEnd(new Point(pos, node.getSize().height));
-            int yCoord = 0 - width + node.getSize().width;
-            e.getData().addEndPoint(new Point(pos, yCoord));
-            e.getData().addEndPoint(new Point(end.x, yCoord));
-            e.getData().addEndPoint(end);
-        }
-
-        public int getHeight() {
-            if (isDummy()) {
-                if (VERTICAL_LAYOUT) {
-                    return DUMMY_HEIGHT;
-                } else {
-                    return DUMMY_WIDTH;
-                }
-
-            } else {
-                if (VERTICAL_LAYOUT) {
-                    return node.getSize().height;
-                } else {
-                    return node.getSize().width;
-                }
-            }
-        }
-
-        @Override
-        public String toString() {
-            if (isDummy()) {
-                return edge.toString() + "(layer=" + layer + ")";
-            } else {
-                return node.toString() + "(layer=" + layer + ")";
-            }
-        }
-    }
-
-    private class EdgeData {
-
-        private Point relativeEnd;
-        private Point relativeStart;
-        private List<Point> startPoints;
-        private List<Point> endPoints;
-        private boolean important;
-        private boolean reversed;
-        private Link edge;
-
-        public EdgeData(Link edge) {
-            this(edge, false);
-        }
-
-        public EdgeData(Link edge, boolean rev) {
-            this.edge = edge;
-            reversed = rev;
-            relativeStart = edge.getFrom().getRelativePosition();
-            relativeEnd = edge.getTo().getRelativePosition();
-            assert relativeStart.x >= 0 && relativeStart.x <= edge.getFrom().getVertex().getSize().width;
-            assert relativeStart.y >= 0 && relativeStart.y <= edge.getFrom().getVertex().getSize().height;
-            assert relativeEnd.x >= 0 && relativeEnd.x <= edge.getTo().getVertex().getSize().width;
-            assert relativeEnd.y >= 0 && relativeEnd.y <= edge.getTo().getVertex().getSize().height;
-            startPoints = new ArrayList<Point>();
-            endPoints = new ArrayList<Point>();
-            this.important = true;
-        }
-
-        public boolean isImportant() {
-            return important;
-        }
-
-        public void setImportant(boolean b) {
-            this.important = b;
-        }
-
-        public List<Point> getStartPoints() {
-            return startPoints;
-        }
-
-        public List<Point> getEndPoints() {
-            return endPoints;
-        }
-
-        public List<Point> getAbsoluteEndPoints() {
-            if (endPoints.size() == 0) {
-                return endPoints;
-            }
-
-            List<Point> result = new ArrayList<Point>();
-            Point point = edge.getTo().getVertex().getPosition();
-            for (Point p : endPoints) {
-                Point p2 = new Point(p.x + point.x, p.y + point.y);
-                result.add(p2);
-            }
-
-            return result;
-        }
-
-        public List<Point> getAbsoluteStartPoints() {
-            if (startPoints.size() == 0) {
-                return startPoints;
-            }
-
-            List<Point> result = new ArrayList<Point>();
-            Point point = edge.getFrom().getVertex().getPosition();
-            for (Point p : startPoints) {
-                Point p2 = new Point(p.x + point.x, p.y + point.y);
-                result.add(p2);
-            }
-
-            return result;
-        }
-
-        public void addEndPoint(Point p) {
-            endPoints.add(p);
-        }
-
-        public void addStartPoint(Point p) {
-            startPoints.add(p);
-        }
-
-        public Link getEdge() {
-            return edge;
-        }
-
-        public void setRelativeEnd(Point p) {
-            relativeEnd = p;
-        }
-
-        public void setRelativeStart(Point p) {
-            relativeStart = p;
-        }
-
-        public Point getRelativeEnd() {
-            return relativeEnd;
-        }
-
-        public Point getRelativeStart() {
-            return relativeStart;
-        }
-
-        public boolean isReversed() {
-            return reversed;
-        }
-
-        public void setReversed(boolean b) {
-            reversed = b;
-        }
-
-        @Override
-        public String toString() {
-            return "EdgeData[reversed=" + reversed + "]";
-        }
-    }
-    private Graph<NodeData, EdgeData> graph;
-    private Map<Vertex, Node<NodeData, EdgeData>> nodeMap;
-    private int layerOffset;
-
-    /** Creates a new instance of HierarchicalPositionManager */
-    public OldHierarchicalLayoutManager(Combine combine) {
-        this(combine, LAYER_OFFSET);
-    }
-
-    public OldHierarchicalLayoutManager(Combine combine, int layerOffset) {
-        this.combine = combine;
-        this.layerOffset = layerOffset;
-    }
-
-    public void doRouting(LayoutGraph graph) {
-    }
-
-    //public void setPositions(PositionedNode rootNode, List<? extends PositionedNode> nodes, List<? extends PositionedEdge> edges) {
-    public void doLayout(LayoutGraph layoutGraph) {
-        doLayout(layoutGraph, new HashSet<Vertex>(), new HashSet<Vertex>());
-    }
-
-    public void doLayout(LayoutGraph layoutGraph, Set<? extends Vertex> firstLayerHint, Set<? extends Vertex> lastLayerHint) {
-        doLayout(layoutGraph, firstLayerHint, lastLayerHint, new HashSet<Link>());
-    }
-
-    public void doLayout(LayoutGraph layoutGraph, Set<? extends Vertex> firstLayerHint, Set<? extends Vertex> lastLayerHint, Set<? extends Link> importantLinksHint) {
-
-        if (TRACE) {
-            System.out.println("HierarchicalPositionManager.doLayout called");
-            System.out.println("Vertex count = " + layoutGraph.getVertices().size() + " Link count = " + layoutGraph.getLinks().size());
-        }
-
-        // Nothing to do => quit immediately
-        if (layoutGraph.getVertices().size() == 0) {
-            return;
-        }
-
-        initTiming.start();
-
-        // Mapping vertex to Node in graph
-        nodeMap = new HashMap<Vertex, Node<NodeData, EdgeData>>();
-
-        graph = new Graph<NodeData, EdgeData>();
-
-        Set<Node<NodeData, EdgeData>> rootNodes = new HashSet<Node<NodeData, EdgeData>>();
-        Set<Vertex> startRootVertices = new HashSet<Vertex>();
-
-        for (Vertex v : layoutGraph.getVertices()) {
-            if (v.isRoot()) {
-                startRootVertices.add(v);
-            }
-        }
-
-        rootVertexTiming.start();
-        Set<Vertex> rootVertices = layoutGraph.findRootVertices(startRootVertices);
-        rootVertexTiming.stop();
-
-
-        for (Vertex node : layoutGraph.getVertices()) {
-
-            NodeData data = new NodeData(node);
-            Node<NodeData, EdgeData> n = graph.createNode(data, node);
-            nodeMap.put(node, n);
-
-            if (rootVertices.contains(node)) {
-                rootNodes.add(n);
-            }
-        }
-
-        Set<? extends Link> links = layoutGraph.getLinks();
-        Link[] linkArr = new Link[links.size()];
-        links.toArray(linkArr);
-
-        List<Link> linkList = new ArrayList<Link>();
-        for (Link l : linkArr) {
-            linkList.add(l);
-        }
-
-        createEdgesTiming.start();
-        Collections.sort(linkList, new Comparator<Link>() {
-
-            public int compare(Link o1, Link o2) {
-                int result = o1.getFrom().getVertex().compareTo(o2.getFrom().getVertex());
-                if (result == 0) {
-                    return o1.getTo().getVertex().compareTo(o2.getTo().getVertex());
-                } else {
-                    return result;
-                }
-            }
-        });
-
-        for (Link edge : linkList) {
-            EdgeData data = new EdgeData(edge);
-            graph.createEdge(graph.getNode(edge.getFrom().getVertex()), graph.getNode(edge.getTo().getVertex()), data, data);
-            if (importantLinksHint.size() > 0 && !importantLinksHint.contains(edge)) {
-                data.setImportant(false);
-            }
-        }
-        createEdgesTiming.stop();
-
-        initTiming.stop();
-
-        removeCyclesTiming.start();
-
-        // STEP 1: Remove cycles!
-        removeCycles(rootNodes);
-        if (ASSERT) {
-            assert checkRemoveCycles();
-        }
-
-        removeCyclesTiming.stop();
-
-        reversedEdgesTiming.start();
-
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            List<Edge<NodeData, EdgeData>> edges = new ArrayList<Edge<NodeData, EdgeData>>(n.getOutEdges());
-            Collections.sort(edges, new Comparator<Edge<NodeData, EdgeData>>() {
-
-                public int compare(Edge<NodeData, EdgeData> o1, Edge<NodeData, EdgeData> o2) {
-                    return o2.getData().getRelativeEnd().x - o1.getData().getRelativeEnd().x;
-                }
-            });
-
-
-            for (Edge<NodeData, EdgeData> e : edges) {
-
-                if (e.getData().isReversed()) {
-                    e.getSource().getData().addReversedEndEdge(e);
-                }
-            }
-        }
-
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            List<Edge<NodeData, EdgeData>> edges = new ArrayList<Edge<NodeData, EdgeData>>(n.getInEdges());
-            Collections.sort(edges, new Comparator<Edge<NodeData, EdgeData>>() {
-
-                public int compare(Edge<NodeData, EdgeData> o1, Edge<NodeData, EdgeData> o2) {
-                    return o2.getData().getRelativeStart().x - o1.getData().getRelativeStart().x;
-                }
-            });
-
-
-            for (Edge<NodeData, EdgeData> e : edges) {
-                if (e.getData().isReversed()) {
-                    e.getDest().getData().addReversedStartEdge(e);
-                }
-            }
-        }
-
-        reversedEdgesTiming.stop();
-
-        assignLayersTiming.start();
-        // STEP 2: Assign layers!
-        int maxLayer = assignLayers(rootNodes, firstLayerHint, lastLayerHint);
-        if (ASSERT) {
-            assert checkAssignLayers();
-        }
-
-        // Put into layer array
-        //int maxLayer = 0;
-        //for(Node<NodeData, EdgeData> n : graph.getNodes()) {
-        //    maxLayer = Math.max(maxLayer, n.getData().getLayer());
-        //}
-
-
-        ArrayList<Node<NodeData, EdgeData>> layers[] = new ArrayList[maxLayer + 1];
-        int layerSizes[] = new int[maxLayer + 1];
-        for (int i = 0; i < maxLayer + 1; i++) {
-            layers[i] = new ArrayList<Node<NodeData, EdgeData>>();
-        }
-
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            int curLayer = n.getData().getLayer();
-            layers[curLayer].add(n);
-        }
-
-        assignLayersTiming.stop();
-
-        // STEP 3: Insert dummy nodes!
-        dummyNodesTiming.start();
-        insertDummyNodes(layers);
-        if (ASSERT) {
-            assert checkDummyNodes();
-        }
-        dummyNodesTiming.stop();
-
-        crossingReductionTiming.start();
-        // STEP 4: Assign Y coordinates
-        assignLayerCoordinates(layers, layerSizes);
-
-        // STEP 5: Crossing reduction
-        crossingReduction(layers);
-        crossingReductionTiming.stop();
-
-        // STEP 6: Assign Y coordinates
-        assignCoordinatesTiming.start();
-        assignCoordinates(layers);
-        assignCoordinatesTiming.stop();
-
-        assignRealTiming.start();
-
-        // Assign coordinates of nodes to real objects
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            if (!n.getData().isDummy()) {
-
-                Vertex node = n.getData().getNode();
-                node.setPosition(new Point(n.getData().getX(), n.getData().getY()));
-            }
-        }
-
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            if (!n.getData().isDummy()) {
-
-                Vertex node = n.getData().getNode();
-
-                List<Edge<NodeData, EdgeData>> outEdges = n.getOutEdges();
-                for (Edge<NodeData, EdgeData> e : outEdges) {
-                    Node<NodeData, EdgeData> succ = e.getDest();
-                    if (succ.getData().isDummy()) {
-                        //PositionedEdge edge = succ.getData().getEdge();
-                        List<Point> points = new ArrayList<Point>();
-                        assignToRealObjects(layerSizes, succ, points);
-                    } else {
-                        List<Point> points = new ArrayList<Point>();
-
-                        EdgeData otherEdgeData = e.getData();
-                        points.addAll(otherEdgeData.getAbsoluteStartPoints());
-                        Link otherEdge = otherEdgeData.getEdge();
-                        Point relFrom = new Point(otherEdgeData.getRelativeStart());
-                        Point from = otherEdge.getFrom().getVertex().getPosition();
-                        relFrom.move(relFrom.x + from.x, relFrom.y + from.y);
-                        points.add(relFrom);
-
-                        Point relTo = new Point(otherEdgeData.getRelativeEnd());
-                        Point to = otherEdge.getTo().getVertex().getPosition();
-                        relTo.move(relTo.x + to.x, relTo.y + to.y);
-                        assert from != null;
-                        assert to != null;
-                        points.add(relTo);
-                        points.addAll(otherEdgeData.getAbsoluteEndPoints());
-                        e.getData().getEdge().setControlPoints(points);
-                    }
-                }
-            }
-        }
-
-        assignRealTiming.stop();
-
-        initTiming.print();
-        removeCyclesTiming.print();
-        reversedEdgesTiming.print();
-        assignLayersTiming.print();
-        dummyNodesTiming.print();
-        crossingReductionTiming.print();
-        assignCoordinatesTiming.print();
-        assignRealTiming.print();
-        rootVertexTiming.print();
-        createEdgesTiming.print();
-        optimizeMedianTiming.print();
-    }
-
-    public boolean onOneLine(Point p1, Point p2, Point p3) {
-        int xoff1 = p1.x - p2.x;
-        int yoff1 = p1.y - p2.y;
-        int xoff2 = p3.x - p2.x;
-        int yoff2 = p3.y - p2.x;
-
-        return (xoff1 * yoff2 - yoff1 * xoff2 == 0);
-    }
-
-    private void assignToRealObjects(int layerSizes[], Node<NodeData, EdgeData> cur, List<Point> points) {
-        assert cur.getData().isDummy();
-
-        ArrayList<Point> otherPoints = new ArrayList<Point>(points);
-
-        int size = layerSizes[cur.getData().getLayer()];
-        otherPoints.add(new Point(cur.getData().getX(), cur.getData().getY() - size / 2));
-        if (otherPoints.size() >= 3 && onOneLine(otherPoints.get(otherPoints.size() - 1), otherPoints.get(otherPoints.size() - 2), otherPoints.get(otherPoints.size() - 3))) {
-            otherPoints.remove(otherPoints.size() - 2);
-        }
-        otherPoints.add(new Point(cur.getData().getX(), cur.getData().getY() + size / 2));
-        if (otherPoints.size() >= 3 && onOneLine(otherPoints.get(otherPoints.size() - 1), otherPoints.get(otherPoints.size() - 2), otherPoints.get(otherPoints.size() - 3))) {
-            otherPoints.remove(otherPoints.size() - 2);
-        }
-
-        for (int i = 0; i < cur.getOutEdges().size(); i++) {
-            Node<NodeData, EdgeData> otherSucc = cur.getOutEdges().get(i).getDest();
-
-            if (otherSucc.getData().isDummy()) {
-                assignToRealObjects(layerSizes, otherSucc, otherPoints);
-            } else {
-                EdgeData otherEdgeData = cur.getOutEdges().get(i).getData();
-                Link otherEdge = otherEdgeData.getEdge();
-
-                List<Point> middlePoints = new ArrayList<Point>(otherPoints);
-                if (cur.getOutEdges().get(i).getData().isReversed()) {
-                    Collections.reverse(middlePoints);
-                }
-
-                ArrayList<Point> copy = new ArrayList<Point>();
-                Point relFrom = new Point(otherEdgeData.getRelativeStart());
-                Point from = otherEdge.getFrom().getVertex().getPosition();
-                //int moveUp = (size - otherEdge.getFrom().getVertex().getSize().height) / 2;
-                relFrom.move(relFrom.x + from.x, relFrom.y + from.y);
-                copy.addAll(otherEdgeData.getAbsoluteStartPoints());
-                copy.add(relFrom);
-                copy.addAll(middlePoints);
-
-                Point relTo = new Point(otherEdgeData.getRelativeEnd());
-                Point to = otherEdge.getTo().getVertex().getPosition();
-                relTo.move(relTo.x + to.x, relTo.y + to.y);
-                copy.add(relTo);
-
-                copy.addAll(otherEdgeData.getAbsoluteEndPoints());
-
-
-                otherEdge.setControlPoints(copy);
-            }
-        }
-    }
-
-    private boolean checkDummyNodes() {
-        for (Edge<NodeData, EdgeData> e : graph.getEdges()) {
-            if (e.getSource().getData().getLayer() != e.getDest().getData().getLayer() - 1) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    private void insertDummyNodes(ArrayList<Node<NodeData, EdgeData>> layers[]) {
-
-        int sum = 0;
-        List<Node<NodeData, EdgeData>> nodes = new ArrayList<Node<NodeData, EdgeData>>(graph.getNodes());
-        int edgeCount = 0;
-        int innerMostLoop = 0;
-
-        for (Node<NodeData, EdgeData> n : nodes) {
-            List<Edge<NodeData, EdgeData>> edges = new ArrayList<Edge<NodeData, EdgeData>>(n.getOutEdges());
-            for (Edge<NodeData, EdgeData> e : edges) {
-
-                edgeCount++;
-                Link edge = e.getData().getEdge();
-                Node<NodeData, EdgeData> destNode = e.getDest();
-                Node<NodeData, EdgeData> lastNode = n;
-                Edge<NodeData, EdgeData> lastEdge = e;
-
-                boolean searchForNode = (combine != Combine.NONE);
-                for (int i = n.getData().getLayer() + 1; i < destNode.getData().getLayer(); i++) {
-
-                    Node<NodeData, EdgeData> foundNode = null;
-                    if (searchForNode) {
-                        for (Node<NodeData, EdgeData> sameLayerNode : layers[i]) {
-                            innerMostLoop++;
-
-                            if (combine == Combine.SAME_OUTPUTS) {
-                                if (sameLayerNode.getData().isDummy() && sameLayerNode.getData().getEdge().getFrom() == edge.getFrom()) {
-                                    foundNode = sameLayerNode;
-                                    break;
-                                }
-                            } else if (combine == Combine.SAME_INPUTS) {
-                                if (sameLayerNode.getData().isDummy() && sameLayerNode.getData().getEdge().getTo() == edge.getTo()) {
-                                    foundNode = sameLayerNode;
-                                    break;
-                                }
-                            }
-                        }
-                    }
-
-                    if (foundNode == null) {
-                        searchForNode = false;
-                        NodeData intermediateData = new NodeData(edge);
-                        Node<NodeData, EdgeData> curNode = graph.createNode(intermediateData, null);
-                        curNode.getData().setLayer(i);
-                        layers[i].add(0, curNode);
-                        sum++;
-                        lastEdge.remove();
-                        graph.createEdge(lastNode, curNode, e.getData(), null);
-                        assert lastNode.getData().getLayer() == curNode.getData().getLayer() - 1;
-                        lastEdge = graph.createEdge(curNode, destNode, e.getData(), null);
-                        lastNode = curNode;
-                    } else {
-                        lastEdge.remove();
-                        lastEdge = graph.createEdge(foundNode, destNode, e.getData(), null);
-                        lastNode = foundNode;
-                    }
-
-                }
-            }
-        }
-
-        if (TRACE) {
-            System.out.println("Number of edges: " + edgeCount);
-        }
-        if (TRACE) {
-            System.out.println("Dummy nodes inserted: " + sum);
-        }
-    }
-
-    private void assignLayerCoordinates(ArrayList<Node<NodeData, EdgeData>> layers[], int layerSizes[]) {
-        int cur = 0;
-        for (int i = 0; i < layers.length; i++) {
-            int maxHeight = 0;
-            for (Node<NodeData, EdgeData> n : layers[i]) {
-                maxHeight = Math.max(maxHeight, n.getData().getHeight());
-            }
-
-            layerSizes[i] = maxHeight;
-            for (Node<NodeData, EdgeData> n : layers[i]) {
-                int curCoordinate = cur + (maxHeight - n.getData().getHeight()) / 2;
-                n.getData().setLayerCoordinate(curCoordinate);
-            }
-            cur += maxHeight + layerOffset;
-
-        }
-    }
-
-    private void assignCoordinates(ArrayList<Node<NodeData, EdgeData>> layers[]) {
-
-        // TODO: change this
-        for (int i = 0; i < layers.length; i++) {
-            ArrayList<Node<NodeData, EdgeData>> curArray = layers[i];
-            int curY = 0;
-            for (Node<NodeData, EdgeData> n : curArray) {
-
-                n.getData().setCoordinate(curY);
-                if (!n.getData().isDummy()) {
-                    curY += n.getData().getWidth();
-                }
-                curY += OFFSET;
-
-            }
-        }
-
-        int curSol = evaluateSolution();
-        if (TRACE) {
-            System.out.println("First coordinate solution found: " + curSol);
-        }
-
-        // Sort to correct order
-        for (int i = 0; i < layers.length; i++) {
-            Collections.sort(layers[i], new Comparator<Node<NodeData, EdgeData>>() {
-
-                public int compare(Node<NodeData, EdgeData> o1, Node<NodeData, EdgeData> o2) {
-                    if (o2.getData().isDummy()) {
-                        return 1;
-                    } else if (o1.getData().isDummy()) {
-                        return -1;
-                    }
-                    return o2.getInEdges().size() + o2.getOutEdges().size() - o1.getInEdges().size() - o1.getOutEdges().size();
-                }
-            });
-        }
-
-
-        optimizeMedianTiming.start();
-        for (int i = 0; i < 2; i++) {
-            optimizeMedian(layers);
-            curSol = evaluateSolution();
-            if (TRACE) {
-                System.out.println("Current coordinate solution found: " + curSol);
-            }
-        }
-        optimizeMedianTiming.stop();
-        normalizeCoordinate();
-
-    }
-
-    private void normalizeCoordinate() {
-
-        int min = Integer.MAX_VALUE;
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            min = Math.min(min, n.getData().getCoordinate());
-        }
-
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            n.getData().setCoordinate(n.getData().getCoordinate() - min);
-        }
-
-    }
-
-    private void optimizeMedian(ArrayList<Node<NodeData, EdgeData>> layers[]) {
-
-        // Downsweep
-        for (int i = 1; i < layers.length; i++) {
-
-            ArrayList<Node<NodeData, EdgeData>> processingList = layers[i];
-            ArrayList<Node<NodeData, EdgeData>> alreadyAssigned = new ArrayList<Node<NodeData, EdgeData>>();
-            for (Node<NodeData, EdgeData> n : processingList) {
-
-
-                ArrayList<Node<NodeData, EdgeData>> preds = new ArrayList<Node<NodeData, EdgeData>>(n.getPredecessors());
-                int pos = n.getData().getCoordinate();
-                if (preds.size() > 0) {
-
-                    Collections.sort(preds, new Comparator<Node<NodeData, EdgeData>>() {
-
-                        public int compare(Node<NodeData, EdgeData> o1, Node<NodeData, EdgeData> o2) {
-                            return o1.getData().getCoordinate() - o2.getData().getCoordinate();
-                        }
-                    });
-
-                    if (preds.size() % 2 == 0) {
-                        assert preds.size() >= 2;
-                        pos = (preds.get(preds.size() / 2).getData().getCoordinate() - calcRelativeCoordinate(preds.get(preds.size() / 2), n) + preds.get(preds.size() / 2 - 1).getData().getCoordinate() - calcRelativeCoordinate(preds.get(preds.size() / 2 - 1), n)) / 2;
-                    } else {
-                        assert preds.size() >= 1;
-                        pos = preds.get(preds.size() / 2).getData().getCoordinate() - calcRelativeCoordinate(preds.get(preds.size() / 2), n);
-                    }
-                }
-
-                tryAdding(alreadyAssigned, n, pos);
-            }
-        }
-        // Upsweep
-        for (int i = layers.length - 2; i >= 0; i--) {
-            ArrayList<Node<NodeData, EdgeData>> processingList = layers[i];
-            ArrayList<Node<NodeData, EdgeData>> alreadyAssigned = new ArrayList<Node<NodeData, EdgeData>>();
-            for (Node<NodeData, EdgeData> n : processingList) {
-
-                ArrayList<Node<NodeData, EdgeData>> succs = new ArrayList<Node<NodeData, EdgeData>>(n.getSuccessors());
-                int pos = n.getData().getCoordinate();
-                if (succs.size() > 0) {
-
-                    Collections.sort(succs, new Comparator<Node<NodeData, EdgeData>>() {
-
-                        public int compare(Node<NodeData, EdgeData> o1, Node<NodeData, EdgeData> o2) {
-                            return o1.getData().getCoordinate() - o2.getData().getCoordinate();
-                        }
-                    });
-
-                    if (succs.size() % 2 == 0) {
-                        assert succs.size() >= 2;
-                        pos = (succs.get(succs.size() / 2).getData().getCoordinate() - calcRelativeCoordinate(n, succs.get(succs.size() / 2)) + succs.get(succs.size() / 2 - 1).getData().getCoordinate() - calcRelativeCoordinate(n, succs.get(succs.size() / 2 - 1))) / 2;
-                    } else {
-                        assert succs.size() >= 1;
-                        pos = succs.get(succs.size() / 2).getData().getCoordinate() - calcRelativeCoordinate(n, succs.get(succs.size() / 2));
-                    }
-                }
-
-                tryAdding(alreadyAssigned, n, pos);
-            }
-        }
-    }
-
-    private int median(ArrayList<Integer> arr) {
-        assert arr.size() > 0;
-        Collections.sort(arr);
-        if (arr.size() % 2 == 0) {
-            return (arr.get(arr.size() / 2) + arr.get(arr.size() / 2 - 1)) / 2;
-        } else {
-            return arr.get(arr.size() / 2);
-        }
-    }
-
-    private int calcRelativeCoordinate(Node<NodeData, EdgeData> n, Node<NodeData, EdgeData> succ) {
-
-        if (n.getData().isDummy() && succ.getData().isDummy()) {
-            return 0;
-        }
-
-        int pos = 0;
-        int pos2 = 0;
-        ArrayList<Integer> coords2 = new ArrayList<Integer>();
-        ArrayList<Integer> coords = new ArrayList<Integer>();
-        /*if(!n.getData().isDummy())*/ {
-            for (Edge<NodeData, EdgeData> e : n.getOutEdges()) {
-
-                //System.out.println("reversed: " + e.getData().isReversed());
-                if (e.getDest() == succ) {
-
-                    if (e.getData().isReversed()) {
-                        if (!n.getData().isDummy()) {
-                            coords.add(e.getData().getRelativeEnd().x);
-                        }
-
-                        if (!succ.getData().isDummy()) {
-                            coords2.add(e.getData().getRelativeStart().x);
-                        }
-                    } else {
-                        if (!n.getData().isDummy()) {
-                            coords.add(e.getData().getRelativeStart().x);
-                        }
-
-                        if (!succ.getData().isDummy()) {
-                            coords2.add(e.getData().getRelativeEnd().x);
-                        }
-                    }
-                }
-            }
-
-            // assert coords.size() > 0;
-            if (!n.getData().isDummy()) {
-                pos = median(coords);
-            }
-
-            if (!succ.getData().isDummy()) {
-                pos2 = median(coords2);
-            }
-        }
-        //System.out.println("coords=" + coords);
-        //System.out.println("coords2=" + coords2);
-
-        return pos - pos2;
-    }
-
-    private boolean intersect(int v1, int w1, int v2, int w2) {
-        if (v1 >= v2 && v1 < v2 + w2) {
-            return true;
-        }
-        if (v1 + w1 > v2 && v1 + w1 < v2 + w2) {
-            return true;
-        }
-        if (v1 < v2 && v1 + w1 > v2) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean intersect(Node<NodeData, EdgeData> n1, Node<NodeData, EdgeData> n2) {
-        return intersect(n1.getData().getCoordinate(), n1.getData().getWidth() + OFFSET, n2.getData().getCoordinate(), n2.getData().getWidth() + OFFSET);
-    }
-
-    private void tryAdding(List<Node<NodeData, EdgeData>> alreadyAssigned, Node<NodeData, EdgeData> node, int pos) {
-
-        boolean doesIntersect = false;
-        node.getData().setCoordinate(pos);
-        for (Node<NodeData, EdgeData> n : alreadyAssigned) {
-            if (n.getData().getCoordinate() + n.getData().getWidth() < pos) {
-                break;
-            } else if (intersect(node, n)) {
-                doesIntersect = true;
-                break;
-            }
-
-        }
-
-        if (!doesIntersect) {
-
-            // Everything fine, just place the node
-            int z = 0;
-            for (Node<NodeData, EdgeData> n : alreadyAssigned) {
-                if (pos > n.getData().getCoordinate()) {
-                    break;
-                }
-                z++;
-            }
-
-            if (z == -1) {
-                z = alreadyAssigned.size();
-            }
-
-
-            if (ASSERT) {
-                assert !findOverlap(alreadyAssigned, node);
-            }
-            alreadyAssigned.add(z, node);
-
-        } else {
-
-            assert alreadyAssigned.size() > 0;
-
-            // Search for alternative location
-            int minOffset = Integer.MAX_VALUE;
-            int minIndex = -1;
-            int minPos = 0;
-            int w = node.getData().getWidth() + OFFSET;
-
-            // Try top-most
-            minIndex = 0;
-            minPos = alreadyAssigned.get(0).getData().getCoordinate() + alreadyAssigned.get(0).getData().getWidth() + OFFSET;
-            minOffset = Math.abs(minPos - pos);
-
-            // Try bottom-most
-            Node<NodeData, EdgeData> lastNode = alreadyAssigned.get(alreadyAssigned.size() - 1);
-            int lastPos = lastNode.getData().getCoordinate() - w;
-            int lastOffset = Math.abs(lastPos - pos);
-            if (lastOffset < minOffset) {
-                minPos = lastPos;
-                minOffset = lastOffset;
-                minIndex = alreadyAssigned.size();
-            }
-
-            // Try between
-            for (int i = 0; i < alreadyAssigned.size() - 1; i++) {
-                Node<NodeData, EdgeData> curNode = alreadyAssigned.get(i);
-                Node<NodeData, EdgeData> nextNode = alreadyAssigned.get(i + 1);
-
-                int start = nextNode.getData().getCoordinate() + nextNode.getData().getWidth() + OFFSET;
-                int end = curNode.getData().getCoordinate() - OFFSET;
-
-                int bestPoss = end - node.getData().getWidth();
-                if (bestPoss < pos && pos - bestPoss > minOffset) {
-                    // No better solution possible => break
-                    break;
-                }
-
-                if (end - start >= node.getData().getWidth()) {
-                    // Node could fit here
-                    int cand1 = start;
-                    int cand2 = end - node.getData().getWidth();
-                    int off1 = Math.abs(cand1 - pos);
-                    int off2 = Math.abs(cand2 - pos);
-                    if (off1 < minOffset) {
-                        minPos = cand1;
-                        minOffset = off1;
-                        minIndex = i + 1;
-                    }
-
-                    if (off2 < minOffset) {
-                        minPos = cand2;
-                        minOffset = off2;
-                        minIndex = i + 1;
-                    }
-                }
-            }
-
-            assert minIndex != -1;
-            node.getData().setCoordinate(minPos);
-            if (ASSERT) {
-                assert !findOverlap(alreadyAssigned, node);
-            }
-            alreadyAssigned.add(minIndex, node);
-        }
-
-    }
-
-    private boolean findOverlap(List<Node<NodeData, EdgeData>> nodes, Node<NodeData, EdgeData> node) {
-
-        for (Node<NodeData, EdgeData> n1 : nodes) {
-            if (intersect(n1, node)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private int evaluateSolution() {
-
-        int sum = 0;
-        for (Edge<NodeData, EdgeData> e : graph.getEdges()) {
-            Node<NodeData, EdgeData> source = e.getSource();
-            Node<NodeData, EdgeData> dest = e.getDest();
-            int offset = 0;
-            offset = Math.abs(source.getData().getCoordinate() - dest.getData().getCoordinate());
-            sum += offset;
-        }
-
-        return sum;
-    }
-
-    private void crossingReduction(ArrayList<Node<NodeData, EdgeData>> layers[]) {
-
-        for (int i = 0; i < layers.length - 1; i++) {
-
-            ArrayList<Node<NodeData, EdgeData>> curNodes = layers[i];
-            ArrayList<Node<NodeData, EdgeData>> nextNodes = layers[i + 1];
-            for (Node<NodeData, EdgeData> n : curNodes) {
-                for (Node<NodeData, EdgeData> succ : n.getSuccessors()) {
-                    if (ASSERT) {
-                        assert nextNodes.contains(succ);
-                    }
-                    nextNodes.remove(succ);
-                    nextNodes.add(succ);
-                }
-            }
-
-        }
-
-    }
-
-    private void removeCycles(Set<Node<NodeData, EdgeData>> rootNodes) {
-        final List<Edge<NodeData, EdgeData>> reversedEdges = new ArrayList<Edge<NodeData, EdgeData>>();
-
-
-        int removedCount = 0;
-        int reversedCount = 0;
-
-        Graph.DFSTraversalVisitor visitor = graph.new DFSTraversalVisitor() {
-
-            @Override
-            public boolean visitEdge(Edge<NodeData, EdgeData> e, boolean backEdge) {
-                if (backEdge) {
-                    if (ASSERT) {
-                        assert !reversedEdges.contains(e);
-                    }
-                    reversedEdges.add(e);
-                    e.getData().setReversed(!e.getData().isReversed());
-                }
-
-                return e.getData().isImportant();
-            }
-        };
-        Set<Node<NodeData, EdgeData>> nodes = new HashSet<Node<NodeData, EdgeData>>();
-        nodes.addAll(rootNodes);
-
-        assert nodes.size() > 0;
-
-        this.graph.traverseDFS(nodes, visitor);
-
-        for (Edge<NodeData, EdgeData> e : reversedEdges) {
-            if (e.isSelfLoop()) {
-                e.remove();
-                removedCount++;
-            } else {
-                e.reverse();
-                reversedCount++;
-            }
-        }
-    }
-
-    private boolean checkRemoveCycles() {
-        return !graph.hasCycles();
-    }
-    // Only used by assignLayers
-    private int maxLayerTemp;
-
-    private int assignLayers(Set<Node<NodeData, EdgeData>> rootNodes, Set<? extends Vertex> firstLayerHints,
-            Set<? extends Vertex> lastLayerHints) {
-        this.maxLayerTemp = -1;
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            n.getData().setLayer(-1);
-        }
-
-        Graph.BFSTraversalVisitor traverser = graph.new BFSTraversalVisitor() {
-
-            @Override
-            public void visitNode(Node<NodeData, EdgeData> n, int depth) {
-                if (depth > n.getData().getLayer()) {
-                    n.getData().setLayer(depth);
-                    maxLayerTemp = Math.max(maxLayerTemp, depth);
-                }
-            }
-        };
-
-        for (Node<NodeData, EdgeData> n : rootNodes) {
-            if (n.getData().getLayer() == -1) {
-                this.graph.traverseBFS(n, traverser, true);
-            }
-        }
-
-        for (Vertex v : firstLayerHints) {
-            assert nodeMap.containsKey(v);
-            nodeMap.get(v).getData().setLayer(0);
-        }
-
-        for (Vertex v : lastLayerHints) {
-            assert nodeMap.containsKey(v);
-            nodeMap.get(v).getData().setLayer(maxLayerTemp);
-        }
-
-        return maxLayerTemp;
-    }
-
-    private boolean checkAssignLayers() {
-
-        for (Edge<NodeData, EdgeData> e : graph.getEdges()) {
-            Node<NodeData, EdgeData> source = e.getSource();
-            Node<NodeData, EdgeData> dest = e.getDest();
-
-
-            if (source.getData().getLayer() >= dest.getData().getLayer()) {
-                return false;
-            }
-        }
-        int maxLayer = 0;
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            assert n.getData().getLayer() >= 0;
-            if (n.getData().getLayer() > maxLayer) {
-                maxLayer = n.getData().getLayer();
-            }
-        }
-
-        int countPerLayer[] = new int[maxLayer + 1];
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            countPerLayer[n.getData().getLayer()]++;
-        }
-
-        if (TRACE) {
-            System.out.println("Number of layers: " + maxLayer);
-        }
-        return true;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/Layout/nbproject/project.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Layout/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Cluster.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.layout;
-
-import java.awt.Rectangle;
-import java.util.Set;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public interface Cluster extends Comparable<Cluster> {
-
-    public Cluster getOuter();
-
-    public void setBounds(Rectangle r);
-
-    public Set<? extends Cluster> getSuccessors();
-
-    public Set<? extends Cluster> getPredecessors();
-}
--- a/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutGraph.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutGraph.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,11 +23,7 @@
  */
 package com.sun.hotspot.igv.layout;
 
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
+import java.util.*;
 
 /**
  *
@@ -49,10 +45,10 @@
         this.links = links;
         assert verify();
 
-        vertices = new TreeSet<Vertex>();
-        portLinks = new HashMap<Port, Set<Link>>();
-        inputPorts = new HashMap<Vertex, Set<Port>>();
-        outputPorts = new HashMap<Vertex, Set<Port>>();
+        vertices = new TreeSet<>();
+        portLinks = new HashMap<>(links.size());
+        inputPorts = new HashMap<>(links.size());
+        outputPorts = new HashMap<>(links.size());
 
         for (Link l : links) {
             Port p = l.getFrom();
@@ -76,7 +72,7 @@
             }
 
             if (!portLinks.containsKey(p)) {
-                HashSet<Link> hashSet = new HashSet<Link>(3);
+                HashSet<Link> hashSet = new HashSet<>(3);
                 portLinks.put(p, hashSet);
             }
 
@@ -148,11 +144,11 @@
 
     // Returns a set of vertices with the following properties:
     // - All Vertices in the set startingRoots are elements of the set.
-    // - When starting a DFS at every vertex in the set, every vertex of the
+    // - When starting a DFS at every vertex in the set, every vertex of the 
     //   whole graph is visited.
     public Set<Vertex> findRootVertices(Set<Vertex> startingRoots) {
 
-        Set<Vertex> notRootSet = new HashSet<Vertex>();
+        Set<Vertex> notRootSet = new HashSet<>();
         for (Vertex v : startingRoots) {
             if (!notRootSet.contains(v)) {
                 markNotRoot(notRootSet, v, v);
@@ -174,7 +170,7 @@
             }
         }
 
-        Set<Vertex> result = new HashSet<Vertex>();
+        Set<Vertex> result = new HashSet<>();
         for (Vertex v : tmpVertices) {
             if (!notRootSet.contains(v)) {
                 result.add(v);
@@ -187,16 +183,4 @@
     public Set<Vertex> findRootVertices() {
         return findRootVertices(new HashSet<Vertex>());
     }
-
-    public SortedSet<Cluster> getClusters() {
-
-        SortedSet<Cluster> clusters = new TreeSet<Cluster>();
-        for (Vertex v : getVertices()) {
-            if (v.getCluster() != null) {
-                clusters.add(v.getCluster());
-            }
-        }
-
-        return clusters;
-    }
 }
--- a/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Link.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Link.java	Mon Feb 27 13:10:13 2012 +0100
@@ -35,6 +35,8 @@
     public Port getFrom();
 
     public Port getTo();
+    
+    public boolean isVIP();
 
     public List<Point> getControlPoints();
 
--- a/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Vertex.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Vertex.java	Mon Feb 27 13:10:13 2012 +0100
@@ -32,8 +32,6 @@
  */
 public interface Vertex extends Comparable<Vertex> {
 
-    public Cluster getCluster();
-
     public Dimension getSize();
 
     public Point getPosition();
--- a/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/build-impl.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -4,6 +4,13 @@
 ***         EDIT ../build.xml INSTEAD         ***
 -->
 <project name="com.sun.hotspot.igv.connection-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
     <property file="nbproject/private/suite-private.properties"/>
     <property file="nbproject/suite.properties"/>
     <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
@@ -16,13 +23,21 @@
             <property name="@{name}" value="${@{value}}"/>
         </sequential>
     </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
     <property file="${user.properties.file}"/>
     <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
-    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
-    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
         <condition>
             <not>
-                <available file="${harness.dir}" type="dir"/>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
             </not>
         </condition>
     </fail>
--- a/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/genfiles.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,8 +1,5 @@
-build.xml.data.CRC32=f8e21cb6
-build.xml.script.CRC32=a265137e
-build.xml.stylesheet.CRC32=79c3b980
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=f8e21cb6
-nbproject/build-impl.xml.script.CRC32=36f3138c
-nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
+nbproject/build-impl.xml.data.CRC32=5a0e591e
+nbproject/build-impl.xml.script.CRC32=61516e53
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.45.1
--- a/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/project.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/project.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -27,7 +27,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.11.1.1</specification-version>
+                        <specification-version>7.30.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -35,7 +35,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.5.1</specification-version>
+                        <specification-version>7.18.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -43,7 +43,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.10.1.1</specification-version>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
                     </run-dependency>
                 </dependency>
             </module-dependencies>
--- a/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/META-INF/services/com.sun.hotspot.igv.data.services.GroupReceiver	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-com.sun.hotspot.igv.connection.Server
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/com/sun/hotspot/igv/connection/Client.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/com/sun/hotspot/igv/connection/Client.java	Mon Feb 27 13:10:13 2012 +0100
@@ -24,73 +24,51 @@
  */
 package com.sun.hotspot.igv.connection;
 
-import com.sun.hotspot.igv.data.Group;
+import com.sun.hotspot.igv.data.serialization.Parser;
 import com.sun.hotspot.igv.data.services.GroupCallback;
-import com.sun.hotspot.igv.data.serialization.Parser;
-import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher;
+import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.Socket;
-import javax.swing.JTextField;
 import org.openide.util.Exceptions;
-import org.openide.xml.XMLUtil;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public class Client implements Runnable, GroupCallback {
+public class Client implements Runnable {
 
     private Socket socket;
-    private JTextField networkTextField;
     private GroupCallback callback;
 
-    public Client(Socket socket, JTextField networkTextField, GroupCallback callback) {
+    public Client(Socket socket, GroupCallback callback) {
         this.callback = callback;
         this.socket = socket;
-        this.networkTextField = networkTextField;
     }
 
+    @Override
     public void run() {
 
         try {
-            InputStream inputStream = socket.getInputStream();
-
-            if (networkTextField.isEnabled()) {
-
-                socket.getOutputStream().write('y');
-                InputSource is = new InputSource(inputStream);
+            InputStream inputStream = new BufferedInputStream(socket.getInputStream());
+            InputSource is = new InputSource(inputStream);
 
-                try {
-                    XMLReader reader = XMLUtil.createXMLReader();
-                    Parser parser = new Parser(this);
-                    parser.parse(reader, is, null);
-                } catch (SAXException ex) {
-                    ex.printStackTrace();
-                }
-            } else {
-                socket.getOutputStream().write('n');
+            try {
+                Parser parser = new Parser(callback);
+                parser.parse(is, null);
+            } catch (SAXException ex) {
+                ex.printStackTrace();
             }
-
-            socket.close();
         } catch (IOException ex) {
             Exceptions.printStackTrace(ex);
+        } finally {
+            try {
+                socket.close();
+            } catch (IOException ex) {
+                Exceptions.printStackTrace(ex);
+            }
         }
     }
-
-    public void started(final Group g) {
-        try {
-            RegexpPropertyMatcher matcher = new RegexpPropertyMatcher("name", ".*" + networkTextField.getText() + ".*");
-            if (g.getProperties().selectSingle(matcher) != null && networkTextField.isEnabled()) {
-                socket.getOutputStream().write('y');
-                callback.started(g);
-            } else {
-                socket.getOutputStream().write('n');
-            }
-        } catch (IOException e) {
-        }
-    }
-}
+}
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/com/sun/hotspot/igv/connection/Server.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/com/sun/hotspot/igv/connection/Server.java	Mon Feb 27 13:10:13 2012 +0100
@@ -24,17 +24,13 @@
  */
 package com.sun.hotspot.igv.connection;
 
-import com.sun.hotspot.igv.data.Group;
 import com.sun.hotspot.igv.data.services.GroupCallback;
-import com.sun.hotspot.igv.data.services.GroupReceiver;
 import com.sun.hotspot.igv.settings.Settings;
-import java.awt.Component;
 import java.io.IOException;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.util.prefs.PreferenceChangeEvent;
 import java.util.prefs.PreferenceChangeListener;
-import javax.swing.SwingUtilities;
 import org.openide.DialogDisplayer;
 import org.openide.NotifyDescriptor;
 import org.openide.util.RequestProcessor;
@@ -43,51 +39,21 @@
  *
  * @author Thomas Wuerthinger
  */
-public class Server implements GroupCallback, GroupReceiver, PreferenceChangeListener {
+public class Server implements PreferenceChangeListener {
 
-    private javax.swing.JPanel jPanel1;
-    private javax.swing.JCheckBox networkCheckBox;
-    private javax.swing.JTextField networkTextField;
     private ServerSocket serverSocket;
     private GroupCallback callback;
     private int port;
     private Runnable serverRunnable;
 
-    public Component init(GroupCallback callback) {
+    public Server(GroupCallback callback) {
 
         this.callback = callback;
-
-        jPanel1 = new javax.swing.JPanel();
-        networkTextField = new javax.swing.JTextField();
-        networkCheckBox = new javax.swing.JCheckBox();
-
-
-        jPanel1.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5));
-        jPanel1.setLayout(new java.awt.BorderLayout(10, 10));
-        jPanel1.add(networkTextField, java.awt.BorderLayout.CENTER);
-
-        networkCheckBox.setSelected(true);
-        org.openide.awt.Mnemonics.setLocalizedText(networkCheckBox, "Receive when name contains");
-        networkCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
-        networkCheckBox.setMargin(new java.awt.Insets(0, 0, 0, 0));
-        networkCheckBox.addChangeListener(new javax.swing.event.ChangeListener() {
-
-            public void stateChanged(javax.swing.event.ChangeEvent evt) {
-                networkCheckBoxChanged(evt);
-            }
-        });
-        jPanel1.add(networkCheckBox, java.awt.BorderLayout.WEST);
-        networkCheckBox.getAccessibleContext().setAccessibleName("Read from network when name contains");
-
         initializeNetwork();
         Settings.get().addPreferenceChangeListener(this);
-        return jPanel1;
     }
 
-    private void networkCheckBoxChanged(javax.swing.event.ChangeEvent evt) {
-        networkTextField.setEnabled(networkCheckBox.isSelected());
-    }
-
+    @Override
     public void preferenceChange(PreferenceChangeEvent e) {
 
         int curPort = Integer.parseInt(Settings.get().get(Settings.PORT, Settings.PORT_DEFAULT));
@@ -110,6 +76,7 @@
 
         Runnable runnable = new Runnable() {
 
+            @Override
             public void run() {
                 while (true) {
                     try {
@@ -118,7 +85,7 @@
                             clientSocket.close();
                             return;
                         }
-                        RequestProcessor.getDefault().post(new Client(clientSocket, networkTextField, Server.this), 0, Thread.MAX_PRIORITY);
+                        RequestProcessor.getDefault().post(new Client(clientSocket, callback), 0, Thread.MAX_PRIORITY);
                     } catch (IOException ex) {
                         serverSocket = null;
                         NotifyDescriptor message = new NotifyDescriptor.Message("Error during listening for incoming connections. Listening for incoming data is disabled.", NotifyDescriptor.ERROR_MESSAGE);
@@ -133,13 +100,4 @@
 
         RequestProcessor.getDefault().post(runnable, 0, Thread.MAX_PRIORITY);
     }
-
-    public void started(final Group g) {
-        SwingUtilities.invokeLater(new Runnable() {
-
-            public void run() {
-                callback.started(g);
-            }
-        });
-    }
 }
--- a/src/share/tools/IdealGraphVisualizer/README	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/README	Mon Feb 27 13:10:13 2012 +0100
@@ -5,16 +5,11 @@
 was the primary target of the tool.  The tool itself is fairly general
 with only a few modules that contain C2 specific elements.
 
-The tool is built on top of the NetBeans 6.1 rich client
+The tool is built on top of the NetBeans 7 rich client
 infrastructure and so requires NetBeans to build.  It currently
 requires Java 6 to run as it needs support for JavaScript for its
 filtering mechanism and assumes it's built into the platform.  It
-should build out of the box with NetBeans 6.1 and Java 6 or later.
-It's possible to run it on 1.5 by including Rhino on the classpath
-though that currently isn't working correctly.  Support for exporting
-graphs as SVG can be enabled by adding batik to the classpath which
-isn't included by default.  It can be built on top of NetBeans 6.0 if
-you change the required modules to be platform7 instead of platform8.
+should build out of the box with NetBeans 7.0 and Java 6 or later.
 
 The JVM support is controlled by the flag -XX:PrintIdealGraphLevel=#
 where # is:
--- a/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/build.xml	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
-<!-- for some information on what you could do (e.g. targets to override). -->
-<!-- If you delete this file and reopen the project it will be recreated. -->
-<project name="com.sun.hotspot.igv.rhino" default="netbeans" basedir=".">
-    <description>Builds, tests, and runs the project com.sun.hotspot.igv.rhino.</description>
-    <import file="nbproject/build-impl.xml"/>
-</project>
--- a/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/manifest.mf	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-Manifest-Version: 1.0
-OpenIDE-Module: com.sun.hotspot.igv.rhino
-OpenIDE-Module-Layer: com/sun/hotspot/igv/rhino/layer.xml
-OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/rhino/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.0
-
--- a/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/build-impl.xml	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-*** GENERATED FROM project.xml - DO NOT EDIT  ***
-***         EDIT ../build.xml INSTEAD         ***
--->
-<project name="com.sun.hotspot.igv.rhino-impl" basedir="..">
-    <property file="nbproject/private/suite-private.properties"/>
-    <property file="nbproject/suite.properties"/>
-    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
-    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
-    <property file="${suite.dir}/nbproject/platform.properties"/>
-    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
-        <attribute name="name"/>
-        <attribute name="value"/>
-        <sequential>
-            <property name="@{name}" value="${@{value}}"/>
-        </sequential>
-    </macrodef>
-    <property file="${user.properties.file}"/>
-    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
-    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
-    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
-        <condition>
-            <not>
-                <available file="${harness.dir}" type="dir"/>
-            </not>
-        </condition>
-    </fail>
-    <import file="${harness.dir}/build.xml"/>
-</project>
--- a/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/genfiles.properties	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-build.xml.data.CRC32=0c3e7912
-build.xml.script.CRC32=44d0050c
-build.xml.stylesheet.CRC32=79c3b980
-# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
-# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=0c3e7912
-nbproject/build-impl.xml.script.CRC32=7aab3f52
-nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- a/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/project.properties	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/project.xml	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://www.netbeans.org/ns/project/1">
-    <type>org.netbeans.modules.apisupport.project</type>
-    <configuration>
-        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
-            <code-name-base>com.sun.hotspot.igv.rhino</code-name-base>
-            <suite-component/>
-            <module-dependencies>
-                <dependency>
-                    <code-name-base>com.sun.hotspot.igv.filter</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.0</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.0</specification-version>
-                    </run-dependency>
-                </dependency>
-            </module-dependencies>
-            <public-packages>
-                <package>com.sun.hotspot.igv.rhino</package>
-            </public-packages>
-        </data>
-    </configuration>
-</project>
--- a/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/suite.properties	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-suite.dir=${basedir}/..
--- a/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/META-INF/services/com.sun.hotspot.igv.filter.ScriptEngineAbstraction	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-com.sun.hotspot.igv.rhino.RhinoScriptEngine
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/Bundle.properties	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-OpenIDE-Module-Name=RhinoScriptEngineProxy
--- a/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/RhinoScriptEngine.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.sun.hotspot.igv.rhino;
-
-import com.sun.hotspot.igv.filter.ScriptEngineAbstraction;
-import com.sun.hotspot.igv.graph.Diagram;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class RhinoScriptEngine implements ScriptEngineAbstraction {
-
-    private String jsHelperText;
-    private Constructor importer;
-    private Method scope_put;
-    private Method cx_evaluateString;
-    private Method context_enter;
-    private Method context_exit;
-
-    public boolean initialize(String s) {
-        this.jsHelperText = s;
-        Class importerTopLevel = null;
-        try {
-            ClassLoader cl = RhinoScriptEngine.class.getClassLoader();
-            Class context = cl.loadClass("org.mozilla.javascript.Context");
-            Class scriptable = cl.loadClass("org.mozilla.javascript.Scriptable");
-            importerTopLevel = cl.loadClass("org.mozilla.javascript.ImporterTopLevel");
-            importer = importerTopLevel.getDeclaredConstructor(context);
-            scope_put = importerTopLevel.getMethod("put", new Class[]{String.class, scriptable, Object.class});
-            cx_evaluateString = context.getDeclaredMethod("evaluateString", new Class[]{scriptable, String.class, String.class, Integer.TYPE, Object.class});
-            context_enter = context.getDeclaredMethod("enter", new Class[0]);
-            context_exit = context.getDeclaredMethod("exit", new Class[0]);
-            return true;
-        } catch (NoSuchMethodException nsme) {
-            return false;
-        } catch (ClassNotFoundException cnfe) {
-            return false;
-        }
-    }
-
-    public void execute(Diagram d, String code) {
-        try {
-            Object cx = context_enter.invoke(null, (Object[]) null);
-            try {
-                Object scope = importer.newInstance(cx);
-                scope_put.invoke(scope, "IO", scope, System.out);
-                scope_put.invoke(scope, "graph", scope, d);
-                cx_evaluateString.invoke(cx, scope, jsHelperText, "jsHelper.js", 1, null);
-                cx_evaluateString.invoke(cx, scope, code, "<cmd>", 1, null);
-            } finally {
-                // Exit from the context.
-                context_exit.invoke(null, (Object[]) null);
-            }
-        } catch (InvocationTargetException iae) {
-        } catch (IllegalAccessException iae) {
-        } catch (InstantiationException iae) {
-        }
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/layer.xml	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
-<filesystem>
-</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.selectioncoordinator" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.selectioncoordinator.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.selectioncoordinator
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/selectioncoordinator/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.selectioncoordinator-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,5 @@
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=13553862
+nbproject/build-impl.xml.script.CRC32=3db87c68
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.45.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/nbproject/platform.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,129 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    gsf1,\
+    harness,\
+    java2,\
+    nb6.1,\
+    profiler3
+disabled.modules=\
+    org.apache.xml.resolver,\
+    org.netbeans.api.debugger,\
+    org.netbeans.api.xml,\
+    org.netbeans.core.execution,\
+    org.netbeans.core.ide,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.nativeaccess,\
+    org.netbeans.core.output2,\
+    org.netbeans.insane,\
+    org.netbeans.lib.cvsclient,\
+    org.netbeans.libs.commons_logging,\
+    org.netbeans.libs.freemarker,\
+    org.netbeans.libs.ini4j,\
+    org.netbeans.libs.jna,\
+    org.netbeans.libs.jsch,\
+    org.netbeans.libs.jsr223,\
+    org.netbeans.libs.lucene,\
+    org.netbeans.libs.svnClientAdapter,\
+    org.netbeans.libs.xerces,\
+    org.netbeans.modules.applemenu,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.classfile,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.db,\
+    org.netbeans.modules.db.core,\
+    org.netbeans.modules.db.drivers,\
+    org.netbeans.modules.db.kit,\
+    org.netbeans.modules.db.mysql,\
+    org.netbeans.modules.db.sql.editor,\
+    org.netbeans.modules.db.sql.visualeditor,\
+    org.netbeans.modules.dbapi,\
+    org.netbeans.modules.defaults,\
+    org.netbeans.modules.diff,\
+    org.netbeans.modules.editor.bookmarks,\
+    org.netbeans.modules.editor.bracesmatching,\
+    org.netbeans.modules.editor.codetemplates,\
+    org.netbeans.modules.editor.completion,\
+    org.netbeans.modules.editor.errorstripe,\
+    org.netbeans.modules.editor.errorstripe.api,\
+    org.netbeans.modules.editor.guards,\
+    org.netbeans.modules.editor.highlights,\
+    org.netbeans.modules.editor.macros,\
+    org.netbeans.modules.editor.plain,\
+    org.netbeans.modules.editor.plain.lib,\
+    org.netbeans.modules.editor.structure,\
+    org.netbeans.modules.extbrowser,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.gototest,\
+    org.netbeans.modules.httpserver,\
+    org.netbeans.modules.ide.kit,\
+    org.netbeans.modules.image,\
+    org.netbeans.modules.javahelp,\
+    org.netbeans.modules.jumpto,\
+    org.netbeans.modules.languages,\
+    org.netbeans.modules.languages.bat,\
+    org.netbeans.modules.languages.diff,\
+    org.netbeans.modules.languages.manifest,\
+    org.netbeans.modules.languages.sh,\
+    org.netbeans.modules.lexer.editorbridge,\
+    org.netbeans.modules.lexer.nbbridge,\
+    org.netbeans.modules.localhistory,\
+    org.netbeans.modules.masterfs,\
+    org.netbeans.modules.mercurial,\
+    org.netbeans.modules.progress.ui,\
+    org.netbeans.modules.project.ant,\
+    org.netbeans.modules.project.libraries,\
+    org.netbeans.modules.projectui,\
+    org.netbeans.modules.projectuiapi,\
+    org.netbeans.modules.properties,\
+    org.netbeans.modules.properties.syntax,\
+    org.netbeans.modules.refactoring.api,\
+    org.netbeans.modules.schema2beans,\
+    org.netbeans.modules.sendopts,\
+    org.netbeans.modules.server,\
+    org.netbeans.modules.servletapi,\
+    org.netbeans.modules.subversion,\
+    org.netbeans.modules.tasklist.kit,\
+    org.netbeans.modules.tasklist.projectint,\
+    org.netbeans.modules.tasklist.todo,\
+    org.netbeans.modules.tasklist.ui,\
+    org.netbeans.modules.templates,\
+    org.netbeans.modules.timers,\
+    org.netbeans.modules.usersguide,\
+    org.netbeans.modules.utilities,\
+    org.netbeans.modules.utilities.project,\
+    org.netbeans.modules.versioning,\
+    org.netbeans.modules.versioning.system.cvss,\
+    org.netbeans.modules.versioning.util,\
+    org.netbeans.modules.web.flyingsaucer,\
+    org.netbeans.modules.xml,\
+    org.netbeans.modules.xml.axi,\
+    org.netbeans.modules.xml.catalog,\
+    org.netbeans.modules.xml.core,\
+    org.netbeans.modules.xml.lexer,\
+    org.netbeans.modules.xml.multiview,\
+    org.netbeans.modules.xml.retriever,\
+    org.netbeans.modules.xml.schema.completion,\
+    org.netbeans.modules.xml.schema.model,\
+    org.netbeans.modules.xml.tax,\
+    org.netbeans.modules.xml.text,\
+    org.netbeans.modules.xml.tools,\
+    org.netbeans.modules.xml.wsdl.model,\
+    org.netbeans.modules.xml.xam,\
+    org.netbeans.modules.xml.xdm,\
+    org.netbeans.modules.xsl,\
+    org.netbeans.spi.debugger.ui,\
+    org.netbeans.spi.editor.hints,\
+    org.netbeans.spi.navigator,\
+    org.netbeans.spi.palette,\
+    org.netbeans.spi.tasklist,\
+    org.netbeans.spi.viewmodel,\
+    org.netbeans.swing.dirchooser,\
+    org.openide.compat,\
+    org.openide.util.enumerations
+enabled.clusters=\
+    ide9,\
+    platform8
+nbjdk.active=default
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.selectioncoordinator</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.sun.hotspot.igv.selectioncoordinator</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/src/com/sun/hotspot/igv/selectioncoordinator/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=SelectionCoordinator
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/src/com/sun/hotspot/igv/selectioncoordinator/SelectionCoordinator.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,139 @@
+/*
+ * 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.sun.hotspot.igv.selectioncoordinator;
+
+import com.sun.hotspot.igv.data.ChangedEvent;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas
+ */
+public class SelectionCoordinator {
+
+    private static SelectionCoordinator singleInstance = new SelectionCoordinator();
+    private Set<Object> selectedObjects;
+    private Set<Object> highlightedObjects;
+    private ChangedEvent<SelectionCoordinator> selectedChangedEvent;
+    private ChangedEvent<SelectionCoordinator> highlightedChangedEvent;
+
+    public static SelectionCoordinator getInstance() {
+        return singleInstance;
+    }
+
+    private SelectionCoordinator() {
+        selectedChangedEvent = new ChangedEvent<>(this);
+        highlightedChangedEvent = new ChangedEvent<>(this);
+        selectedObjects = new HashSet<>();
+        highlightedObjects = new HashSet<>();
+    }
+
+    public Set<Object> getSelectedObjects() {
+        return Collections.unmodifiableSet(selectedObjects);
+    }
+
+    public Set<Object> getHighlightedObjects() {
+        return Collections.unmodifiableSet(highlightedObjects);
+    }
+
+    public ChangedEvent<SelectionCoordinator> getHighlightedChangedEvent() {
+        return highlightedChangedEvent;
+    }
+
+    public ChangedEvent<SelectionCoordinator> getSelectedChangedEvent() {
+        return selectedChangedEvent;
+    }
+
+    public void addHighlighted(Object o) {
+        if (!highlightedObjects.contains(o)) {
+            highlightedObjects.add(o);
+            highlightedObjectsChanged();
+        }
+    }
+
+    public void removeHighlighted(Object o) {
+        if (highlightedObjects.contains(o)) {
+            highlightedObjects.remove(o);
+            highlightedObjectsChanged();
+        }
+    }
+
+    public void addAllHighlighted(Set<? extends Object> s) {
+        int oldSize = highlightedObjects.size();
+        highlightedObjects.addAll(s);
+        if (oldSize != highlightedObjects.size()) {
+            highlightedObjectsChanged();
+        }
+    }
+
+    public void removeAllHighlighted(Set<? extends Object> s) {
+        int oldSize = highlightedObjects.size();
+        highlightedObjects.removeAll(s);
+        if (oldSize != highlightedObjects.size()) {
+            highlightedObjectsChanged();
+        }
+    }
+
+    private void highlightedObjectsChanged() {
+        highlightedChangedEvent.fire();
+
+    }
+
+    public void addAllSelected(Set<? extends Object> s) {
+        int oldSize = selectedObjects.size();
+        selectedObjects.addAll(s);
+        if (oldSize != selectedObjects.size()) {
+            selectedObjectsChanged();
+        }
+    }
+
+    public void removeAllSelected(Set<? extends Object> s) {
+        int oldSize = selectedObjects.size();
+        selectedObjects.removeAll(s);
+        if (oldSize != selectedObjects.size()) {
+            selectedObjectsChanged();
+        }
+    }
+
+    public void setSelectedObjects(Set<? extends Object> s) {
+        assert s != null;
+        selectedObjects.clear();
+        selectedObjects.addAll(s);
+        selectedObjectsChanged();
+    }
+
+    private void selectedObjectsChanged() {
+        selectedChangedEvent.fire();
+    }
+
+    public void setHighlightedObjects(Set<? extends Object> s) {
+        assert s != null;
+        this.highlightedObjects.clear();
+        this.highlightedObjects.addAll(s);
+        highlightedObjectsChanged();
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/project.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/project.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -1,21 +1,29 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://www.netbeans.org/ns/project/1">
-    <type>org.netbeans.modules.apisupport.project</type>
-    <configuration>
-        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
-            <code-name-base>com.sun.hotspot.igv.servercompiler</code-name-base>
-            <suite-component/>
-            <module-dependencies>
-                <dependency>
-                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.0</specification-version>
-                    </run-dependency>
-                </dependency>
-            </module-dependencies>
-            <public-packages/>
-        </data>
-    </configuration>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.servercompiler</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages/>
+        </data>
+    </configuration>
+</project>
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/META-INF/services/com.sun.hotspot.igv.data.services.GroupOrganizer	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-com.sun.hotspot.igv.servercompiler.JavaGroupOrganizer
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/JavaGroupOrganizer.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.sun.hotspot.igv.servercompiler;
-
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.services.GroupOrganizer;
-import com.sun.hotspot.igv.data.Pair;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class JavaGroupOrganizer implements GroupOrganizer {
-
-    public String getName() {
-        return "Java structure";
-    }
-
-    public List<Pair<String, List<Group>>> organize(List<String> subFolders, List<Group> groups) {
-
-        List<Pair<String, List<Group>>> result = new ArrayList<Pair<String, List<Group>>>();
-
-        if (subFolders.size() == 0) {
-            buildResult(result, groups, packageNameProvider);
-        } else if (subFolders.size() == 1) {
-            buildResult(result, groups, classNameProvider);
-        } else if (subFolders.size() == 2) {
-            for (Group g : groups) {
-                List<Group> children = new ArrayList<Group>();
-                children.add(g);
-                Pair<String, List<Group>> p = new Pair<String, List<Group>>();
-                p.setLeft(reducedNameProvider.getName(g));
-                p.setRight(children);
-                result.add(p);
-            }
-        } else {
-            result.add(new Pair<String, List<Group>>("", groups));
-        }
-
-        return result;
-    }
-
-    private void buildResult(List<Pair<String, List<Group>>> result, List<Group> groups, NameProvider provider) {
-        HashMap<String, List<Group>> map = new HashMap<String, List<Group>>();
-        for (Group g : groups) {
-            String s = provider.getName(g);
-
-            if (!map.containsKey(s)) {
-                List<Group> list = new ArrayList<Group>();
-                Pair<String, List<Group>> pair = new Pair<String, List<Group>>(s, list);
-                result.add(pair);
-                map.put(s, list);
-            }
-
-            List<Group> curList = map.get(s);
-            curList.add(g);
-        }
-
-        Collections.sort(result, new Comparator<Pair<String, List<Group>>>() {
-
-            public int compare(Pair<String, List<Group>> a, Pair<String, List<Group>> b) {
-                return a.getLeft().compareTo(b.getLeft());
-            }
-        });
-    }
-
-    private static interface NameProvider {
-
-        public String getName(Group g);
-    }
-    private NameProvider reducedNameProvider = new NameProvider() {
-
-        public String getName(Group g) {
-            String name = g.getName();
-            assert name != null : "name of group must be set!";
-            final String noReducedName = name;
-
-            int firstPoint = name.indexOf(".");
-            if (firstPoint == -1) {
-                return noReducedName;
-            }
-
-            int firstParenthese = name.indexOf("(");
-            if (firstParenthese == -1 || firstParenthese < firstPoint) {
-                return noReducedName;
-            }
-
-            int current = firstPoint;
-            while (current > 0 && name.charAt(current) != ' ') {
-                current--;
-            }
-
-            String tmp = name.substring(0, firstParenthese);
-            int lastPoint = tmp.lastIndexOf(".");
-            if (lastPoint == -1) {
-                return noReducedName;
-            }
-
-            name = name.substring(0, current + 1) + name.substring(lastPoint + 1);
-            return name;
-        }
-    };
-    private NameProvider packageNameProvider = new NameProvider() {
-
-        public String getName(Group g) {
-            String name = g.getName();
-            assert name != null : "name of group must be set!";
-            final String noPackage = "<default>";
-
-            int firstPoint = name.indexOf(".");
-            if (firstPoint == -1) {
-                return noPackage;
-            }
-
-            int firstParenthese = name.indexOf("(");
-            if (firstParenthese == -1 || firstParenthese < firstPoint) {
-                return noPackage;
-            }
-
-            int current = firstPoint;
-            while (current > 0 && name.charAt(current) != ' ') {
-                current--;
-            }
-
-            String fullClassName = name.substring(current + 1, firstParenthese);
-            int lastPoint = fullClassName.lastIndexOf(".");
-            if (lastPoint == -1) {
-                return noPackage;
-            }
-            lastPoint = fullClassName.lastIndexOf(".", lastPoint - 1);
-            if (lastPoint == -1) {
-                return noPackage;
-            }
-
-            String packageName = fullClassName.substring(0, lastPoint);
-            return packageName;
-        }
-    };
-    private NameProvider classNameProvider = new NameProvider() {
-
-        public String getName(Group g) {
-            String name = g.getName();
-            assert name != null : "name of group must be set!";
-
-            final String noClass = "<noclass>";
-
-            int firstPoint = name.indexOf(".");
-            if (firstPoint == -1) {
-                return noClass;
-            }
-
-            int firstParenthese = name.indexOf("(");
-            if (firstParenthese == -1 || firstParenthese < firstPoint) {
-                return noClass;
-            }
-
-            int current = firstPoint;
-            while (current > 0 && name.charAt(current) != ' ') {
-                current--;
-            }
-
-            String fullClassName = name.substring(current + 1, firstParenthese);
-            int lastPoint = fullClassName.lastIndexOf(".");
-            if (lastPoint == -1) {
-                return noClass;
-            }
-            int lastlastPoint = fullClassName.lastIndexOf(".", lastPoint - 1);
-
-            String className = fullClassName.substring(lastlastPoint + 1, lastPoint);
-            return className;
-        }
-    };
-}
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/ServerCompilerScheduler.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/ServerCompilerScheduler.java	Mon Feb 27 13:10:13 2012 +0100
@@ -29,17 +29,7 @@
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.InputNode;
 import com.sun.hotspot.igv.data.services.Scheduler;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
-import java.util.Vector;
+import java.util.*;
 
 /**
  *
@@ -50,8 +40,8 @@
     private static class Node {
 
         public InputNode inputNode;
-        public Set<Node> succs = new HashSet<Node>();
-        public List<Node> preds = new ArrayList<Node>();
+        public Set<Node> succs = new HashSet<>();
+        public List<Node> preds = new ArrayList<>();
         public InputBlock block;
         public boolean isBlockProjection;
         public boolean isBlockStart;
@@ -65,6 +55,7 @@
     private InputBlock[][] commonDominator;
     private static final Comparator<InputEdge> edgeComparator = new Comparator<InputEdge>() {
 
+        @Override
         public int compare(InputEdge o1, InputEdge o2) {
             return o1.getToIndex() - o2.getToIndex();
         }
@@ -72,13 +63,13 @@
 
     public void buildBlocks() {
 
-        blocks = new Vector<InputBlock>();
+        blocks = new Vector<>();
         Node root = findRoot();
         if (root == null) {
             return;
         }
-        Stack<Node> stack = new Stack<Node>();
-        Set<Node> visited = new HashSet<Node>();
+        Stack<Node> stack = new Stack<>();
+        Set<Node> visited = new HashSet<>();
         stack.add(root);
         int blockCount = 0;
         InputBlock rootBlock = null;
@@ -93,7 +84,7 @@
 
             if (!visited.contains(parent)) {
                 visited.add(parent);
-                InputBlock block = new InputBlock(graph, "" + blockCount);
+                InputBlock block = graph.addBlock(Integer.toString(blockCount));
                 blocks.add(block);
                 if (parent == root) {
                     rootBlock = block;
@@ -111,7 +102,12 @@
                         p = parent;
                         break;
                     }
+
                     p = p.preds.get(0);
+                    if (p == proj) {
+                        // Cycle, stop
+                        break;
+                    }
 
                     if (p.block == null) {
                         p.block = block;
@@ -125,7 +121,7 @@
                                 n = n.preds.get(0);
                             }
                             if (n.block != null) {
-                                n.block.addSuccessor(block);
+                                graph.addBlockEdge(n.block, block);
                             }
                         }
                     }
@@ -136,12 +132,12 @@
                         for (Node n2 : n.succs) {
 
                             if (n2 != parent && n2.block != null && n2.block != rootBlock) {
-                                block.addSuccessor(n2.block);
+                                graph.addBlockEdge(block, n2.block);
                             }
                         }
                     } else {
                         if (n != parent && n.block != null && n.block != rootBlock) {
-                            block.addSuccessor(n.block);
+                            graph.addBlockEdge(block, n.block);
                         }
                     }
                 }
@@ -161,7 +157,7 @@
                 }
 
                 if (pushed == 0 && p == root) {
-                // TODO: special handling when root backedges are not built yet
+                    // TODO: special handling when root backedges are not built yet
                 }
             }
         }
@@ -174,7 +170,7 @@
         }
 
         int z = 0;
-        blockIndex = new HashMap<InputBlock, Integer>();
+        blockIndex = new HashMap<>(blocks.size());
         for (InputBlock b : blocks) {
             blockIndex.put(b, z);
             z++;
@@ -185,20 +181,25 @@
         return n.getProperties().get("block");
     }
 
+    @Override
     public Collection<InputBlock> schedule(InputGraph graph) {
+        if (graph.getNodes().isEmpty()) {
+            return Collections.emptyList();
+        }
+
         if (graph.getBlocks().size() > 0) {
-            Collection<InputNode> tmpNodes = new ArrayList<InputNode>(graph.getNodes());
+            Collection<InputNode> tmpNodes = new ArrayList<>(graph.getNodes());
             for (InputNode n : tmpNodes) {
                 String block = getBlockName(n);
                 if (graph.getBlock(n) == null) {
-                    graph.getBlock(block).addNode(n);
+                    graph.getBlock(block).addNode(n.getId());
                     assert graph.getBlock(n) != null;
                 }
             }
             return graph.getBlocks();
         } else {
-            nodes = new ArrayList<Node>();
-            inputNodeToNode = new HashMap<InputNode, Node>();
+            nodes = new ArrayList<>();
+            inputNodeToNode = new HashMap<>(graph.getNodes().size());
 
             this.graph = graph;
             buildUpGraph();
@@ -207,7 +208,16 @@
             buildCommonDominators();
             scheduleLatest();
 
+            InputBlock noBlock = null;
             for (InputNode n : graph.getNodes()) {
+                if (graph.getBlock(n) == null) {
+                    if (noBlock == null) {
+                        noBlock = graph.addBlock("(no block)");
+                        blocks.add(noBlock);
+                    }
+                    
+                    graph.setBlock(n, noBlock);
+                }
                 assert graph.getBlock(n) != null;
             }
 
@@ -215,15 +225,17 @@
         }
     }
 
-    public void scheduleLatest() {
-
-
+    private void scheduleLatest() {
         Node root = findRoot();
+        if(root == null) {
+            assert false : "No root found!";
+            return;
+        }
 
         // Mark all nodes reachable in backward traversal from root
-        Set<Node> reachable = new HashSet<Node>();
+        Set<Node> reachable = new HashSet<>();
         reachable.add(root);
-        Stack<Node> stack = new Stack<Node>();
+        Stack<Node> stack = new Stack<>();
         stack.push(root);
         while (!stack.isEmpty()) {
             Node cur = stack.pop();
@@ -235,7 +247,7 @@
             }
         }
 
-        Set<Node> unscheduled = new HashSet<Node>();
+        Set<Node> unscheduled = new HashSet<>();
         for (Node n : this.nodes) {
             if (n.block == null && reachable.contains(n)) {
                 unscheduled.add(n);
@@ -245,7 +257,7 @@
         while (unscheduled.size() > 0) {
             boolean progress = false;
 
-            Set<Node> newUnscheduled = new HashSet<Node>();
+            Set<Node> newUnscheduled = new HashSet<>();
             for (Node n : unscheduled) {
 
                 InputBlock block = null;
@@ -285,7 +297,7 @@
             }
         }
 
-        Set<Node> curReachable = new HashSet<Node>(reachable);
+        Set<Node> curReachable = new HashSet<>(reachable);
         for (Node n : curReachable) {
             if (n.block != null) {
                 for (Node s : n.succs) {
@@ -300,7 +312,7 @@
 
     private void markWithBlock(Node n, InputBlock b, Set<Node> reachable) {
         assert !reachable.contains(n);
-        Stack<Node> stack = new Stack<Node>();
+        Stack<Node> stack = new Stack<>();
         stack.push(n);
         n.block = b;
         b.addNode(n.inputNode.getId());
@@ -356,7 +368,7 @@
         if (ba == bb) {
             return ba;
         }
-        Set<InputBlock> visited = new HashSet<InputBlock>();
+        Set<InputBlock> visited = new HashSet<>();
         while (ba != null) {
             visited.add(ba);
             ba = dominatorMap.get(ba);
@@ -374,12 +386,12 @@
     }
 
     public void buildDominators() {
-        dominatorMap = new HashMap<InputBlock, InputBlock>();
+        dominatorMap = new HashMap<>(graph.getBlocks().size());
         if (blocks.size() == 0) {
             return;
         }
-        Vector<BlockIntermediate> intermediate = new Vector<BlockIntermediate>();
-        Map<InputBlock, BlockIntermediate> map = new HashMap<InputBlock, BlockIntermediate>();
+        Vector<BlockIntermediate> intermediate = new Vector<>(graph.getBlocks().size());
+        Map<InputBlock, BlockIntermediate> map = new HashMap<>(graph.getBlocks().size());
         int z = 0;
         for (InputBlock b : blocks) {
             BlockIntermediate bi = new BlockIntermediate();
@@ -390,16 +402,16 @@
             bi.parent = -1;
             bi.label = z;
             bi.ancestor = -1;
-            bi.pred = new ArrayList<Integer>();
-            bi.bucket = new ArrayList<Integer>();
+            bi.pred = new ArrayList<>();
+            bi.bucket = new ArrayList<>();
             intermediate.add(bi);
             map.put(b, bi);
             z++;
         }
-        Stack<Integer> stack = new Stack<Integer>();
+        Stack<Integer> stack = new Stack<>();
         stack.add(0);
 
-        Vector<BlockIntermediate> array = new Vector<BlockIntermediate>();
+        Vector<BlockIntermediate> array = new Vector<>();
         intermediate.get(0).dominator = 0;
 
         int n = 0;
@@ -538,15 +550,30 @@
     }
 
     private Node findRoot() {
+        Node minNode = null;
+        Node alternativeRoot = null;
 
-        for (Node n : nodes) {
-            InputNode inputNode = n.inputNode;
-            if (inputNode.getProperties().get("name").equals("Root")) {
-                return n;
+        for (Node node : nodes) {
+            InputNode inputNode = node.inputNode;
+            String s = inputNode.getProperties().get("name");
+            if (s != null && s.equals("Root")) {
+                return node;
+            }
+
+            if (alternativeRoot == null && node.preds.isEmpty()) {
+                alternativeRoot = node;
+            }
+
+            if (minNode == null || node.inputNode.getId() < minNode.inputNode.getId()) {
+                minNode = node;
             }
         }
 
-        return null;
+        if (alternativeRoot != null) {
+            return alternativeRoot;
+        } else {
+            return minNode;
+        }
     }
 
     public void buildUpGraph() {
@@ -562,7 +589,7 @@
             inputNodeToNode.put(n, node);
         }
 
-        Map<Integer, List<InputEdge>> edgeMap = new HashMap<Integer, List<InputEdge>>();
+        Map<Integer, List<InputEdge>> edgeMap = new HashMap<>(graph.getEdges().size());
         for (InputEdge e : graph.getEdges()) {
 
             int to = e.getTo();
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/color.filter	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/color.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -1,5 +1,18 @@
 colorize("name", ".*", yellow);
 colorize("name", "Catch.*", blue);
-
 colorize("name", "Region|Loop|CountedLoop|Root", red);
 colorize("name", "CProj|IfFalse|IfTrue|JProj|CatchProj", magenta);
+colorize("name", "Con.*", orange);
+colorize("name", "Parm|Proj", lightGray);
+
+// Nodes with bci
+colorize("bci", "..*", magenta);
+
+// Line style
+var f = new ColorFilter("Line Style filter");
+f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "int:")), null, Color.BLUE, null));
+f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "control")), null, Color.RED, null));
+f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "memory")), null, Color.GREEN, null));
+f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "tuple:")), null, Color.MAGENTA, null));
+f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "bottom")), null, Color.LIGHT_GRAY, null));
+f.apply(graph);
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/combine.filter	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-var f = new CombineFilter("Combine Filter");
-f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("name", ".*"), new Properties.RegexpPropertyMatcher("name", "Proj|IfFalse|IfTrue|JProj|MachProj|JumpProj|CatchProj")));
-f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("name", "Cmp.*"), new Properties.RegexpPropertyMatcher("name", "Bool")));
-f.apply(graph);
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/extendedColor.filter	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-colorize("name", "Con.*", orange);
-colorize("name", "Parm|Proj", lightGray);
-colorize("bci", "..*", magenta);
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/linestyle.filter	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-var f = new ColorFilter("Line Style filter");
-f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "int:")), null, Color.BLUE, null));
-f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "control")), null, Color.RED, null));
-f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "memory")), null, Color.GREEN, null));
-f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "tuple:")), null, Color.MAGENTA, null));
-f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "bottom")), null, Color.LIGHT_GRAY, null));
-f.apply(graph);
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/onlyControlFlow.filter	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/onlyControlFlow.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -20,5 +20,5 @@
     ), false
   )
 );
-f.addRule( new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher("name", "Phi|Store.")), false));
+f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher("name", "Phi|Store."))));
 f.apply(graph);
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/register.filter	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/register.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -1,4 +1,5 @@
+// Register coloring
 colorize("reg", "EAX", green);
 colorize("reg", "EFLAGS", gray);
 colorize("reg", "EBP", orange);
-colorize("reg", "ECX", cyan);
+colorize("reg", "ECX", cyan);
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/remove.filter	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/remove.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -1,1 +1,8 @@
-remove("dump_spec", "FramePtr|ReturnAdr|I_O"); 
\ No newline at end of file
+remove("dump_spec", "FramePtr|ReturnAdr|I_O"); 
+removeInputs("name", "Root");
+var f = new RemoveSelfLoopsFilter("Remove Self-Loops");
+f.apply(graph);
+removeInputs("name", "SafePoint|CallStaticJava|CallDynamicJava|CallJava|CallLeaf|CallRuntime|AbstractLock|CallLeafNoFP|Call|CallStaticJavaDirect", 5);
+removeInputs("name", "Unlock|Lock", 7);
+removeInputs("name", "Allocate", 7);
+removeInputs("name", "AllocateArray", 9);
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeMemory.filter	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-
-//var f = new RemoveFilter("Remove Memory");
-//f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.StringPropertyMatcher("dump_spec", "Memory")), false));
-//f.addRule(new RemoveFilter.RemoveRule(new AndSelector(new MatcherSelector(new Properties.StringPropertyMatcher("name", "Proj")), new MatcherSelector(new Properties.StringPropertyMatcher("type", "memory"))), false));
-//f.apply(graph);
-
-remove("dump_spec", "Memory");
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeRootInputs.filter	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-removeInputs("name", "Root");
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeSafepointInputs.filter	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-removeInputs("name", "SafePoint|CallStaticJava|CallDynamicJava|CallJava|CallLeaf|CallRuntime|AbstractLock|CallLeafNoFP|Call|CallStaticJavaDirect", 5);
-removeInputs("name", "Unlock|Lock", 7);
-removeInputs("name", "Allocate", 7);
-removeInputs("name", "AllocateArray", 9);
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeSelfLoops.filter	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-var f = new RemoveSelfLoopsFilter("Remove Self-Loops");
-f.apply(graph);
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/split.filter	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-split("name", "BoxLock");
-split("name", "(Con.*)|(loadCon.*)");
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/structural.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,6 @@
+var f = new CombineFilter("Combine Filter");
+f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("name", ".*"), new Properties.RegexpPropertyMatcher("name", "Proj|IfFalse|IfTrue|JProj|MachProj|JumpProj|CatchProj")));
+f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("name", "Cmp.*"), new Properties.RegexpPropertyMatcher("name", "Bool")));
+f.apply(graph);
+split("name", "BoxLock");
+split("name", "(Con.*)|(loadCon.*)", "[dump_spec]");
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/layer.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/layer.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -2,60 +2,28 @@
 <!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
 <filesystem>
       <folder name="Filters">
-        <file name="Basic Coloring" url="filters/color.filter">
-            <attr name="enabled" boolvalue="true"/>
-        </file>
-        <file name="Matcher Flags Coloring" url="filters/matchingFlags.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Basic Coloring"/>
-        </file>
-        <file name="Register Coloring" url="filters/register.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Matcher Flags Coloring"/>
+        <file name="C2 Basic Coloring" url="filters/color.filter">
+            <attr name="enabled" boolvalue="false"/>
         </file>
-        <file name="Extended Coloring" url="filters/extendedColor.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Register Coloring"/>
-        </file>
-        <file name="Line Coloring" url="filters/linestyle.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Extended Coloring"/>
+        <file name="C2 Matcher Flags Coloring" url="filters/matchingFlags.filter">
+            <attr name="enabled" boolvalue="false"/>
+            <attr name="after" stringvalue="C2 Basic Coloring"/>
         </file>
-        <file name="Difference Coloring" url="filters/difference.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Line Coloring"/>
-        </file>
-        <file name="Only Control Flow" url="filters/onlyControlFlow.filter">
+        <file name="C2 Register Coloring" url="filters/register.filter">
             <attr name="enabled" boolvalue="false"/>
-            <attr name="after" stringvalue="Difference Coloring"/>
+            <attr name="after" stringvalue="C2 Matcher Flags Coloring"/>
         </file>
-        <file name="Remove FramePtr, I_O and Return Address" url="filters/remove.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Only Control Flow"/>
-        </file>
-        <file name="Remove Memory" url="filters/removeMemory.filter">
+        <file name="C2 Only Control Flow" url="filters/onlyControlFlow.filter">
             <attr name="enabled" boolvalue="false"/>
-            <attr name="after" stringvalue="Remove FramePtr, I_O and Return Address"/>
-        </file>
-        <file name="Remove Root Inputs" url="filters/removeRootInputs.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Remove Memory"/>
+            <attr name="after" stringvalue="C2 Register Coloring"/>
         </file>
-        <file name="Remove Safepoint Inputs" url="filters/removeSafepointInputs.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Remove Root Inputs"/>
-        </file>
-        <file name="Remove Self Loops" url="filters/removeSelfLoops.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Remove Safepoint Inputs"/>
+        <file name="C2 Remove Filter" url="filters/remove.filter">
+            <attr name="enabled" boolvalue="false"/>
+            <attr name="after" stringvalue="C2 Only Control Flow"/>
         </file>
-        <file name="Combine" url="filters/combine.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Remove Self Loops"/>
+        <file name="C2 Structural" url="filters/structural.filter">
+            <attr name="enabled" boolvalue="false"/>
+            <attr name="after" stringvalue="C2 Remove Filter"/>
         </file>
-        <file name="Split" url="filters/split.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Combine"/>
-        </file>
-    </folder>
+    </folder>	
 </filesystem>
--- a/src/share/tools/IdealGraphVisualizer/Settings/nbproject/project.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Settings/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/Settings/nbproject/project.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Settings/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -12,7 +12,7 @@
                     <compile-dependency/>
                     <run-dependency>
                         <release-version>1</release-version>
-                        <specification-version>1.4</specification-version>
+                        <specification-version>1.16.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -21,7 +21,7 @@
                     <compile-dependency/>
                     <run-dependency>
                         <release-version>1</release-version>
-                        <specification-version>1.5</specification-version>
+                        <specification-version>1.21.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -29,7 +29,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.11.0.1</specification-version>
+                        <specification-version>7.30.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -37,7 +37,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.9.0.1</specification-version>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
                     </run-dependency>
                 </dependency>
             </module-dependencies>
--- a/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/ViewOptionsCategory.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/ViewOptionsCategory.java	Mon Feb 27 13:10:13 2012 +0100
@@ -27,8 +27,8 @@
 import javax.swing.ImageIcon;
 import org.netbeans.spi.options.OptionsCategory;
 import org.netbeans.spi.options.OptionsPanelController;
+import org.openide.util.ImageUtilities;
 import org.openide.util.NbBundle;
-import org.openide.util.Utilities;
 
 /**
  *
@@ -38,17 +38,20 @@
 
     @Override
     public Icon getIcon() {
-        return new ImageIcon(Utilities.loadImage("com/sun/hotspot/igv/settings/settings.gif"));
+        return new ImageIcon(ImageUtilities.loadImage("com/sun/hotspot/igv/settings/settings.png"));
     }
 
+    @Override
     public String getCategoryName() {
         return NbBundle.getMessage(ViewOptionsCategory.class, "OptionsCategory_Name_View");
     }
 
+    @Override
     public String getTitle() {
         return NbBundle.getMessage(ViewOptionsCategory.class, "OptionsCategory_Title_View");
     }
 
+    @Override
     public OptionsPanelController create() {
         return new ViewOptionsPanelController();
     }
--- a/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/ViewOptionsPanelController.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/ViewOptionsPanelController.java	Mon Feb 27 13:10:13 2012 +0100
@@ -40,40 +40,49 @@
     private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
     private boolean changed;
 
+    @Override
     public void update() {
         getPanel().load();
         changed = false;
     }
 
+    @Override
     public void applyChanges() {
         getPanel().store();
         changed = false;
     }
 
+    @Override
     public void cancel() {
     // need not do anything special, if no changes have been persisted yet
     }
 
+    @Override
     public boolean isValid() {
         return getPanel().valid();
     }
 
+    @Override
     public boolean isChanged() {
         return changed;
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return null; // new HelpCtx("...ID") if you have a help set
     }
 
+    @Override
     public JComponent getComponent(Lookup masterLookup) {
         return getPanel();
     }
 
+    @Override
     public void addPropertyChangeListener(PropertyChangeListener l) {
         pcs.addPropertyChangeListener(l);
     }
 
+    @Override
     public void removePropertyChangeListener(PropertyChangeListener l) {
         pcs.removePropertyChangeListener(l);
     }
--- a/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/layer.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/layer.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -2,8 +2,10 @@
 <!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
 <filesystem>
     <folder name="OptionsDialog">
-        <file name="Advanced.instance_hidden"/>
-        <file name="General.instance_hidden"/>
-        <file name="com-sun-hotspot-igv-settings-ViewOptionsCategory.instance"/>
+      <!-- <file name="Advanced.instance_hidden"/>
+        <file name="General.instance_hidden"/>-->
+        <file name="com-sun-hotspot-igv-settings-ViewOptionsCategory.instance">
+            <attr name="position" intvalue="100" />
+        </file>
     </folder>
 </filesystem>
Binary file src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/settings.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/settings.png has changed
--- a/src/share/tools/IdealGraphVisualizer/Util/nbproject/project.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Util/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/Util/nbproject/project.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Util/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -19,7 +19,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>2.9</specification-version>
+                        <specification-version>2.27.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -27,7 +27,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.2.1.1</specification-version>
+                        <specification-version>7.20.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -35,7 +35,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.10.1.1</specification-version>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
                     </run-dependency>
                 </dependency>
             </module-dependencies>
--- a/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ColorIcon.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ColorIcon.java	Mon Feb 27 13:10:13 2012 +0100
@@ -40,15 +40,18 @@
         color = c;
     }
 
+    @Override
     public void paintIcon(Component c, Graphics g, int x, int y) {
         g.setColor(color);
         g.fillRect(x, y, 16, 16);
     }
 
+    @Override
     public int getIconWidth() {
         return 16;
     }
 
+    @Override
     public int getIconHeight() {
         return 16;
     }
--- a/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ContextAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ContextAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -25,11 +25,7 @@
 package com.sun.hotspot.igv.util;
 
 import java.awt.EventQueue;
-import org.openide.util.ContextAwareAction;
-import org.openide.util.Lookup;
-import org.openide.util.LookupEvent;
-import org.openide.util.LookupListener;
-import org.openide.util.Utilities;
+import org.openide.util.*;
 import org.openide.util.actions.CallableSystemAction;
 
 /**
@@ -56,6 +52,7 @@
         resultChanged(null);
     }
 
+    @Override
     public void resultChanged(LookupEvent e) {
         if (result.allItems().size() != 0) {
             update(result.allInstances().iterator().next());
@@ -71,6 +68,7 @@
         // Ensure it's AWT event thread
         EventQueue.invokeLater(new Runnable() {
 
+            @Override
             public void run() {
                 performAction(t);
             }
--- a/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ExtendedSatelliteComponent.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ExtendedSatelliteComponent.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,11 +23,10 @@
  */
 package com.sun.hotspot.igv.util;
 
-import org.netbeans.api.visual.widget.Scene;
-
-import javax.swing.*;
 import java.awt.*;
 import java.awt.event.*;
+import javax.swing.JComponent;
+import org.netbeans.api.visual.widget.Scene;
 
 /**
  * @author David Kaspar
@@ -118,27 +117,34 @@
         }
     }
 
+    @Override
     public void mouseClicked(MouseEvent e) {
     }
 
+    @Override
     public void mousePressed(MouseEvent e) {
         moveVisibleRect(e.getPoint());
     }
 
+    @Override
     public void mouseReleased(MouseEvent e) {
         moveVisibleRect(e.getPoint());
     }
 
+    @Override
     public void mouseEntered(MouseEvent e) {
     }
 
+    @Override
     public void mouseExited(MouseEvent e) {
     }
 
+    @Override
     public void mouseDragged(MouseEvent e) {
         moveVisibleRect(e.getPoint());
     }
 
+    @Override
     public void mouseMoved(MouseEvent e) {
     }
 
@@ -170,26 +176,33 @@
 
     }
 
+    @Override
     public void sceneRepaint() {
     }
 
+    @Override
     public void sceneValidating() {
     }
 
+    @Override
     public void sceneValidated() {
     }
 
+    @Override
     public void componentResized(ComponentEvent e) {
         repaint();
     }
 
+    @Override
     public void componentMoved(ComponentEvent e) {
         repaint();
     }
 
+    @Override
     public void componentShown(ComponentEvent e) {
     }
 
+    @Override
     public void componentHidden(ComponentEvent e) {
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/LookupHistory.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * 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.sun.hotspot.igv.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.openide.util.Lookup.Result;
+import org.openide.util.LookupEvent;
+import org.openide.util.LookupListener;
+import org.openide.util.Utilities;
+
+/**
+ *
+ * @author Thomas
+ */
+public class LookupHistory {
+
+    private static Map<Class, LookupHistoryImpl> cache = new HashMap<>();
+
+    private static class LookupHistoryImpl<T> implements LookupListener {
+
+        private Class<T> klass;
+        private Result<T> result;
+        private T last;
+
+        public LookupHistoryImpl(Class<T> klass) {
+            this.klass = klass;
+            result = Utilities.actionsGlobalContext().lookupResult(klass);
+            result.addLookupListener(this);
+            last = Utilities.actionsGlobalContext().lookup(klass);
+        }
+
+        public T getLast() {
+            return last;
+        }
+
+        @Override
+        public void resultChanged(LookupEvent ev) {
+            T current = Utilities.actionsGlobalContext().lookup(klass);
+            if (current != null) {
+                last = current;
+            }
+        }
+    }
+
+    public static <T> void init(Class<T> klass) {
+        if (!cache.containsKey(klass)) {
+            cache.put(klass, new LookupHistoryImpl<>(klass));
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> T getLast(Class<T> klass) {
+        init(klass);
+        assert cache.containsKey(klass);
+        return (T) cache.get(klass).getLast();
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSlider.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSlider.java	Mon Feb 27 13:10:13 2012 +0100
@@ -25,15 +25,7 @@
 package com.sun.hotspot.igv.util;
 
 import com.sun.hotspot.igv.data.ChangedListener;
-import java.awt.Color;
-import java.awt.Cursor;
-import java.awt.Dimension;
-import java.awt.FontMetrics;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
+import java.awt.*;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
 import java.awt.event.MouseMotionListener;
@@ -105,6 +97,7 @@
         return d;
     }
 
+    @Override
     public void changed(RangeSliderModel source) {
         update();
     }
@@ -240,6 +233,7 @@
         return false;
     }
 
+    @Override
     public void mouseDragged(MouseEvent e) {
         if (state == State.DragBar) {
             int firstX = this.getStartXPosition(model.getFirstPosition());
@@ -294,6 +288,7 @@
         return result;
     }
 
+    @Override
     public void mouseMoved(MouseEvent e) {
         isOverBar = false;
         if (model == null) {
@@ -313,6 +308,7 @@
         repaint();
     }
 
+    @Override
     public void mouseClicked(MouseEvent e) {
         if (e.getClickCount() > 1) {
             // Double click
@@ -321,6 +317,7 @@
         }
     }
 
+    @Override
     public void mousePressed(MouseEvent e) {
         if (model == null) {
             return;
@@ -341,6 +338,7 @@
         tempModel = model.copy();
     }
 
+    @Override
     public void mouseReleased(MouseEvent e) {
         if (model == null || tempModel == null) {
             return;
@@ -350,9 +348,11 @@
         tempModel = null;
     }
 
+    @Override
     public void mouseEntered(MouseEvent e) {
     }
 
+    @Override
     public void mouseExited(MouseEvent e) {
         isOverBar = false;
         repaint();
--- a/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSliderModel.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSliderModel.java	Mon Feb 27 13:10:13 2012 +0100
@@ -24,8 +24,8 @@
  */
 package com.sun.hotspot.igv.util;
 
+import com.sun.hotspot.igv.data.ChangedEvent;
 import com.sun.hotspot.igv.data.ChangedEventProvider;
-import com.sun.hotspot.igv.data.ChangedEvent;
 import java.awt.Color;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -65,17 +65,19 @@
 
     public RangeSliderModel(List<String> positions) {
         assert positions.size() > 0;
-        this.changedEvent = new ChangedEvent<RangeSliderModel>(this);
-        this.colorChangedEvent = new ChangedEvent<RangeSliderModel>(this);
+        this.changedEvent = new ChangedEvent<>(this);
+        this.colorChangedEvent = new ChangedEvent<>(this);
         setPositions(positions);
     }
 
     protected void setPositions(List<String> positions) {
         this.positions = positions;
-        colors = new ArrayList<Color>();
+        colors = new ArrayList<>();
         for (int i = 0; i < positions.size(); i++) {
             colors.add(Color.black);
         }
+        firstPosition = Math.min(firstPosition, positions.size() - 1);
+        secondPosition = Math.min(secondPosition, positions.size() - 1);
         changedEvent.fire();
         colorChangedEvent.fire();
     }
@@ -91,9 +93,7 @@
 
     public RangeSliderModel copy() {
         RangeSliderModel newModel = new RangeSliderModel(positions);
-        newModel.firstPosition = firstPosition;
-        newModel.secondPosition = secondPosition;
-        newModel.colors = colors;
+        newModel.setData(this);
         return newModel;
     }
 
@@ -130,6 +130,7 @@
         return colorChangedEvent;
     }
 
+    @Override
     public ChangedEvent<RangeSliderModel> getChangedEvent() {
         return changedEvent;
     }
--- a/src/share/tools/IdealGraphVisualizer/View/nbproject/project.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/View/nbproject/project.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -55,6 +55,14 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
+                    <code-name-base>com.sun.hotspot.igv.selectioncoordinator</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
                     <code-name-base>com.sun.hotspot.igv.settings</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
@@ -83,7 +91,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>2.9</specification-version>
+                        <specification-version>2.27.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.spi.quicksearch</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -91,7 +107,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.6.0.1</specification-version>
+                        <specification-version>6.21.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -99,7 +115,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.11.0.1</specification-version>
+                        <specification-version>7.30.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -107,7 +123,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.5.1</specification-version>
+                        <specification-version>7.18.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -115,7 +131,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.7</specification-version>
+                        <specification-version>7.20.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -123,7 +139,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.2.1.1</specification-version>
+                        <specification-version>7.20.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -131,7 +147,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.9.0.1</specification-version>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -139,7 +163,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.16</specification-version>
+                        <specification-version>6.39.1</specification-version>
                     </run-dependency>
                 </dependency>
             </module-dependencies>
--- a/src/share/tools/IdealGraphVisualizer/View/src/META-INF/services/com.sun.hotspot.igv.data.services.InputGraphProvider	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-com.sun.hotspot.igv.view.EditorInputGraphProvider
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/Bundle.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,3 +1,3 @@
-HINT_EditorTopComponent=This is a Editor window
-OpenIDE-Module-Name=View
-CTL_EditorTopComponent=Editor Window
+HINT_EditorTopComponent=Visualizes a graph.
+OpenIDE-Module-Name=View
+CTL_EditorTopComponent=Graph
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ConnectionAnchor.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.view;
-
-import com.sun.hotspot.igv.view.widgets.SlotWidget;
-import java.awt.Point;
-import java.awt.Rectangle;
-import org.netbeans.api.visual.anchor.Anchor;
-import org.netbeans.api.visual.anchor.Anchor.Entry;
-import org.netbeans.api.visual.anchor.Anchor.Result;
-import org.netbeans.api.visual.widget.Widget;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class ConnectionAnchor extends Anchor {
-
-    public enum HorizontalAlignment {
-
-        Left,
-        Center,
-        Right
-    }
-    private HorizontalAlignment alignment;
-
-    public ConnectionAnchor(Widget widget) {
-        this(HorizontalAlignment.Center, widget);
-    }
-
-    public ConnectionAnchor(HorizontalAlignment alignment, Widget widget) {
-        super(widget);
-        this.alignment = alignment;
-    }
-
-    public Result compute(Entry entry) {
-        return new Result(getRelatedSceneLocation(), Anchor.DIRECTION_ANY);
-    }
-
-    @Override
-    public Point getRelatedSceneLocation() {
-        Point p = null;
-        Widget w = getRelatedWidget();
-        if (w != null) {
-            if (w instanceof SlotWidget) {
-                p = ((SlotWidget) w).getAnchorPosition();
-            } else {
-                Rectangle r = w.convertLocalToScene(w.getBounds());
-                int y = r.y + r.height / 2;
-                int x = r.x;
-                if (alignment == HorizontalAlignment.Center) {
-                    x = r.x + r.width / 2;
-                } else if (alignment == HorizontalAlignment.Right) {
-                    x = r.x + r.width;
-                }
-
-                p = new Point(x, y);
-            }
-        }
-
-        return p;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramScene.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramScene.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,77 +23,38 @@
  */
 package com.sun.hotspot.igv.view;
 
-import com.sun.hotspot.igv.view.widgets.BlockWidget;
-import com.sun.hotspot.igv.view.widgets.LineWidget;
-import com.sun.hotspot.igv.util.DoubleClickAction;
-import com.sun.hotspot.igv.data.InputBlock;
-import com.sun.hotspot.igv.data.InputNode;
-import com.sun.hotspot.igv.graph.Connection;
-import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.InputSlot;
-import com.sun.hotspot.igv.graph.OutputSlot;
-import com.sun.hotspot.igv.graph.Slot;
-import com.sun.hotspot.igv.hierarchicallayout.HierarchicalClusterLayoutManager;
-import com.sun.hotspot.igv.hierarchicallayout.OldHierarchicalLayoutManager;
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.data.ControllableChangedListener;
+import com.sun.hotspot.igv.data.Pair;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.graph.*;
 import com.sun.hotspot.igv.hierarchicallayout.HierarchicalLayoutManager;
-import com.sun.hotspot.igv.view.widgets.FigureWidget;
-import com.sun.hotspot.igv.view.widgets.InputSlotWidget;
-import com.sun.hotspot.igv.view.widgets.OutputSlotWidget;
-import com.sun.hotspot.igv.view.widgets.SlotWidget;
 import com.sun.hotspot.igv.layout.LayoutGraph;
-import com.sun.hotspot.igv.data.services.Scheduler;
-import com.sun.hotspot.igv.data.ChangedListener;
-import com.sun.hotspot.igv.graph.Block;
+import com.sun.hotspot.igv.selectioncoordinator.SelectionCoordinator;
 import com.sun.hotspot.igv.util.ColorIcon;
-import com.sun.hotspot.igv.util.ExtendedSelectAction;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.event.ActionEvent;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.awt.event.MouseMotionListener;
-import java.awt.event.MouseWheelEvent;
-import java.awt.event.MouseWheelListener;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.HashMap;
+import com.sun.hotspot.igv.util.DoubleClickAction;
+import com.sun.hotspot.igv.util.PropertiesSheet;
+import com.sun.hotspot.igv.view.actions.CustomizablePanAction;
+import com.sun.hotspot.igv.view.widgets.*;
+import java.awt.*;
+import java.awt.event.*;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.swing.AbstractAction;
-import javax.swing.Action;
-import javax.swing.BorderFactory;
-import javax.swing.JComponent;
-import javax.swing.JPopupMenu;
-import javax.swing.JScrollPane;
-import javax.swing.SwingUtilities;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
+import java.util.*;
+import javax.swing.*;
 import javax.swing.event.UndoableEditEvent;
 import javax.swing.undo.AbstractUndoableEdit;
 import javax.swing.undo.CannotRedoException;
 import javax.swing.undo.CannotUndoException;
-import org.netbeans.api.visual.action.ActionFactory;
-import org.netbeans.api.visual.action.PopupMenuProvider;
-import org.netbeans.api.visual.action.RectangularSelectDecorator;
-import org.netbeans.api.visual.action.RectangularSelectProvider;
-import org.netbeans.api.visual.action.SelectProvider;
-import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.action.*;
 import org.netbeans.api.visual.animator.SceneAnimator;
 import org.netbeans.api.visual.layout.LayoutFactory;
-import org.netbeans.api.visual.widget.ConnectionWidget;
+import org.netbeans.api.visual.model.*;
 import org.netbeans.api.visual.widget.LayerWidget;
-import org.netbeans.api.visual.widget.Scene;
 import org.netbeans.api.visual.widget.Widget;
-import org.netbeans.api.visual.widget.LabelWidget;
 import org.openide.awt.UndoRedo;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Sheet;
 import org.openide.util.Lookup;
 import org.openide.util.lookup.AbstractLookup;
 import org.openide.util.lookup.InstanceContent;
@@ -102,15 +63,11 @@
  *
  * @author Thomas Wuerthinger
  */
-public class DiagramScene extends Scene implements ChangedListener<DiagramViewModel> {
+public class DiagramScene extends ObjectScene implements DiagramViewer {
 
-    private HashMap<Figure, FigureWidget> figureWidgets;
-    private HashMap<Slot, SlotWidget> slotWidgets;
-    private HashMap<Connection, ConnectionWidget> connectionWidgets;
-    private HashMap<InputBlock, BlockWidget> blockWidgets;
-    private Widget hoverWidget;
+    private CustomizablePanAction panAction;
     private WidgetAction hoverAction;
-    private List<FigureWidget> selectedWidgets;
+    private WidgetAction selectAction;
     private Lookup lookup;
     private InstanceContent content;
     private Action[] actions;
@@ -118,22 +75,25 @@
     private JScrollPane scrollPane;
     private UndoRedo.Manager undoRedoManager;
     private LayerWidget mainLayer;
-    private LayerWidget slotLayer;
     private LayerWidget blockLayer;
-    private double realZoomFactor;
-    private BoundedZoomAction zoomAction;
-    private WidgetAction panAction;
     private Widget topLeft;
     private Widget bottomRight;
-    private LayerWidget startLayer;
-    private LabelWidget startLabel;
     private DiagramViewModel model;
     private DiagramViewModel modelCopy;
-    public static final int AFTER = 1;
-    public static final int BEFORE = 1;
+    private WidgetAction zoomAction;
+    private boolean rebuilding;
+    
+    /**
+     * The alpha level of partially visible figures.
+     */
     public static final float ALPHA = 0.4f;
-    public static final int GRID_SIZE = 30;
+    
+    /**
+     * The offset of the graph to the border of the window showing it.
+     */
     public static final int BORDER_SIZE = 20;
+    
+    
     public static final int UNDOREDO_LIMIT = 100;
     public static final int SCROLL_UNIT_INCREMENT = 80;
     public static final int SCROLL_BLOCK_INCREMENT = 400;
@@ -142,14 +102,17 @@
     public static final float ZOOM_INCREMENT = 1.5f;
     public static final int SLOT_OFFSET = 6;
     public static final int ANIMATION_LIMIT = 40;
+    
     private PopupMenuProvider popupMenuProvider = new PopupMenuProvider() {
 
+        @Override
         public JPopupMenu getPopupMenu(Widget widget, Point localLocation) {
             return DiagramScene.this.createPopupMenu();
         }
     };
     private RectangularSelectDecorator rectangularSelectDecorator = new RectangularSelectDecorator() {
 
+        @Override
         public Widget createSelectionWidget() {
             Widget widget = new Widget(DiagramScene.this);
             widget.setBorder(BorderFactory.createLineBorder(Color.black, 2));
@@ -157,8 +120,98 @@
             return widget;
         }
     };
+
+    @SuppressWarnings("unchecked")
+    public <T> T getWidget(Object o) {
+        Widget w = this.findWidget(o);
+        return (T) w;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T getWidget(Object o, Class<T> klass) {
+        Widget w = this.findWidget(o);
+        return (T) w;
+    }
+
+    private static boolean intersects(Set<? extends Object> s1, Set<? extends Object> s2) {
+        for (Object o : s1) {
+            if (s2.contains(o)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void zoomOut() {
+        double zoom = getZoomFactor();
+        Point viewPosition = getScrollPane().getViewport().getViewPosition();
+        double newZoom = zoom / DiagramScene.ZOOM_INCREMENT;
+        if (newZoom > DiagramScene.ZOOM_MIN_FACTOR) {
+            setZoomFactor(newZoom);
+            validate();
+            getScrollPane().getViewport().setViewPosition(new Point((int) (viewPosition.x / DiagramScene.ZOOM_INCREMENT), (int) (viewPosition.y / DiagramScene.ZOOM_INCREMENT)));
+        }
+    }
+
+    @Override
+    public void zoomIn() {
+
+        double zoom = getZoomFactor();
+        Point viewPosition = getScrollPane().getViewport().getViewPosition();
+        double newZoom = zoom * DiagramScene.ZOOM_INCREMENT;
+        if (newZoom < DiagramScene.ZOOM_MAX_FACTOR) {
+            setZoomFactor(newZoom);
+            validate();
+            getScrollPane().getViewport().setViewPosition(new Point((int) (viewPosition.x * DiagramScene.ZOOM_INCREMENT), (int) (viewPosition.y * DiagramScene.ZOOM_INCREMENT)));
+        }
+    }
+
+
+    @Override
+    public void centerFigures(List<Figure> list) {
+
+        boolean b = getUndoRedoEnabled();
+        setUndoRedoEnabled(false);
+        gotoFigures(list);
+        setUndoRedoEnabled(b);
+    }
+
+    private Set<Object> getObjectsFromIdSet(Set<Object> set) {
+        Set<Object> selectedObjects = new HashSet<>();
+        for (Figure f : getModel().getDiagramToView().getFigures()) {
+            if (intersects(f.getSource().getSourceNodesAsSet(), set)) {
+                selectedObjects.add(f);
+            }
+
+            for (Slot s : f.getSlots()) {
+                if (intersects(s.getSource().getSourceNodesAsSet(), set)) {
+                    selectedObjects.add(s);
+                }
+            }
+        }
+        return selectedObjects;
+    }
+    private ControllableChangedListener<SelectionCoordinator> highlightedCoordinatorListener = new ControllableChangedListener<SelectionCoordinator>() {
+
+        @Override
+        public void filteredChanged(SelectionCoordinator source) {
+            DiagramScene.this.setHighlightedObjects(getObjectsFromIdSet(source.getHighlightedObjects()));
+            DiagramScene.this.validate();
+        }
+    };
+    private ControllableChangedListener<SelectionCoordinator> selectedCoordinatorListener = new ControllableChangedListener<SelectionCoordinator>() {
+
+        @Override
+        public void filteredChanged(SelectionCoordinator source) {
+            DiagramScene.this.gotoSelection(source.getSelectedObjects());
+            DiagramScene.this.validate();
+        }
+    };
+
     private RectangularSelectProvider rectangularSelectProvider = new RectangularSelectProvider() {
 
+        @Override
         public void performSelection(Rectangle rectangle) {
             if (rectangle.width < 0) {
                 rectangle.x += rectangle.width;
@@ -170,168 +223,44 @@
                 rectangle.height *= -1;
             }
 
-            boolean updated = false;
+            Set<Object> selectedObjects = new HashSet<>();
             for (Figure f : getModel().getDiagramToView().getFigures()) {
-                FigureWidget w = figureWidgets.get(f);
-                Rectangle r = new Rectangle(w.getBounds());
-                r.setLocation(w.getLocation());
-                if (r.intersects(rectangle)) {
-                    if (!selectedWidgets.contains(w)) {
-                        addToSelection(w);
-                        updated = true;
+                FigureWidget w = getWidget(f);
+                if (w != null) {
+                    Rectangle r = new Rectangle(w.getBounds());
+                    r.setLocation(w.getLocation());
+
+                    if (r.intersects(rectangle)) {
+                        selectedObjects.add(f);
+                    }
+
+                    for (Slot s : f.getSlots()) {
+                        SlotWidget sw = getWidget(s);
+                        Rectangle r2 = new Rectangle(sw.getBounds());
+                        r2.setLocation(sw.convertLocalToScene(new Point(0, 0)));
+
+                        if (r2.intersects(rectangle)) {
+                            selectedObjects.add(s);
+                        }
                     }
                 } else {
-                    if (selectedWidgets.contains(w)) {
-                        selectedWidgets.remove(w);
-                        content.remove(w.getNode());
-                        w.setState(w.getState().deriveSelected(false));
-                        updated = true;
-                    }
-                }
-            }
-
-            if (updated) {
-                selectionUpdated();
-            }
-        }
-    };
-    private SelectProvider selectProvider = new SelectProvider() {
-
-        public boolean isAimingAllowed(Widget widget, Point point, boolean b) {
-            return false;
-        }
-
-        public boolean isSelectionAllowed(Widget widget, Point point, boolean b) {
-            return widget instanceof FigureWidget || widget == DiagramScene.this;
-        }
-
-        public void select(Widget w, Point point, boolean change) {
-
-            boolean updated = false;
-
-            if (w == DiagramScene.this) {
-                if (DiagramScene.this.selectedWidgets.size() != 0) {
-                    clearSelection();
-                    selectionUpdated();
-                }
-                return;
-            }
-
-            FigureWidget widget = (FigureWidget) w;
-
-
-            if (change) {
-                if (widget.getState().isSelected()) {
-                    assert selectedWidgets.contains(widget);
-                    widget.setState(widget.getState().deriveSelected(false));
-                    selectedWidgets.remove(widget);
-                    content.remove(widget.getNode());
-                    updated = true;
-                } else {
-                    assert !selectedWidgets.contains(widget);
-                    addToSelection(widget);
-                    updated = true;
-                    assert widget.getState().isSelected();
-                }
-            } else {
-
-                if (widget.getState().isSelected()) {
-                    assert selectedWidgets.contains(widget);
-                } else {
-
-                    assert !selectedWidgets.contains(widget);
-                    clearSelection();
-                    addToSelection(widget);
-                    updated = true;
-                    assert widget.getState().isSelected();
+                    assert false : "w should not be null here!";
                 }
             }
 
-            if (updated) {
-                selectionUpdated();
-            }
-
+            setSelectedObjects(selectedObjects);
         }
     };
 
-    private FigureWidget getFigureWidget(Figure f) {
-        return figureWidgets.get(f);
-    }
-    private FocusListener focusListener = new FocusListener() {
-
-        public void focusGained(FocusEvent e) {
-            DiagramScene.this.getView().requestFocus();
-        }
-
-        public void focusLost(FocusEvent e) {
-        }
-    };
     private MouseWheelListener mouseWheelListener = new MouseWheelListener() {
 
+        @Override
         public void mouseWheelMoved(MouseWheelEvent e) {
-            DiagramScene.this.zoomAction.mouseWheelMoved(DiagramScene.this, new WidgetAction.WidgetMouseWheelEvent(0, e));
-            DiagramScene.this.validate();
+            if (e.isControlDown()) {
+                DiagramScene.this.relayoutWithoutLayout(null);
+            }
         }
     };
-    private MouseListener mouseListener = new MouseListener() {
-
-        public void mouseClicked(MouseEvent e) {
-            DiagramScene.this.panAction.mouseClicked(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
-        }
-
-        public void mousePressed(MouseEvent e) {
-            DiagramScene.this.panAction.mousePressed(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
-        }
-
-        public void mouseReleased(MouseEvent e) {
-            DiagramScene.this.panAction.mouseReleased(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
-        }
-
-        public void mouseEntered(MouseEvent e) {
-            DiagramScene.this.panAction.mouseEntered(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
-        }
-
-        public void mouseExited(MouseEvent e) {
-            DiagramScene.this.panAction.mouseExited(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
-        }
-    };
-    private MouseMotionListener mouseMotionListener = new MouseMotionListener() {
-
-        public void mouseDragged(MouseEvent e) {
-            DiagramScene.this.panAction.mouseDragged(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
-        }
-
-        public void mouseMoved(MouseEvent e) {
-        }
-    };
-    private ScrollChangeListener scrollChangeListener = new ScrollChangeListener();
-
-    private class ScrollChangeListener implements ChangeListener {
-
-        private Map<Widget, Point> relativePositions = new HashMap<Widget, Point>();
-        private Point oldPosition;
-
-        public void register(Widget w, Point p) {
-            relativePositions.put(w, p);
-        }
-
-        public void unregister(Widget w) {
-            relativePositions.remove(w);
-        }
-
-        public void stateChanged(ChangeEvent e) {
-            Point p = DiagramScene.this.getScrollPane().getViewport().getViewPosition();
-            if (oldPosition == null || !p.equals(oldPosition)) {
-                for (Widget w : relativePositions.keySet()) {
-                    Point curPoint = relativePositions.get(w);
-                    Point newPoint = new Point(p.x + curPoint.x, p.y + curPoint.y);
-                    w.setPreferredLocation(newPoint);
-                    DiagramScene.this.validate();
-                }
-                oldPosition = p;
-            }
-        }
-    }
 
     public Point getScrollPosition() {
         return getScrollPane().getViewport().getViewPosition();
@@ -341,43 +270,135 @@
         getScrollPane().getViewport().setViewPosition(p);
     }
 
-    public DiagramScene(Action[] actions, DiagramViewModel model) {
-        this.actions = actions;
-        selectedWidgets = new ArrayList<FigureWidget>();
-        content = new InstanceContent();
-        lookup = new AbstractLookup(content);
-        this.setCheckClipping(true);
-        this.getInputBindings().setZoomActionModifiers(0);
-
+    private JScrollPane createScrollPane() {
         JComponent comp = this.createView();
         comp.setDoubleBuffered(true);
         comp.setBackground(Color.WHITE);
         comp.setOpaque(true);
-
         this.setBackground(Color.WHITE);
         this.setOpaque(true);
-        scrollPane = new JScrollPane(comp);
-        scrollPane.setBackground(Color.WHITE);
-        scrollPane.getVerticalScrollBar().setUnitIncrement(SCROLL_UNIT_INCREMENT);
-        scrollPane.getVerticalScrollBar().setBlockIncrement(SCROLL_BLOCK_INCREMENT);
-        scrollPane.getHorizontalScrollBar().setUnitIncrement(SCROLL_UNIT_INCREMENT);
-        scrollPane.getHorizontalScrollBar().setBlockIncrement(SCROLL_BLOCK_INCREMENT);
-        scrollPane.getViewport().addChangeListener(scrollChangeListener);
-        hoverAction = this.createWidgetHoverAction();
+        JScrollPane result = new JScrollPane(comp);
+        result.setBackground(Color.WHITE);
+        result.getVerticalScrollBar().setUnitIncrement(SCROLL_UNIT_INCREMENT);
+        result.getVerticalScrollBar().setBlockIncrement(SCROLL_BLOCK_INCREMENT);
+        result.getHorizontalScrollBar().setUnitIncrement(SCROLL_UNIT_INCREMENT);
+        result.getHorizontalScrollBar().setBlockIncrement(SCROLL_BLOCK_INCREMENT);
+        return result;
+    }
+    private ObjectSceneListener selectionChangedListener = new ObjectSceneListener() {
+
+        @Override
+        public void objectAdded(ObjectSceneEvent arg0, Object arg1) {
+        }
+
+        @Override
+        public void objectRemoved(ObjectSceneEvent arg0, Object arg1) {
+        }
+
+        @Override
+        public void objectStateChanged(ObjectSceneEvent e, Object o, ObjectState oldState, ObjectState newState) {
+        }
+
+        @Override
+        public void selectionChanged(ObjectSceneEvent e, Set<Object> oldSet, Set<Object> newSet) {
+            DiagramScene scene = (DiagramScene) e.getObjectScene();
+            if (scene.isRebuilding()) {
+                return;
+            }
+
+            content.set(newSet, null);
+
+            Set<Integer> nodeSelection = new HashSet<>();
+            for (Object o : newSet) {
+                if (o instanceof Properties.Provider) {
+                    final Properties.Provider provider = (Properties.Provider) o;
+                    AbstractNode node = new AbstractNode(Children.LEAF) {
+
+                        @Override
+                        protected Sheet createSheet() {
+                            Sheet s = super.createSheet();
+                            PropertiesSheet.initializeSheet(provider.getProperties(), s);
+                            return s;
+                        }
+                    };
+                    node.setDisplayName(provider.getProperties().get("name"));
+                    content.add(node);
+                }
+
+
+                if (o instanceof Figure) {
+                    nodeSelection.addAll(((Figure) o).getSource().getSourceNodesAsSet());
+                } else if (o instanceof Slot) {
+                    nodeSelection.addAll(((Slot) o).getSource().getSourceNodesAsSet());
+                }
+            }
+            getModel().setSelectedNodes(nodeSelection);
+
+            boolean b = selectedCoordinatorListener.isEnabled();
+            selectedCoordinatorListener.setEnabled(false);
+            SelectionCoordinator.getInstance().setSelectedObjects(nodeSelection);
+            selectedCoordinatorListener.setEnabled(b);
+
+        }
+
+        @Override
+        public void highlightingChanged(ObjectSceneEvent e, Set<Object> oldSet, Set<Object> newSet) {
+            Set<Integer> nodeHighlighting = new HashSet<>();
+            for (Object o : newSet) {
+                if (o instanceof Figure) {
+                    nodeHighlighting.addAll(((Figure) o).getSource().getSourceNodesAsSet());
+                } else if (o instanceof Slot) {
+                    nodeHighlighting.addAll(((Slot) o).getSource().getSourceNodesAsSet());
+                }
+            }
+            boolean b = highlightedCoordinatorListener.isEnabled();
+            highlightedCoordinatorListener.setEnabled(false);
+            SelectionCoordinator.getInstance().setHighlightedObjects(nodeHighlighting);
+            highlightedCoordinatorListener.setEnabled(true);
+        }
+
+        @Override
+        public void hoverChanged(ObjectSceneEvent e, Object oldObject, Object newObject) {
+            Set<Object> newHighlightedObjects = new HashSet<>(DiagramScene.this.getHighlightedObjects());
+            if (oldObject != null) {
+                newHighlightedObjects.remove(oldObject);
+            }
+            if (newObject != null) {
+                newHighlightedObjects.add(newObject);
+            }
+            DiagramScene.this.setHighlightedObjects(newHighlightedObjects);
+        }
+
+        @Override
+        public void focusChanged(ObjectSceneEvent arg0, Object arg1, Object arg2) {
+        }
+    };
+
+    public DiagramScene(Action[] actions, DiagramViewModel model) {
+
+        this.actions = actions;
+
+        content = new InstanceContent();
+        lookup = new AbstractLookup(content);
+
+        this.setCheckClipping(true);
+
+        scrollPane = createScrollPane();
+
+        hoverAction = createObjectHoverAction();
+
+        // This panAction handles the event only when the left mouse button is
+        // pressed without any modifier keys, otherwise it will not consume it
+        // and the selection action (below) will handle the event
+        panAction = new CustomizablePanAction(~0, MouseEvent.BUTTON1_DOWN_MASK);
+        this.getActions().addAction(panAction);
+
+        selectAction = createSelectAction();
+        this.getActions().addAction(selectAction);
 
         blockLayer = new LayerWidget(this);
         this.addChild(blockLayer);
 
-        startLayer = new LayerWidget(this);
-        this.addChild(startLayer);
-        // TODO: String startLabelString = "Loading graph with " + originalDiagram.getFigures().size() + " figures and " + originalDiagram.getConnections().size() + " connections...";
-        String startLabelString = "";
-        LabelWidget w = new LabelWidget(this, startLabelString);
-        scrollChangeListener.register(w, new Point(10, 10));
-        w.setAlignment(LabelWidget.Alignment.CENTER);
-        startLabel = w;
-        startLayer.addChild(w);
-
         mainLayer = new LayerWidget(this);
         this.addChild(mainLayer);
 
@@ -385,14 +406,10 @@
         topLeft.setPreferredLocation(new Point(-BORDER_SIZE, -BORDER_SIZE));
         this.addChild(topLeft);
 
-
         bottomRight = new Widget(this);
         bottomRight.setPreferredLocation(new Point(-BORDER_SIZE, -BORDER_SIZE));
         this.addChild(bottomRight);
 
-        slotLayer = new LayerWidget(this);
-        this.addChild(slotLayer);
-
         connectionLayer = new LayerWidget(this);
         this.addChild(connectionLayer);
 
@@ -401,52 +418,38 @@
 
         this.setLayout(LayoutFactory.createAbsoluteLayout());
 
-        this.getActions().addAction(hoverAction);
-        zoomAction = new BoundedZoomAction(1.1, false);
-        zoomAction.setMaxFactor(ZOOM_MAX_FACTOR);
-        zoomAction.setMinFactor(ZOOM_MIN_FACTOR);
-        this.getActions().addAction(ActionFactory.createMouseCenteredZoomAction(1.1));
-        panAction = new ExtendedPanAction();
-        this.getActions().addAction(panAction);
+        this.getInputBindings().setZoomActionModifiers(KeyEvent.CTRL_MASK);
+        zoomAction = ActionFactory.createMouseCenteredZoomAction(1.2);
+        this.getActions().addAction(zoomAction);
+        this.getView().addMouseWheelListener(mouseWheelListener);
         this.getActions().addAction(ActionFactory.createPopupMenuAction(popupMenuProvider));
+        
+        this.getActions().addAction(ActionFactory.createWheelPanAction());
 
         LayerWidget selectLayer = new LayerWidget(this);
         this.addChild(selectLayer);
         this.getActions().addAction(ActionFactory.createRectangularSelectAction(rectangularSelectDecorator, selectLayer, rectangularSelectProvider));
 
-        blockWidgets = new HashMap<InputBlock, BlockWidget>();
-
         boolean b = this.getUndoRedoEnabled();
         this.setUndoRedoEnabled(false);
         this.setNewModel(model);
         this.setUndoRedoEnabled(b);
-    }
-
-    private void selectionUpdated() {
-        getModel().setSelectedNodes(this.getSelectedNodes());
-        addUndo();
+        this.addObjectSceneListener(selectionChangedListener, ObjectSceneEventType.OBJECT_SELECTION_CHANGED, ObjectSceneEventType.OBJECT_HIGHLIGHTING_CHANGED, ObjectSceneEventType.OBJECT_HOVER_CHANGED);
     }
 
     public DiagramViewModel getModel() {
         return model;
     }
 
-    public void setRealZoomFactor(double d) {
-        this.realZoomFactor = d;
-    }
-
-    public double getRealZoomFactor() {
-        if (realZoomFactor == 0.0) {
-            return getZoomFactor();
-        } else {
-            return realZoomFactor;
-        }
-    }
-
     public JScrollPane getScrollPane() {
         return scrollPane;
     }
 
+    @Override
+    public Component getComponent() {
+        return scrollPane;
+    }
+    
     public boolean isAllVisible() {
         return getModel().getHiddenNodes().size() == 0;
     }
@@ -455,6 +458,7 @@
         final DiagramScene diagramScene = this;
         Action a = new AbstractAction() {
 
+            @Override
             public void actionPerformed(ActionEvent e) {
                 diagramScene.gotoFigure(f);
             }
@@ -466,13 +470,7 @@
 
         name += " (";
 
-        if (f.getCluster() != null) {
-            name += "B" + f.getCluster().toString();
-        }
-        if (!this.getFigureWidget(f).isVisible()) {
-            if (f.getCluster() != null) {
-                name += ", ";
-            }
+        if (!this.getWidget(f, FigureWidget.class).isVisible()) {
             name += "hidden";
         }
         name += ")";
@@ -481,130 +479,77 @@
     }
 
     public void setNewModel(DiagramViewModel model) {
-        if (this.model != null) {
-            this.model.getDiagramChangedEvent().removeListener(this);
-            this.model.getViewPropertiesChangedEvent().removeListener(this);
-        }
+        assert this.model == null : "can set model only once!";
         this.model = model;
+        this.modelCopy = null;
 
-        if (this.model == null) {
-            this.modelCopy = null;
-        } else {
-            this.modelCopy = this.model.copy();
-        }
-
-        model.getDiagramChangedEvent().addListener(this);
-        model.getViewPropertiesChangedEvent().addListener(this);
-
+        model.getDiagramChangedEvent().addListener(fullChange);
+        model.getViewPropertiesChangedEvent().addListener(fullChange);
+        model.getViewChangedEvent().addListener(selectionChange);
+        model.getHiddenNodesChangedEvent().addListener(hiddenNodesChange);
         update();
     }
 
     private void update() {
-
-        /*if (startLabel != null) {
-        // Animate fade-out
-        final LabelWidget labelWidget = this.startLabel;
-        labelWidget.setVisible(true);
-        RequestProcessor.getDefault().post(new Runnable() {
-        public void run() {
-        final int Sleep = 200;
-        final int Progress = 10;
-        for (int i = 0; i < 255 / Progress + 1; i++) {
-        try {
-        SwingUtilities.invokeAndWait(new Runnable() {
-        public void run() {
-        Color c = labelWidget.getForeground();
-        int v = c.getRed();
-        v += Progress;
-        if (v > 255) {
-        v = 255;
-        }
-        labelWidget.setForeground(new Color(v, v, v, 255 - v));
-        labelWidget.getScene().validate();
-        }
-        });
-        } catch (InterruptedException ex) {
-        } catch (InvocationTargetException ex) {
-        }
-        try {
-        Thread.sleep(Sleep);
-        } catch (InterruptedException ex) {
-        }
-        }
-        labelWidget.setVisible(false);
-        DiagramScene.this.scrollChangeListener.unregister(labelWidget);
-        }
-        }, 1000);
-        startLabel = null;
-        }*/
-
-        slotLayer.removeChildren();
         mainLayer.removeChildren();
         blockLayer.removeChildren();
+        
+        rebuilding = true;
 
-        blockWidgets.clear();
-        figureWidgets = new HashMap<Figure, FigureWidget>();
-        slotWidgets = new HashMap<Slot, SlotWidget>();
-        connectionWidgets = new HashMap<Connection, ConnectionWidget>();
+        Collection<Object> objects = new ArrayList<>(this.getObjects());
+        for (Object o : objects) {
+            this.removeObject(o);
+        }
 
-        WidgetAction selectAction = new ExtendedSelectAction(selectProvider);
         Diagram d = getModel().getDiagramToView();
 
-        if (getModel().getShowBlocks()) {
-            Scheduler s = Lookup.getDefault().lookup(Scheduler.class);
-            Collection<InputBlock> newBlocks = new ArrayList<InputBlock>(s.schedule(d.getGraph()));
-            d.schedule(newBlocks);
-        }
-
         for (Figure f : d.getFigures()) {
-            FigureWidget w = new FigureWidget(f, this, mainLayer);
+            FigureWidget w = new FigureWidget(f, hoverAction, selectAction, this, mainLayer);
+            w.getActions().addAction(ActionFactory.createPopupMenuAction(w));
             w.getActions().addAction(selectAction);
             w.getActions().addAction(hoverAction);
-            w.getActions().addAction(ActionFactory.createPopupMenuAction(w));
-            w.getActions().addAction(new DoubleClickAction(w));
             w.setVisible(false);
 
-            figureWidgets.put(f, w);
+            this.addObject(f, w);
 
             for (InputSlot s : f.getInputSlots()) {
-                SlotWidget sw = new InputSlotWidget(s, this, slotLayer, w);
-                slotWidgets.put(s, sw);
+                SlotWidget sw = new InputSlotWidget(s, this, w, w);
+                addObject(s, sw);
+                sw.getActions().addAction(new DoubleClickAction(sw));
+                sw.getActions().addAction(hoverAction);
                 sw.getActions().addAction(selectAction);
             }
 
             for (OutputSlot s : f.getOutputSlots()) {
-                SlotWidget sw = new OutputSlotWidget(s, this, slotLayer, w);
-                slotWidgets.put(s, sw);
+                SlotWidget sw = new OutputSlotWidget(s, this, w, w);
+                addObject(s, sw);
+                sw.getActions().addAction(new DoubleClickAction(sw));
+                sw.getActions().addAction(hoverAction);
                 sw.getActions().addAction(selectAction);
             }
         }
-
-        if (getModel().getShowBlocks()) {
-            for (InputBlock bn : d.getGraph().getBlocks()) {
-                BlockWidget w = new BlockWidget(this, d, bn);
-                w.setVisible(false);
-                blockWidgets.put(bn, w);
-                blockLayer.addChild(w);
-            }
-        }
-
+        
+        rebuilding = false;
         this.smallUpdate(true);
-
+    }
+    
+    public boolean isRebuilding() {
+        return rebuilding;
     }
 
     private void smallUpdate(boolean relayout) {
 
+        System.out.println("smallUpdate " + relayout);
         this.updateHiddenNodes(model.getHiddenNodes(), relayout);
         boolean b = this.getUndoRedoEnabled();
         this.setUndoRedoEnabled(false);
-        this.setSelection(getModel().getSelectedNodes());
         this.setUndoRedoEnabled(b);
         this.validate();
     }
 
     private boolean isVisible(Connection c) {
-        FigureWidget w1 = figureWidgets.get(c.getInputSlot().getFigure());
-        FigureWidget w2 = figureWidgets.get(c.getOutputSlot().getFigure());
+        FigureWidget w1 = getWidget(c.getInputSlot().getFigure());
+        FigureWidget w2 = getWidget(c.getOutputSlot().getFigure());
 
         if (w1.isVisible() && w2.isVisible()) {
             return true;
@@ -614,19 +559,20 @@
     }
 
     private void relayout(Set<Widget> oldVisibleWidgets) {
+        System.out.println("relayout called with old visible widgets: " + oldVisibleWidgets);
 
         Diagram diagram = getModel().getDiagramToView();
 
-        HashSet<Figure> figures = new HashSet<Figure>();
+        HashSet<Figure> figures = new HashSet<>();
 
         for (Figure f : diagram.getFigures()) {
-            FigureWidget w = figureWidgets.get(f);
+            FigureWidget w = getWidget(f);
             if (w.isVisible()) {
                 figures.add(f);
             }
         }
 
-        HashSet<Connection> edges = new HashSet<Connection>();
+        HashSet<Connection> edges = new HashSet<>();
 
         for (Connection c : diagram.getConnections()) {
             if (isVisible(c)) {
@@ -634,25 +580,23 @@
             }
         }
 
-        if (getModel().getShowBlocks()) {
-            HierarchicalClusterLayoutManager m = new HierarchicalClusterLayoutManager(OldHierarchicalLayoutManager.Combine.SAME_OUTPUTS);
-            HierarchicalLayoutManager manager = new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS);
-            manager.setMaxLayerLength(9);
-            manager.setMinLayerDifference(3);
-            m.setManager(manager);
-            m.setSubManager(new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS));
-            m.doLayout(new LayoutGraph(edges, figures));
+        HierarchicalLayoutManager manager = new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS);
+        manager.setMaxLayerLength(10);
+        manager.doLayout(new LayoutGraph(edges, figures));
+        relayoutWithoutLayout(oldVisibleWidgets);
+    }
+    private Set<Pair<Point, Point>> lineCache = new HashSet<>();
 
-        } else {
-            HierarchicalLayoutManager manager = new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS);
-            manager.setMaxLayerLength(10);
-            manager.doLayout(new LayoutGraph(edges, figures));
-        }
+    private void relayoutWithoutLayout(Set<Widget> oldVisibleWidgets) {
+
+        System.out.println("relayout without layout with visible widgets: " + oldVisibleWidgets);
+
+        Diagram diagram = getModel().getDiagramToView();
 
         int maxX = -BORDER_SIZE;
         int maxY = -BORDER_SIZE;
         for (Figure f : diagram.getFigures()) {
-            FigureWidget w = figureWidgets.get(f);
+            FigureWidget w = getWidget(f);
             if (w.isVisible()) {
                 Point p = f.getPosition();
                 Dimension d = f.getSize();
@@ -663,8 +607,8 @@
 
         for (Connection c : diagram.getConnections()) {
             List<Point> points = c.getControlPoints();
-            FigureWidget w1 = figureWidgets.get((Figure) c.getTo().getVertex());
-            FigureWidget w2 = figureWidgets.get((Figure) c.getFrom().getVertex());
+            FigureWidget w1 = getWidget((Figure) c.getTo().getVertex());
+            FigureWidget w2 = getWidget((Figure) c.getFrom().getVertex());
             if (w1.isVisible() && w2.isVisible()) {
                 for (Point p : points) {
                     if (p != null) {
@@ -675,17 +619,6 @@
             }
         }
 
-        if (getModel().getShowBlocks()) {
-            for (Block b : diagram.getBlocks()) {
-                BlockWidget w = blockWidgets.get(b.getInputBlock());
-                if (w != null && w.isVisible()) {
-                    Rectangle r = b.getBounds();
-                    maxX = Math.max(maxX, r.x + r.width);
-                    maxY = Math.max(maxY, r.y + r.height);
-                }
-            }
-        }
-
         bottomRight.setPreferredLocation(new Point(maxX + BORDER_SIZE, maxY + BORDER_SIZE));
         int offx = 0;
         int offy = 0;
@@ -693,6 +626,8 @@
         int curHeight = maxY + 2 * BORDER_SIZE;
 
         Rectangle bounds = this.getScrollPane().getBounds();
+        bounds.width /= getZoomFactor();
+        bounds.height /= getZoomFactor();
         if (curWidth < bounds.width) {
             offx = (bounds.width - curWidth) / 2;
         }
@@ -708,62 +643,44 @@
         connectionLayer.removeChildren();
         int visibleFigureCount = 0;
         for (Figure f : diagram.getFigures()) {
-            if (figureWidgets.get(f).isVisible()) {
+            if (getWidget(f, FigureWidget.class).isVisible()) {
                 visibleFigureCount++;
             }
         }
 
+
+        Set<Pair<Point, Point>> lastLineCache = lineCache;
+        lineCache = new HashSet<>();
         for (Figure f : diagram.getFigures()) {
             for (OutputSlot s : f.getOutputSlots()) {
                 SceneAnimator anim = animator;
-                if (visibleFigureCount > ANIMATION_LIMIT) {
+                if (visibleFigureCount > ANIMATION_LIMIT || oldVisibleWidgets == null) {
                     anim = null;
                 }
-                processOutputSlot(s, s.getConnections(), 0, null, null, offx2, offy2, anim);
+                processOutputSlot(lastLineCache, s, s.getConnections(), 0, null, null, offx2, offy2, anim);
             }
         }
 
         for (Figure f : diagram.getFigures()) {
-            FigureWidget w = figureWidgets.get(f);
+            FigureWidget w = getWidget(f);
             if (w.isVisible()) {
                 Point p = f.getPosition();
                 Point p2 = new Point(p.x + offx2, p.y + offy2);
-                Rectangle r = new Rectangle(p.x + offx2, p.y + offy2, f.getSize().width, f.getSize().height);
-                if (oldVisibleWidgets.contains(w)) {
-                    if (visibleFigureCount > ANIMATION_LIMIT) {
-                        w.setPreferredLocation(p2);
-                    } else {
-                        animator.animatePreferredLocation(w, p2);
-                    }
+                if ((visibleFigureCount <= ANIMATION_LIMIT && oldVisibleWidgets != null && oldVisibleWidgets.contains(w))) {
+                    animator.animatePreferredLocation(w, p2);
                 } else {
                     w.setPreferredLocation(p2);
+                    animator.animatePreferredLocation(w, p2);
                 }
             }
         }
 
-        if (getModel().getShowBlocks()) {
-            for (Block b : diagram.getBlocks()) {
-                BlockWidget w = blockWidgets.get(b.getInputBlock());
-                if (w != null && w.isVisible()) {
-                    Point location = new Point(b.getBounds().x + offx2, b.getBounds().y + offy2);
-                    Rectangle r = new Rectangle(location.x, location.y, b.getBounds().width, b.getBounds().height);
-                    if (oldVisibleWidgets.contains(w)) {
-                        if (visibleFigureCount > ANIMATION_LIMIT) {
-                            w.setPreferredBounds(r);
-                        } else {
-                            animator.animatePreferredBounds(w, r);
-                        }
-                    } else {
-                        w.setPreferredBounds(r);
-                    }
-                }
-            }
-        }
+        this.validate();
     }
     private final Point specialNullPoint = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
 
-    private void processOutputSlot(OutputSlot s, List<Connection> connections, int controlPointIndex, Point lastPoint, LineWidget predecessor, int offx, int offy, SceneAnimator animator) {
-        Map<Point, List<Connection>> pointMap = new HashMap<Point, List<Connection>>();
+    private void processOutputSlot(Set<Pair<Point, Point>> lastLineCache, OutputSlot s, List<Connection> connections, int controlPointIndex, Point lastPoint, LineWidget predecessor, int offx, int offy, SceneAnimator animator) {
+        Map<Point, List<Connection>> pointMap = new HashMap<>(connections.size());
 
         for (Connection c : connections) {
 
@@ -779,16 +696,16 @@
             Point cur = controlPoints.get(controlPointIndex);
             if (cur == null) {
                 cur = specialNullPoint;
-            } else if (controlPointIndex == 0 && !s.getShowName()) {
+            } else if (controlPointIndex == 0 && !s.shouldShowName()) {
                 cur = new Point(cur.x, cur.y - SLOT_OFFSET);
-            } else if (controlPointIndex == controlPoints.size() - 1 && !c.getInputSlot().getShowName()) {
+            } else if (controlPointIndex == controlPoints.size() - 1 && !c.getInputSlot().shouldShowName()) {
                 cur = new Point(cur.x, cur.y + SLOT_OFFSET);
             }
 
             if (pointMap.containsKey(cur)) {
                 pointMap.get(cur).add(c);
             } else {
-                List<Connection> newList = new ArrayList<Connection>(2);
+                List<Connection> newList = new ArrayList<>(2);
                 newList.add(c);
                 pointMap.put(cur, newList);
             }
@@ -814,44 +731,70 @@
 
             LineWidget newPredecessor = predecessor;
             if (p == specialNullPoint) {
-
             } else if (lastPoint == specialNullPoint) {
-
             } else if (lastPoint != null) {
                 Point p1 = new Point(lastPoint.x + offx, lastPoint.y + offy);
                 Point p2 = new Point(p.x + offx, p.y + offy);
-                LineWidget w = new LineWidget(this, s, connectionList, p1, p2, predecessor, animator, isBold, isDashed);
+
+                Pair<Point, Point> curPair = new Pair<>(p1, p2);
+                SceneAnimator curAnimator = animator;
+                if (lastLineCache.contains(curPair)) {
+                    curAnimator = null;
+                }
+                LineWidget w = new LineWidget(this, s, connectionList, p1, p2, predecessor, curAnimator, isBold, isDashed);
+                lineCache.add(curPair);
+
                 newPredecessor = w;
                 connectionLayer.addChild(w);
+                this.addObject(new ConnectionSet(connectionList), w);
                 w.getActions().addAction(hoverAction);
             }
 
-            processOutputSlot(s, connectionList, controlPointIndex + 1, p, newPredecessor, offx, offy, animator);
+            processOutputSlot(lastLineCache, s, connectionList, controlPointIndex + 1, p, newPredecessor, offx, offy, animator);
         }
     }
 
-    private void clearSelection() {
-        if (selectedWidgets.size() == 0) {
-            return;
-        }
-        for (FigureWidget w : selectedWidgets) {
-            assert w.getState().isSelected();
-            w.setState(w.getState().deriveSelected(false));
-            content.remove(w.getNode());
-        }
-        selectedWidgets.clear();
+    @Override
+    public void setInteractionMode(InteractionMode mode) {
+        panAction.setEnabled(mode == InteractionMode.PANNING);
+        // When panAction is not enabled, it does not consume the event
+        // and the selection action handles it instead
     }
 
+    private class ConnectionSet {
+
+        private Set<Connection> connections;
+
+        public ConnectionSet(Collection<Connection> connections) {
+            connections = new HashSet<>(connections);
+        }
+
+        public Set<Connection> getConnectionSet() {
+            return Collections.unmodifiableSet(connections);
+        }
+    }
+
+    @Override
     public Lookup getLookup() {
         return lookup;
     }
 
+    @Override
+    public void initialize() {
+        Figure f = getModel().getDiagramToView().getRootFigure();
+        if (f != null) {
+            setUndoRedoEnabled(false);
+            gotoFigure(f);
+            setUndoRedoEnabled(true);
+        }
+    }
+
     public void gotoFigures(final List<Figure> figures) {
         Rectangle overall = null;
-        showFigures(figures);
+        getModel().showFigures(figures);
         for (Figure f : figures) {
 
-            FigureWidget fw = getFigureWidget(f);
+            FigureWidget fw = getWidget(f);
             if (fw != null) {
                 Rectangle r = fw.getBounds();
                 Point p = fw.getLocation();
@@ -869,6 +812,54 @@
         }
     }
 
+    private Set<Object> idSetToObjectSet(Set<Object> ids) {
+
+        Set<Object> result = new HashSet<>();
+        for (Figure f : getModel().getDiagramToView().getFigures()) {
+            if (DiagramScene.doesIntersect(f.getSource().getSourceNodesAsSet(), ids)) {
+                result.add(f);
+            }
+
+            for (Slot s : f.getSlots()) {
+                if (DiagramScene.doesIntersect(s.getSource().getSourceNodesAsSet(), ids)) {
+                    result.add(s);
+                }
+            }
+        }
+        return result;
+    }
+
+    public void gotoSelection(Set<Object> ids) {
+
+        Rectangle overall = null;
+        Set<Integer> hiddenNodes = new HashSet<>(this.getModel().getHiddenNodes());
+        hiddenNodes.removeAll(ids);
+        this.getModel().showNot(hiddenNodes);
+
+        Set<Object> objects = idSetToObjectSet(ids);
+        for (Object o : objects) {
+
+            Widget w = getWidget(o);
+            if (w != null) {
+                Rectangle r = w.getBounds();
+                Point p = w.convertLocalToScene(new Point(0, 0));
+
+                Rectangle r2 = new Rectangle(p.x, p.y, r.width, r.height);
+
+                if (overall == null) {
+                    overall = r2;
+                } else {
+                    overall = overall.union(r2);
+                }
+            }
+        }
+        if (overall != null) {
+            centerRectangle(overall);
+        }
+
+        setSelectedObjects(objects);
+    }
+
     private Point calcCenter(Rectangle r) {
 
         Point center = new Point((int) r.getCenterX(), (int) r.getCenterY());
@@ -909,63 +900,9 @@
         }
     }
 
-    private void addToSelection(Figure f) {
-        FigureWidget w = getFigureWidget(f);
-        addToSelection(w);
-    }
-
-    private void addToSelection(FigureWidget w) {
-        assert !selectedWidgets.contains(w);
-        selectedWidgets.add(w);
-        content.add(w.getNode());
-        w.setState(w.getState().deriveSelected(true));
-    }
-
-    private void setSelection(Set<Integer> nodes) {
-        clearSelection();
-        for (Figure f : getModel().getDiagramToView().getFigures()) {
-            if (doesIntersect(f.getSource().getSourceNodesAsSet(), nodes)) {
-                addToSelection(f);
-            }
-        }
-        selectionUpdated();
-        this.validate();
-    }
-
+    @Override
     public void setSelection(Collection<Figure> list) {
-        clearSelection();
-        for (Figure f : list) {
-            addToSelection(f);
-        }
-
-        selectionUpdated();
-        this.validate();
-    }
-
-    public Set<Figure> getSelectedFigures() {
-        Set<Figure> result = new HashSet<Figure>();
-        for (Widget w : selectedWidgets) {
-            if (w instanceof FigureWidget) {
-                FigureWidget fw = (FigureWidget) w;
-                if (fw.getState().isSelected()) {
-                    result.add(fw.getFigure());
-                }
-            }
-        }
-        return result;
-    }
-
-    public Set<Integer> getSelectedNodes() {
-        Set<Integer> result = new HashSet<Integer>();
-        for (Widget w : selectedWidgets) {
-            if (w instanceof FigureWidget) {
-                FigureWidget fw = (FigureWidget) w;
-                if (fw.getState().isSelected()) {
-                    result.addAll(fw.getFigure().getSource().getSourceNodesAsSet());
-                }
-            }
-        }
-        return result;
+        super.setSelectedObjects(new HashSet<>(list));
     }
 
     private UndoRedo.Manager getUndoRedoManager() {
@@ -977,6 +914,7 @@
         return undoRedoManager;
     }
 
+    @Override
     public UndoRedo getUndoRedo() {
         return getUndoRedoManager();
     }
@@ -990,9 +928,9 @@
         return true;
     }
 
-    private boolean doesIntersect(Set s1, Set s2) {
+    public static boolean doesIntersect(Set<?> s1, Set<?> s2) {
         if (s1.size() > s2.size()) {
-            Set tmp = s1;
+            Set<?> tmp = s1;
             s1 = s2;
             s2 = tmp;
         }
@@ -1006,52 +944,42 @@
         return false;
     }
 
-    public void showNot(final Set<Integer> nodes) {
-        updateHiddenNodes(nodes, true);
+    @Override
+    public void componentHidden() {
+        SelectionCoordinator.getInstance().getHighlightedChangedEvent().removeListener(highlightedCoordinatorListener);
+        SelectionCoordinator.getInstance().getSelectedChangedEvent().removeListener(selectedCoordinatorListener);
     }
 
-    public void showOnly(final Set<Integer> nodes) {
-        HashSet<Integer> allNodes = new HashSet<Integer>(getModel().getGraphToView().getGroup().getAllNodes());
-        allNodes.removeAll(nodes);
-        updateHiddenNodes(allNodes, true);
+    @Override
+    public void componentShowing() {
+        SelectionCoordinator.getInstance().getHighlightedChangedEvent().addListener(highlightedCoordinatorListener);
+        SelectionCoordinator.getInstance().getSelectedChangedEvent().addListener(selectedCoordinatorListener);
     }
 
     private void updateHiddenNodes(Set<Integer> newHiddenNodes, boolean doRelayout) {
 
-        Set<InputBlock> visibleBlocks = new HashSet<InputBlock>();
+        System.out.println("newHiddenNodes: " + newHiddenNodes);
 
         Diagram diagram = getModel().getDiagramToView();
         assert diagram != null;
 
-        Set<Widget> oldVisibleWidgets = new HashSet<Widget>();
+        Set<Widget> oldVisibleWidgets = new HashSet<>();
 
         for (Figure f : diagram.getFigures()) {
-            FigureWidget w = figureWidgets.get(f);
-            if (w.isVisible()) {
+            FigureWidget w = getWidget(f);
+            if (w != null && w.isVisible()) {
                 oldVisibleWidgets.add(w);
             }
         }
 
-        if (getModel().getShowBlocks()) {
-            for (InputBlock b : diagram.getGraph().getBlocks()) {
-                BlockWidget w = blockWidgets.get(b);
-                if (w.isVisible()) {
-                    oldVisibleWidgets.add(w);
-                }
-            }
-        }
-
         for (Figure f : diagram.getFigures()) {
             boolean hiddenAfter = doesIntersect(f.getSource().getSourceNodesAsSet(), newHiddenNodes);
 
-            FigureWidget w = this.figureWidgets.get(f);
+            FigureWidget w = getWidget(f);
             w.setBoundary(false);
             if (!hiddenAfter) {
                 // Figure is shown
                 w.setVisible(true);
-                for (InputNode n : f.getSource().getSourceNodes()) {
-                    visibleBlocks.add(diagram.getGraph().getBlock(n));
-                }
             } else {
                 // Figure is hidden
                 w.setVisible(false);
@@ -1059,16 +987,16 @@
         }
 
         if (getModel().getShowNodeHull()) {
-            List<FigureWidget> boundaries = new ArrayList<FigureWidget>();
+            List<FigureWidget> boundaries = new ArrayList<>();
             for (Figure f : diagram.getFigures()) {
-                FigureWidget w = this.figureWidgets.get(f);
+                FigureWidget w = getWidget(f);
                 if (!w.isVisible()) {
-                    Set<Figure> set = new HashSet<Figure>(f.getPredecessorSet());
+                    Set<Figure> set = new HashSet<>(f.getPredecessorSet());
                     set.addAll(f.getSuccessorSet());
 
                     boolean b = false;
                     for (Figure neighbor : set) {
-                        FigureWidget neighborWidget = figureWidgets.get(neighbor);
+                        FigureWidget neighborWidget = getWidget(neighbor);
                         if (neighborWidget.isVisible()) {
                             b = true;
                             break;
@@ -1077,9 +1005,6 @@
 
                     if (b) {
                         w.setBoundary(true);
-                        for (InputNode n : f.getSource().getSourceNodes()) {
-                            visibleBlocks.add(diagram.getGraph().getBlock(n));
-                        }
                         boundaries.add(w);
                     }
                 }
@@ -1092,23 +1017,6 @@
             }
         }
 
-        if (getModel().getShowBlocks()) {
-            for (InputBlock b : diagram.getGraph().getBlocks()) {
-
-                boolean visibleAfter = visibleBlocks.contains(b);
-
-                BlockWidget w = blockWidgets.get(b);
-                if (visibleAfter) {
-                    // Block must be shown
-                    w.setVisible(true);
-                } else {
-                    // Block must be hidden
-                    w.setVisible(false);
-                }
-            }
-        }
-
-        getModel().setHiddenNodes(newHiddenNodes);
         if (doRelayout) {
             relayout(oldVisibleWidgets);
         }
@@ -1116,45 +1024,39 @@
         addUndo();
     }
 
-    private void showFigures(Collection<Figure> f) {
-        HashSet<Integer> newHiddenNodes = new HashSet<Integer>(getModel().getHiddenNodes());
-        for (Figure fig : f) {
-            newHiddenNodes.removeAll(fig.getSource().getSourceNodesAsSet());
-        }
-        updateHiddenNodes(newHiddenNodes, true);
-    }
-
     private void showFigure(Figure f) {
-        HashSet<Integer> newHiddenNodes = new HashSet<Integer>(getModel().getHiddenNodes());
+        HashSet<Integer> newHiddenNodes = new HashSet<>(getModel().getHiddenNodes());
         newHiddenNodes.removeAll(f.getSource().getSourceNodesAsSet());
         updateHiddenNodes(newHiddenNodes, true);
     }
 
-    public void showAll(final Collection<Figure> f) {
-        showFigures(f);
-
-    }
-
     public void show(final Figure f) {
         showFigure(f);
     }
 
+    public void setSelectedObjects(Object... args) {
+        Set<Object> set = new HashSet<>();
+        for (Object o : args) {
+            set.add(o);
+        }
+        super.setSelectedObjects(set);
+    }
+
+    private void centerWidget(Widget w) {
+        Rectangle r = w.getBounds();
+        Point p = w.getLocation();
+        centerRectangle(new Rectangle(p.x, p.y, r.width, r.height));
+    }
+
     public void gotoFigure(final Figure f) {
-
         if (!isVisible(f)) {
             showFigure(f);
         }
 
-        FigureWidget fw = getFigureWidget(f);
+        FigureWidget fw = getWidget(f);
         if (fw != null) {
-            Rectangle r = fw.getBounds();
-            Point p = fw.getLocation();
-            centerRectangle(new Rectangle(p.x, p.y, r.width, r.height));
-
-            // Select figure
-            clearSelection();
-            addToSelection(fw);
-            selectionUpdated();
+            centerWidget(fw);
+            setSelection(Arrays.asList(f));
         }
     }
 
@@ -1208,6 +1110,7 @@
 
             SwingUtilities.invokeLater(new Runnable() {
 
+                @Override
                 public void run() {
                     scene.setScrollPosition(oldScrollPosition);
                 }
@@ -1216,9 +1119,10 @@
             scene.setUndoRedoEnabled(b);
         }
 
+        @Override
         public void changed(DiagramViewModel source) {
             scene.getModel().getViewChangedEvent().removeListener(this);
-            if (oldModel.getSelectedNodes().equals(newModel.getHiddenNodes())) {
+            if (oldModel.getHiddenNodes().equals(newModel.getHiddenNodes())) {
                 scene.smallUpdate(false);
             } else {
                 scene.smallUpdate(true);
@@ -1235,11 +1139,33 @@
         return undoRedoEnabled;
     }
 
-    public void changed(DiagramViewModel source) {
-        assert source == model : "Receive only changed event from current model!";
-        assert source != null;
-        update();
-    }
+    private final ChangedListener<DiagramViewModel> fullChange = new ChangedListener<DiagramViewModel>() {
+        @Override
+        public void changed(DiagramViewModel source) {
+            assert source == model : "Receive only changed event from current model!";
+            assert source != null;
+            update();
+        }
+    };
+
+    private final ChangedListener<DiagramViewModel> hiddenNodesChange = new ChangedListener<DiagramViewModel>() {
+        @Override
+        public void changed(DiagramViewModel source) {
+            assert source == model : "Receive only changed event from current model!";
+            assert source != null;
+            smallUpdate(true);
+        }
+    };
+
+    private final ChangedListener<DiagramViewModel> selectionChange = new ChangedListener<DiagramViewModel>() {
+        @Override
+        public void changed(DiagramViewModel source) {
+            assert source == model : "Receive only changed event from current model!";
+            assert source != null;
+            smallUpdate(false);
+        }
+    };
+
 
     private void addUndo() {
 
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java	Mon Feb 27 13:10:13 2012 +0100
@@ -24,22 +24,16 @@
  */
 package com.sun.hotspot.igv.view;
 
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.InputGraph;
-import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.*;
 import com.sun.hotspot.igv.difference.Difference;
+import com.sun.hotspot.igv.filter.CustomFilter;
 import com.sun.hotspot.igv.filter.FilterChain;
 import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.settings.Settings;
 import com.sun.hotspot.igv.util.RangeSliderModel;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import com.sun.hotspot.igv.data.ChangedListener;
-import com.sun.hotspot.igv.settings.Settings;
 import java.awt.Color;
+import java.util.*;
 
 /**
  *
@@ -55,14 +49,16 @@
     private FilterChain filterChain;
     private FilterChain sequenceFilterChain;
     private Diagram diagram;
+    private InputGraph inputGraph;
     private ChangedEvent<DiagramViewModel> groupChangedEvent;
     private ChangedEvent<DiagramViewModel> diagramChangedEvent;
     private ChangedEvent<DiagramViewModel> viewChangedEvent;
+    private ChangedEvent<DiagramViewModel> hiddenNodesChangedEvent;
     private ChangedEvent<DiagramViewModel> viewPropertiesChangedEvent;
-    private boolean showBlocks;
     private boolean showNodeHull;
     private ChangedListener<FilterChain> filterChainChangedListener = new ChangedListener<FilterChain>() {
 
+        @Override
         public void changed(FilterChain source) {
             diagramChanged();
         }
@@ -95,12 +91,10 @@
         this.onScreenNodes = newModel.onScreenNodes;
         viewChanged |= (selectedNodes != newModel.selectedNodes);
         this.selectedNodes = newModel.selectedNodes;
-        viewPropertiesChanged |= (showBlocks != newModel.showBlocks);
-        this.showBlocks = newModel.showBlocks;
         viewPropertiesChanged |= (showNodeHull != newModel.showNodeHull);
         this.showNodeHull = newModel.showNodeHull;
 
-        if(groupChanged) {
+        if (groupChanged) {
             groupChangedEvent.fire();
         }
 
@@ -115,15 +109,6 @@
         }
     }
 
-    public boolean getShowBlocks() {
-        return showBlocks;
-    }
-
-    public void setShowBlocks(boolean b) {
-        showBlocks = b;
-        viewPropertiesChangedEvent.fire();
-    }
-
     public boolean getShowNodeHull() {
         return showNodeHull;
     }
@@ -137,49 +122,48 @@
         super(calculateStringList(g));
 
         this.showNodeHull = true;
-        this.showBlocks = true;
         this.group = g;
         assert filterChain != null;
         this.filterChain = filterChain;
         assert sequenceFilterChain != null;
         this.sequenceFilterChain = sequenceFilterChain;
-        hiddenNodes = new HashSet<Integer>();
-        onScreenNodes = new HashSet<Integer>();
-        selectedNodes = new HashSet<Integer>();
+        hiddenNodes = new HashSet<>();
+        onScreenNodes = new HashSet<>();
+        selectedNodes = new HashSet<>();
         super.getChangedEvent().addListener(this);
-        diagramChangedEvent = new ChangedEvent<DiagramViewModel>(this);
-        viewChangedEvent = new ChangedEvent<DiagramViewModel>(this);
-        viewPropertiesChangedEvent = new ChangedEvent<DiagramViewModel>(this);
-        groupChangedEvent = new ChangedEvent<DiagramViewModel>(this);
+        diagramChangedEvent = new ChangedEvent<>(this);
+        viewChangedEvent = new ChangedEvent<>(this);
+        hiddenNodesChangedEvent = new ChangedEvent<>(this);
+        viewPropertiesChangedEvent = new ChangedEvent<>(this);
+
+        groupChangedEvent = new ChangedEvent<>(this);
         groupChangedEvent.addListener(groupChangedListener);
         groupChangedEvent.fire();
 
         filterChain.getChangedEvent().addListener(filterChainChangedListener);
         sequenceFilterChain.getChangedEvent().addListener(filterChainChangedListener);
     }
-
     private final ChangedListener<DiagramViewModel> groupChangedListener = new ChangedListener<DiagramViewModel>() {
 
         private Group oldGroup;
 
+        @Override
         public void changed(DiagramViewModel source) {
-            if(oldGroup != null) {
+            if (oldGroup != null) {
                 oldGroup.getChangedEvent().removeListener(groupContentChangedListener);
             }
             group.getChangedEvent().addListener(groupContentChangedListener);
             oldGroup = group;
         }
     };
-
-
     private final ChangedListener<Group> groupContentChangedListener = new ChangedListener<Group>() {
 
+        @Override
         public void changed(Group source) {
             assert source == group;
             setPositions(calculateStringList(source));
             setSelectedNodes(selectedNodes);
         }
-
     };
 
     public ChangedEvent<DiagramViewModel> getDiagramChangedEvent() {
@@ -190,25 +174,29 @@
         return viewChangedEvent;
     }
 
+    public ChangedEvent<DiagramViewModel> getHiddenNodesChangedEvent() {
+        return hiddenNodesChangedEvent;
+    }
+
     public ChangedEvent<DiagramViewModel> getViewPropertiesChangedEvent() {
         return viewPropertiesChangedEvent;
     }
 
     public Set<Integer> getSelectedNodes() {
-        return Collections.unmodifiableSet(selectedNodes);
+        return selectedNodes;
     }
 
     public Set<Integer> getHiddenNodes() {
-        return Collections.unmodifiableSet(hiddenNodes);
+        return hiddenNodes;
     }
 
     public Set<Integer> getOnScreenNodes() {
-        return Collections.unmodifiableSet(onScreenNodes);
+        return onScreenNodes;
     }
 
     public void setSelectedNodes(Set<Integer> nodes) {
         this.selectedNodes = nodes;
-        List<Color> colors = new ArrayList<Color>();
+        List<Color> colors = new ArrayList<>();
         for (String s : getPositions()) {
             colors.add(Color.black);
         }
@@ -242,15 +230,50 @@
                     index++;
                 }
             }
-            this.setColors(colors);
         }
         setColors(colors);
         viewChangedEvent.fire();
     }
 
+    public void showNot(final Set<Integer> nodes) {
+        System.out.println("Shownot called with " + nodes);
+        setHiddenNodes(nodes);
+    }
+
+    public void showFigures(Collection<Figure> f) {
+        HashSet<Integer> newHiddenNodes = new HashSet<>(getHiddenNodes());
+        for (Figure fig : f) {
+            newHiddenNodes.removeAll(fig.getSource().getSourceNodesAsSet());
+        }
+        setHiddenNodes(newHiddenNodes);
+    }
+
+
+    public Set<Figure> getSelectedFigures() {
+        Set<Figure> result = new HashSet<>();
+        for (Figure f : diagram.getFigures()) {
+            for (InputNode node : f.getSource().getSourceNodes()) {
+                if (getSelectedNodes().contains(node.getId())) {
+                    result.add(f);
+                }
+            }
+        }
+        return result;
+    }
+
+    public void showAll(final Collection<Figure> f) {
+        showFigures(f);
+    }
+
+    public void showOnly(final Set<Integer> nodes) {
+        final HashSet<Integer> allNodes = new HashSet<>(getGraphToView().getGroup().getAllNodes());
+        allNodes.removeAll(nodes);
+        setHiddenNodes(allNodes);
+    }
+
     public void setHiddenNodes(Set<Integer> nodes) {
         this.hiddenNodes = nodes;
-        viewChangedEvent.fire();
+        hiddenNodesChangedEvent.fire();
     }
 
     public void setOnScreenNodes(Set<Integer> onScreenNodes) {
@@ -290,7 +313,7 @@
     }
 
     private static List<String> calculateStringList(Group g) {
-        List<String> result = new ArrayList<String>();
+        List<String> result = new ArrayList<>();
         for (InputGraph graph : g.getGraphs()) {
             result.add(graph.getName());
         }
@@ -298,13 +321,18 @@
     }
 
     public InputGraph getFirstGraph() {
-        return group.getGraphs().get(getFirstPosition());
+        List<InputGraph> graphs = group.getGraphs();
+        if (getFirstPosition() < graphs.size()) {
+            return graphs.get(getFirstPosition());
+        }
+        return graphs.get(graphs.size() - 1);
     }
 
     public InputGraph getSecondGraph() {
         List<InputGraph> graphs = group.getGraphs();
-        if (graphs.size() >= getSecondPosition())
-            return group.getGraphs().get(getSecondPosition());
+        if (getSecondPosition() < graphs.size()) {
+            return graphs.get(getSecondPosition());
+        }
         return getFirstGraph();
     }
 
@@ -319,22 +347,42 @@
         if (diagram == null) {
             diagram = Diagram.createDiagram(getGraphToView(), Settings.get().get(Settings.NODE_TEXT, Settings.NODE_TEXT_DEFAULT));
             getFilterChain().apply(diagram, getSequenceFilterChain());
+            if (getFirstPosition() != getSecondPosition()) {
+                CustomFilter f = new CustomFilter(
+                        "difference", "colorize('state', 'same', white);"
+                        + "colorize('state', 'changed', orange);"
+                        + "colorize('state', 'new', green);"
+                        + "colorize('state', 'deleted', red);");
+                f.apply(diagram);
+           }
         }
 
         return diagram;
     }
 
     public InputGraph getGraphToView() {
-        if (getFirstGraph() != getSecondGraph()) {
-            InputGraph inputGraph = Difference.createDiffGraph(getSecondGraph(), getFirstGraph());
-            return inputGraph;
-        } else {
-            InputGraph inputGraph = getFirstGraph();
-            return inputGraph;
+        if (inputGraph == null) {
+            if (getFirstGraph() != getSecondGraph()) {
+                inputGraph = Difference.createDiffGraph(getFirstGraph(), getSecondGraph());
+            } else {
+                inputGraph = getFirstGraph();
+            }
         }
+
+        return inputGraph;
     }
 
+    @Override
     public void changed(RangeSliderModel source) {
+        inputGraph = null;
         diagramChanged();
     }
+
+    void setSelectedFigures(List<Figure> list) {
+        Set<Integer> newSelectedNodes = new HashSet<>();
+        for (Figure f : list) {
+            newSelectedNodes.addAll(f.getSource().getSourceNodesAsSet());
+        }
+        this.setSelectedNodes(newSelectedNodes);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewer.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.view;
+
+import com.sun.hotspot.igv.graph.Figure;
+import java.awt.Component;
+import java.awt.Graphics2D;
+import java.util.Collection;
+import java.util.List;
+import javax.swing.JComponent;
+import org.openide.awt.UndoRedo;
+import org.openide.util.Lookup;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+interface DiagramViewer {
+
+    enum InteractionMode {
+        SELECTION,
+        PANNING,
+    }
+
+    public void paint(Graphics2D svgGenerator);
+
+    public Lookup getLookup();
+
+    public JComponent createSatelliteView();
+
+    public Component getComponent();
+
+    public void zoomOut();
+
+    public void zoomIn();
+
+    public UndoRedo getUndoRedo();
+
+    public void componentHidden();
+
+    public void componentShowing();
+
+    public void initialize();
+    
+    public void setSelection(Collection<Figure> list);
+
+    public void centerFigures(List<Figure> list);
+    
+    public void setInteractionMode(InteractionMode mode);
+
+}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorInputGraphProvider.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorInputGraphProvider.java	Mon Feb 27 13:10:13 2012 +0100
@@ -25,8 +25,8 @@
 package com.sun.hotspot.igv.view;
 
 import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.InputNode;
 import com.sun.hotspot.igv.data.services.InputGraphProvider;
-import com.sun.hotspot.igv.data.InputNode;
 import java.util.Set;
 
 /**
@@ -35,18 +35,19 @@
  */
 public class EditorInputGraphProvider implements InputGraphProvider {
 
+    private EditorTopComponent editor;
+    
+    public EditorInputGraphProvider(EditorTopComponent editor) {
+        this.editor = editor;
+    }
+    
+    @Override
     public InputGraph getGraph() {
-        EditorTopComponent e = EditorTopComponent.getActive();
-        if (e == null) {
-            return null;
-        }
-        return e.getDiagramModel().getGraphToView();
+        return editor.getDiagramModel().getGraphToView();
     }
 
+    @Override
     public void setSelectedNodes(Set<InputNode> nodes) {
-        EditorTopComponent e = EditorTopComponent.getActive();
-        if (e != null) {
-            e.setSelectedNodes(nodes);
-        }
+        editor.setSelectedNodes(nodes);
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.form	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.form	Mon Feb 27 13:10:13 2012 +0100
@@ -18,6 +18,8 @@
   </NonVisualComponents>
   <AuxValues>
     <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
     <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,62 +23,35 @@
  */
 package com.sun.hotspot.igv.view;
 
+import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.data.ChangedListener;
 import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Properties.PropertyMatcher;
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
 import com.sun.hotspot.igv.filter.FilterChain;
+import com.sun.hotspot.igv.filter.FilterChainProvider;
 import com.sun.hotspot.igv.graph.Diagram;
 import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.view.actions.EnableBlockLayoutAction;
-import com.sun.hotspot.igv.view.actions.ExpandPredecessorsAction;
-import com.sun.hotspot.igv.view.actions.ExpandSuccessorsAction;
-import com.sun.hotspot.igv.view.actions.ExtractAction;
-import com.sun.hotspot.igv.view.actions.HideAction;
-import com.sun.hotspot.igv.view.actions.NextDiagramAction;
-import com.sun.hotspot.igv.view.actions.NodeFindAction;
-import com.sun.hotspot.igv.view.actions.OverviewAction;
-import com.sun.hotspot.igv.view.actions.PredSuccAction;
-import com.sun.hotspot.igv.view.actions.PrevDiagramAction;
-import com.sun.hotspot.igv.view.actions.ShowAllAction;
-import com.sun.hotspot.igv.view.actions.ZoomInAction;
-import com.sun.hotspot.igv.view.actions.ZoomOutAction;
-import com.sun.hotspot.igv.data.ChangedListener;
-import com.sun.hotspot.igv.data.Properties;
-import com.sun.hotspot.igv.data.Properties.PropertyMatcher;
-import com.sun.hotspot.igv.filter.FilterChainProvider;
+import com.sun.hotspot.igv.graph.services.DiagramProvider;
+import com.sun.hotspot.igv.svg.BatikSVG;
+import com.sun.hotspot.igv.util.LookupHistory;
 import com.sun.hotspot.igv.util.RangeSlider;
-import com.sun.hotspot.igv.util.RangeSliderModel;
-import com.sun.hotspot.igv.svg.BatikSVG;
-import java.awt.BorderLayout;
-import java.awt.CardLayout;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Graphics2D;
-import java.awt.Point;
+import com.sun.hotspot.igv.view.actions.*;
+import java.awt.*;
 import java.awt.event.HierarchyBoundsListener;
 import java.awt.event.HierarchyEvent;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.HashSet;
+import java.io.*;
 import java.util.List;
-import java.util.Set;
-import javax.swing.Action;
-import javax.swing.ActionMap;
-import javax.swing.JPanel;
-import javax.swing.JToggleButton;
-import javax.swing.SwingUtilities;
-import javax.swing.UIManager;
+import java.util.*;
+import javax.swing.*;
 import javax.swing.border.Border;
 import org.openide.DialogDisplayer;
-import org.openide.actions.FindAction;
+import org.openide.NotifyDescriptor;
 import org.openide.actions.RedoAction;
 import org.openide.actions.UndoAction;
 import org.openide.awt.Toolbar;
@@ -86,30 +59,30 @@
 import org.openide.awt.UndoRedo;
 import org.openide.util.Lookup;
 import org.openide.util.NbBundle;
-import org.openide.util.actions.CallbackSystemAction;
-import org.openide.util.actions.SystemAction;
+import org.openide.util.Utilities;
+import org.openide.util.actions.Presenter;
 import org.openide.util.lookup.AbstractLookup;
 import org.openide.util.lookup.InstanceContent;
 import org.openide.util.lookup.ProxyLookup;
 import org.openide.windows.Mode;
 import org.openide.windows.TopComponent;
 import org.openide.windows.WindowManager;
-import org.openide.NotifyDescriptor;
 
 /**
- *
+ * 
  * @author Thomas Wuerthinger
  */
-public final class EditorTopComponent extends TopComponent implements ChangedListener<RangeSliderModel>, PropertyChangeListener {
+public final class EditorTopComponent extends TopComponent implements PropertyChangeListener {
 
-    private DiagramScene scene;
+    private DiagramViewer scene;
     private InstanceContent content;
-    private FindPanel findPanel;
-    private EnableBlockLayoutAction blockLayoutAction;
+    private InstanceContent graphContent;
     private OverviewAction overviewAction;
     private PredSuccAction predSuccAction;
+    private SelectionModeAction selectionModeAction;
+    private PanModeAction panModeAction;
     private boolean notFirstTime;
-    private ExtendedSatelliteComponent satelliteComponent;
+    private JComponent satelliteComponent;
     private JPanel centerPanel;
     private CardLayout cardLayout;
     private RangeSlider rangeSlider;
@@ -120,6 +93,7 @@
     private DiagramViewModel rangeSliderModel;
     private ExportCookie exportCookie = new ExportCookie() {
 
+        @Override
         public void export(File f) {
 
             Graphics2D svgGenerator = BatikSVG.createGraphicsObject();
@@ -152,12 +126,31 @@
         }
     };
 
+    private DiagramProvider diagramProvider = new DiagramProvider() {
+
+        @Override
+        public Diagram getDiagram() {
+            return getModel().getDiagramToView();
+        }
+
+        @Override
+        public ChangedEvent<DiagramProvider> getChangedEvent() {
+            return diagramChangedEvent;
+        }
+    };
+
+    private ChangedEvent<DiagramProvider> diagramChangedEvent = new ChangedEvent<>(diagramProvider);
+    
+
     private void updateDisplayName() {
         setDisplayName(getDiagram().getName());
     }
 
     public EditorTopComponent(Diagram diagram) {
 
+        LookupHistory.init(InputGraphProvider.class);
+        LookupHistory.init(DiagramProvider.class);
+        this.setFocusable(true);
         FilterChain filterChain = null;
         FilterChain sequence = null;
         FilterChainProvider provider = Lookup.getDefault().lookup(FilterChainProvider.class);
@@ -190,8 +183,6 @@
 
         initComponents();
 
-        ActionMap actionMap = getActionMap();
-
         ToolbarPool.getDefault().setPreferredIconSize(16);
         Toolbar toolBar = new Toolbar();
         Border b = (Border) UIManager.get("Nb.Editor.Toolbar.border"); //NOI18N
@@ -202,24 +193,21 @@
         container.add(BorderLayout.NORTH, toolBar);
 
         rangeSliderModel = new DiagramViewModel(diagram.getGraph().getGroup(), filterChain, sequence);
-        rangeSliderModel.selectGraph(diagram.getGraph());
         rangeSlider = new RangeSlider();
         rangeSlider.setModel(rangeSliderModel);
-        rangeSliderModel.getChangedEvent().addListener(this);
         container.add(BorderLayout.CENTER, rangeSlider);
 
         scene = new DiagramScene(actions, rangeSliderModel);
         content = new InstanceContent();
-        this.associateLookup(new ProxyLookup(new Lookup[]{scene.getLookup(), new AbstractLookup(content)}));
+        graphContent = new InstanceContent();
+        this.associateLookup(new ProxyLookup(new Lookup[]{scene.getLookup(), new AbstractLookup(graphContent), new AbstractLookup(content)}));
         content.add(exportCookie);
         content.add(rangeSliderModel);
-
+        content.add(diagramProvider);
 
-        findPanel = new FindPanel(diagram.getFigures());
-        findPanel.setMaximumSize(new Dimension(200, 50));
-        toolBar.add(findPanel);
-        toolBar.add(NodeFindAction.get(NodeFindAction.class));
-        toolBar.addSeparator();
+        rangeSliderModel.getDiagramChangedEvent().addListener(diagramChangedListener);
+        rangeSliderModel.selectGraph(diagram.getGraph());
+
         toolBar.add(NextDiagramAction.get(NextDiagramAction.class));
         toolBar.add(PrevDiagramAction.get(PrevDiagramAction.class));
         toolBar.addSeparator();
@@ -230,12 +218,6 @@
         toolBar.add(ShowAllAction.get(ZoomInAction.class));
         toolBar.add(ShowAllAction.get(ZoomOutAction.class));
 
-        blockLayoutAction = new EnableBlockLayoutAction();
-        JToggleButton button = new JToggleButton(blockLayoutAction);
-        button.setSelected(true);
-        toolBar.add(button);
-        blockLayoutAction.addPropertyChangeListener(this);
-
         overviewAction = new OverviewAction();
         overviewButton = new JToggleButton(overviewAction);
         overviewButton.setSelected(false);
@@ -243,7 +225,7 @@
         overviewAction.addPropertyChangeListener(this);
 
         predSuccAction = new PredSuccAction();
-        button = new JToggleButton(predSuccAction);
+        JToggleButton button = new JToggleButton(predSuccAction);
         button.setSelected(true);
         toolBar.add(button);
         predSuccAction.addPropertyChangeListener(this);
@@ -252,55 +234,76 @@
         toolBar.add(UndoAction.get(UndoAction.class));
         toolBar.add(RedoAction.get(RedoAction.class));
 
+        toolBar.addSeparator();
+        ButtonGroup interactionButtons = new ButtonGroup();
+
+        panModeAction = new PanModeAction();
+        panModeAction.setSelected(true);
+        button = new JToggleButton(panModeAction);
+        button.setSelected(true);
+        interactionButtons.add(button);
+        toolBar.add(button);
+        panModeAction.addPropertyChangeListener(this);
+
+        selectionModeAction = new SelectionModeAction();
+        button = new JToggleButton(selectionModeAction);
+        interactionButtons.add(button);
+        toolBar.add(button);
+        selectionModeAction.addPropertyChangeListener(this);
+
+        toolBar.add(Box.createHorizontalGlue());
+        Action action = Utilities.actionsForPath("QuickSearchShadow").get(0);
+        Component quicksearch = ((Presenter.Toolbar) action).getToolbarPresenter();
+        quicksearch.setMinimumSize(quicksearch.getPreferredSize()); // necessary for GTK LAF
+        toolBar.add(quicksearch);
+
         centerPanel = new JPanel();
         this.add(centerPanel, BorderLayout.CENTER);
         cardLayout = new CardLayout();
         centerPanel.setLayout(cardLayout);
-        centerPanel.add(SCENE_STRING, scene.getScrollPane());
+        centerPanel.add(SCENE_STRING, scene.getComponent());
         centerPanel.setBackground(Color.WHITE);
-        satelliteComponent = new ExtendedSatelliteComponent(scene);
+        satelliteComponent = scene.createSatelliteView();
         satelliteComponent.setSize(200, 200);
         centerPanel.add(SATELLITE_STRING, satelliteComponent);
 
-        CallbackSystemAction callFindAction = (CallbackSystemAction) SystemAction.get(FindAction.class);
-        NodeFindAction findAction = NodeFindAction.get(NodeFindAction.class);
-        Object key = callFindAction.getActionMapKey();
-        actionMap.put(key, findAction);
+        // TODO: Fix the hot key for entering the satellite view
+        this.addKeyListener(keyListener);
 
-        scene.getScrollPane().addKeyListener(keyListener);
-        scene.getView().addKeyListener(keyListener);
-        satelliteComponent.addKeyListener(keyListener);
+        scene.getComponent().addHierarchyBoundsListener(new HierarchyBoundsListener() {
 
-        scene.getScrollPane().addHierarchyBoundsListener(new HierarchyBoundsListener() {
-
+            @Override
             public void ancestorMoved(HierarchyEvent e) {
             }
 
+            @Override
             public void ancestorResized(HierarchyEvent e) {
-                if (!notFirstTime && scene.getScrollPane().getBounds().width > 0) {
+                if (!notFirstTime && scene.getComponent().getBounds().width > 0) {
                     notFirstTime = true;
                     SwingUtilities.invokeLater(new Runnable() {
 
+                        @Override
                         public void run() {
-                            Figure f = EditorTopComponent.this.scene.getModel().getDiagramToView().getRootFigure();
-                            if (f != null) {
-                                scene.setUndoRedoEnabled(false);
-                                scene.gotoFigure(f);
-                                scene.setUndoRedoEnabled(true);
-                            }
+                            EditorTopComponent.this.scene.initialize();
                         }
                     });
                 }
             }
         });
 
+        if (diagram.getGraph().getGroup().getGraphsCount() == 1) {
+            rangeSlider.setVisible(false);
+        }
+
         updateDisplayName();
     }
     private KeyListener keyListener = new KeyListener() {
 
+        @Override
         public void keyTyped(KeyEvent e) {
         }
 
+        @Override
         public void keyPressed(KeyEvent e) {
             if (e.getKeyCode() == KeyEvent.VK_S) {
                 EditorTopComponent.this.overviewButton.setSelected(true);
@@ -308,6 +311,7 @@
             }
         }
 
+        @Override
         public void keyReleased(KeyEvent e) {
             if (e.getKeyCode() == KeyEvent.VK_S) {
                 EditorTopComponent.this.overviewButton.setSelected(false);
@@ -317,7 +321,7 @@
     };
 
     public DiagramViewModel getDiagramModel() {
-        return scene.getModel();
+        return rangeSliderModel;
     }
 
     private void showSatellite() {
@@ -328,35 +332,15 @@
 
     private void showScene() {
         cardLayout.show(centerPanel, SCENE_STRING);
-        scene.getView().requestFocus();
-    }
-
-    public void findNode() {
-        findPanel.find();
+        scene.getComponent().requestFocus();
     }
 
     public void zoomOut() {
-        double zoom = scene.getZoomFactor();
-        Point viewPosition = scene.getScrollPane().getViewport().getViewPosition();
-        double newZoom = zoom / DiagramScene.ZOOM_INCREMENT;
-        if (newZoom > DiagramScene.ZOOM_MIN_FACTOR) {
-            scene.setZoomFactor(newZoom);
-            scene.validate();
-            scene.getScrollPane().getViewport().setViewPosition(new Point((int) (viewPosition.x / DiagramScene.ZOOM_INCREMENT), (int) (viewPosition.y / DiagramScene.ZOOM_INCREMENT)));
-            this.satelliteComponent.update();
-        }
+        scene.zoomOut();
     }
 
     public void zoomIn() {
-        double zoom = scene.getZoomFactor();
-        Point viewPosition = scene.getScrollPane().getViewport().getViewPosition();
-        double newZoom = zoom * DiagramScene.ZOOM_INCREMENT;
-        if (newZoom < DiagramScene.ZOOM_MAX_FACTOR) {
-            scene.setZoomFactor(newZoom);
-            scene.validate();
-            scene.getScrollPane().getViewport().setViewPosition(new Point((int) (viewPosition.x * DiagramScene.ZOOM_INCREMENT), (int) (viewPosition.y * DiagramScene.ZOOM_INCREMENT)));
-            this.satelliteComponent.update();
-        }
+        scene.zoomIn();
     }
 
     public void showPrevDiagram() {
@@ -370,11 +354,11 @@
     }
 
     public DiagramViewModel getModel() {
-        return scene.getModel();
+        return rangeSliderModel;
     }
 
     public FilterChain getFilterChain() {
-        return this.scene.getModel().getFilterChain();
+        return getModel().getFilterChain();
     }
 
     public static EditorTopComponent getActive() {
@@ -407,6 +391,7 @@
         // Variables declaration - do not modify//GEN-BEGIN:variables
         private javax.swing.JCheckBox jCheckBox1;
         // End of variables declaration//GEN-END:variables
+
     @Override
     public int getPersistenceType() {
         return TopComponent.PERSISTENCE_NEVER;
@@ -425,9 +410,18 @@
         return PREFERRED_ID;
     }
 
-    public void changed(RangeSliderModel model) {
-        updateDisplayName();
-    }
+    private ChangedListener<DiagramViewModel> diagramChangedListener = new ChangedListener<DiagramViewModel>() {
+
+        @Override
+        public void changed(DiagramViewModel source) {
+            updateDisplayName();
+            Collection<Object> list = new ArrayList<>();
+            list.add(new EditorInputGraphProvider(EditorTopComponent.this));
+            graphContent.set(list, null);
+            diagramProvider.getChangedEvent().fire();
+        }
+        
+    };
 
     public boolean showPredSucc() {
         return (Boolean) predSuccAction.getValue(PredSuccAction.STATE);
@@ -435,24 +429,25 @@
 
     public void setSelection(PropertyMatcher matcher) {
 
-        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(scene.getModel().getDiagramToView().getFigures());
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(getModel().getDiagramToView().getFigures());
         List<Figure> list = selector.selectMultiple(matcher);
-        boolean b = scene.getUndoRedoEnabled();
-        scene.setUndoRedoEnabled(false);
-        scene.gotoFigures(list);
-        scene.setUndoRedoEnabled(b);
+        setSelectedFigures(list);
+    }
+
+    public void setSelectedFigures(List<Figure> list) {
         scene.setSelection(list);
+        scene.centerFigures(list);
     }
 
     public void setSelectedNodes(Set<InputNode> nodes) {
 
-        List<Figure> list = new ArrayList<Figure>();
-        Set<Integer> ids = new HashSet<Integer>();
+        List<Figure> list = new ArrayList<>();
+        Set<Integer> ids = new HashSet<>();
         for (InputNode n : nodes) {
             ids.add(n.getId());
         }
 
-        for (Figure f : scene.getModel().getDiagramToView().getFigures()) {
+        for (Figure f : getModel().getDiagramToView().getFigures()) {
             for (InputNode n : f.getSource().getSourceNodes()) {
                 if (ids.contains(n.getId())) {
                     list.add(f);
@@ -461,10 +456,10 @@
             }
         }
 
-        scene.gotoFigures(list);
-        scene.setSelection(list);
+        setSelectedFigures(list);
     }
 
+    @Override
     public void propertyChange(PropertyChangeEvent evt) {
         if (evt.getSource() == this.predSuccAction) {
             boolean b = (Boolean) predSuccAction.getValue(PredSuccAction.STATE);
@@ -476,29 +471,31 @@
             } else {
                 showScene();
             }
-        } else if (evt.getSource() == this.blockLayoutAction) {
-            boolean b = (Boolean) blockLayoutAction.getValue(EnableBlockLayoutAction.STATE);
-            System.out.println("Showblocks = " + b);
-            this.getModel().setShowBlocks(b);
+        } else if (evt.getSource() == this.selectionModeAction || evt.getSource() == this.panModeAction) {
+            if (panModeAction.isSelected()) {
+                scene.setInteractionMode(DiagramViewer.InteractionMode.PANNING);
+            } else if (selectionModeAction.isSelected()) {
+                scene.setInteractionMode(DiagramViewer.InteractionMode.SELECTION);
+            }
         } else {
             assert false : "Unknown event source";
         }
     }
 
     public void extract() {
-        scene.showOnly(scene.getSelectedNodes());
+        getModel().showOnly(getModel().getSelectedNodes());
     }
 
     public void hideNodes() {
-        Set<Integer> selectedNodes = this.scene.getSelectedNodes();
-        HashSet<Integer> nodes = new HashSet<Integer>(scene.getModel().getHiddenNodes());
+        Set<Integer> selectedNodes = this.getModel().getSelectedNodes();
+        HashSet<Integer> nodes = new HashSet<>(getModel().getHiddenNodes());
         nodes.addAll(selectedNodes);
-        this.scene.showNot(nodes);
+        this.getModel().showNot(nodes);
     }
 
     public void expandPredecessors() {
-        Set<Figure> oldSelection = scene.getSelectedFigures();
-        Set<Figure> figures = new HashSet<Figure>();
+        Set<Figure> oldSelection = getModel().getSelectedFigures();
+        Set<Figure> figures = new HashSet<>();
 
         for (Figure f : this.getDiagramModel().getDiagramToView().getFigures()) {
             boolean ok = false;
@@ -518,12 +515,12 @@
             }
         }
 
-        scene.showAll(figures);
+        getModel().showAll(figures);
     }
 
     public void expandSuccessors() {
-        Set<Figure> oldSelection = scene.getSelectedFigures();
-        Set<Figure> figures = new HashSet<Figure>();
+        Set<Figure> oldSelection = getModel().getSelectedFigures();
+        Set<Figure> figures = new HashSet<>();
 
         for (Figure f : this.getDiagramModel().getDiagramToView().getFigures()) {
             boolean ok = false;
@@ -543,11 +540,11 @@
             }
         }
 
-        scene.showAll(figures);
+        getModel().showAll(figures);
     }
 
     public void showAll() {
-        scene.showNot(new HashSet<Integer>());
+        getModel().showNot(new HashSet<Integer>());
     }
 
     public Diagram getDiagram() {
@@ -555,23 +552,27 @@
     }
 
     @Override
-    protected void componentActivated() {
+    protected void componentHidden() {
+        super.componentHidden();
+        scene.componentHidden();
+
     }
 
     @Override
-    public void requestFocus() {
-        super.requestFocus();
-        scene.getView().requestFocus();
+    protected void componentShowing() {
+        super.componentShowing();
+        scene.componentShowing();
     }
 
     @Override
-    public boolean requestFocusInWindow() {
-        super.requestFocusInWindow();
-        return scene.getView().requestFocusInWindow();
+    public void requestActive() {
+        super.requestActive();
+        scene.getComponent().requestFocus();
     }
 
     @Override
     public UndoRedo getUndoRedo() {
         return scene.getUndoRedo();
     }
+
 }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExtendedPanAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.view;
-
-import java.awt.Container;
-import java.awt.Dimension;
-import java.awt.Point;
-import org.netbeans.api.visual.widget.Scene;
-import org.netbeans.api.visual.widget.Widget;
-import org.netbeans.api.visual.action.WidgetAction;
-
-import java.awt.event.MouseEvent;
-import javax.swing.JComponent;
-import javax.swing.JScrollPane;
-import javax.swing.SwingUtilities;
-
-/**
- * @author David Kaspar
- * @author Thomas Wuerthinger
- */
-public class ExtendedPanAction extends WidgetAction.LockedAdapter {
-
-    private Scene scene;
-    private JScrollPane scrollPane;
-    private Point lastLocation;
-
-    protected boolean isLocked() {
-        return scrollPane != null;
-    }
-
-    @Override
-    public State mousePressed(Widget widget, WidgetMouseEvent event) {
-        if (event.getButton() == MouseEvent.BUTTON2 || event.getButton() == MouseEvent.BUTTON1 && ((event.getModifiers() & MouseEvent.CTRL_MASK) != 0)) {
-            scene = widget.getScene();
-            scrollPane = findScrollPane(scene.getView());
-            if (scrollPane != null) {
-                lastLocation = scene.convertSceneToView(widget.convertLocalToScene(event.getPoint()));
-                SwingUtilities.convertPointToScreen(lastLocation, scrollPane.getViewport().getView());
-                return State.createLocked(widget, this);
-            }
-        }
-        return State.REJECTED;
-    }
-
-    private JScrollPane findScrollPane(JComponent component) {
-        for (;;) {
-            if (component == null) {
-                return null;
-            }
-            if (component instanceof JScrollPane) {
-                return ((JScrollPane) component);
-            }
-            Container parent = component.getParent();
-            if (!(parent instanceof JComponent)) {
-                return null;
-            }
-            component = (JComponent) parent;
-        }
-    }
-
-    @Override
-    public State mouseReleased(Widget widget, WidgetMouseEvent event) {
-        boolean state = pan(widget, event.getPoint());
-        if (state) {
-            scrollPane = null;
-        }
-        return state ? State.createLocked(widget, this) : State.REJECTED;
-    }
-
-    @Override
-    public State mouseDragged(Widget widget, WidgetMouseEvent event) {
-        return pan(widget, event.getPoint()) ? State.createLocked(widget, this) : State.REJECTED;
-    }
-
-    private boolean pan(Widget widget, Point newLocation) {
-        if (scrollPane == null || scene != widget.getScene()) {
-            return false;
-        }
-        newLocation = scene.convertSceneToView(widget.convertLocalToScene(newLocation));
-        SwingUtilities.convertPointToScreen(newLocation, scrollPane.getViewport().getView());
-        Point viewPosition = scrollPane.getViewport().getViewPosition();
-        Dimension viewSize = scrollPane.getViewport().getViewSize();
-        Dimension viewPortSize = scrollPane.getViewport().getSize();
-
-        int xOffset = lastLocation.x - newLocation.x;
-        int yOffset = lastLocation.y - newLocation.y;
-
-        if (viewPortSize.height == viewSize.height) {
-            yOffset = 0;
-        }
-
-        if (viewPortSize.width == viewSize.width) {
-            xOffset = 0;
-        }
-
-        if (xOffset == 0 && yOffset == 0) {
-            return true;
-        }
-        viewPosition = new Point(viewPosition.x + xOffset, viewPosition.y + yOffset);
-        viewPosition.x = Math.max(viewPosition.x, 0);
-        viewPosition.y = Math.max(viewPosition.y, 0);
-        viewPosition.x = Math.min(viewPosition.x, scrollPane.getViewport().getView().getSize().width - scrollPane.getViewport().getSize().width);
-        viewPosition.y = Math.min(viewPosition.y, scrollPane.getViewport().getView().getSize().height - scrollPane.getViewport().getSize().height);
-
-        scrollPane.getViewport().setViewPosition(viewPosition);
-        scrollPane.getViewport().getView().repaint();
-        lastLocation = newLocation;
-        return true;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExtendedSatelliteComponent.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExtendedSatelliteComponent.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,11 +23,10 @@
  */
 package com.sun.hotspot.igv.view;
 
-import org.netbeans.api.visual.widget.Scene;
-
-import javax.swing.*;
 import java.awt.*;
 import java.awt.event.*;
+import javax.swing.JComponent;
+import org.netbeans.api.visual.widget.Scene;
 
 /**
  * @author David Kaspar
@@ -48,6 +47,7 @@
         addMouseMotionListener(this);
     }
 
+    @Override
     public void addNotify() {
         super.addNotify();
         scene.addSceneListener(this);
@@ -59,6 +59,7 @@
         repaint();
     }
 
+    @Override
     public void removeNotify() {
         scene.getView().removeComponentListener(this);
         scene.removeSceneListener(this);
@@ -74,6 +75,7 @@
         }
     }
 
+    @Override
     public void paint(Graphics g) {
         Graphics2D gr = (Graphics2D) g;
         super.paint(g);
@@ -97,9 +99,10 @@
             image = this.createImage(imageWidth, imageHeight);
             Graphics2D ig = (Graphics2D) image.getGraphics();
             ig.scale(scale, scale);
-            scene.setRealZoomFactor(scale);
+	    double oldFactor = scene.getZoomFactor();
+	    scene.setZoomFactor(scale);
             scene.paint(ig);
-            scene.setRealZoomFactor(0.0);
+	    scene.setZoomFactor(oldFactor);
         }
 
         gr.drawImage(image, vx, vy, this);
@@ -121,27 +124,34 @@
         }
     }
 
+    @Override
     public void mouseClicked(MouseEvent e) {
     }
 
+    @Override
     public void mousePressed(MouseEvent e) {
         moveVisibleRect(e.getPoint());
     }
 
+    @Override
     public void mouseReleased(MouseEvent e) {
         moveVisibleRect(e.getPoint());
     }
 
+    @Override
     public void mouseEntered(MouseEvent e) {
     }
 
+    @Override
     public void mouseExited(MouseEvent e) {
     }
 
+    @Override
     public void mouseDragged(MouseEvent e) {
         moveVisibleRect(e.getPoint());
     }
 
+    @Override
     public void mouseMoved(MouseEvent e) {
     }
 
@@ -174,27 +184,34 @@
         this.repaint();
     }
 
+    @Override
     public void sceneRepaint() {
     //repaint ();
     }
 
+    @Override
     public void sceneValidating() {
     }
 
+    @Override
     public void sceneValidated() {
     }
 
+    @Override
     public void componentResized(ComponentEvent e) {
         repaint();
     }
 
+    @Override
     public void componentMoved(ComponentEvent e) {
         repaint();
     }
 
+    @Override
     public void componentShown(ComponentEvent e) {
     }
 
+    @Override
     public void componentHidden(ComponentEvent e) {
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/FindPanel.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.view;
-
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.data.Properties;
-import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher;
-import com.sun.hotspot.igv.data.Property;
-import java.awt.GridLayout;
-import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
-import java.util.List;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import javax.swing.JComboBox;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-class FindPanel extends JPanel implements KeyListener {
-
-    private JComboBox nameComboBox;
-    private JTextField valueTextField;
-
-    public FindPanel(List<Figure> figures) {
-        createDesign();
-        updateComboBox(figures);
-    }
-
-    protected void createDesign() {
-        setLayout(new GridLayout());
-        nameComboBox = new JComboBox();
-        valueTextField = new JTextField();
-        add(nameComboBox);
-        add(valueTextField);
-        valueTextField.addKeyListener(this);
-    }
-
-    public void updateComboBox(List<Figure> figures) {
-
-        String sel = (String) nameComboBox.getSelectedItem();
-        SortedSet<String> propertyNames = new TreeSet<String>();
-
-        for (Figure f : figures) {
-            Properties prop = f.getProperties();
-            for (Property p : prop) {
-                if (!propertyNames.contains(p.getName())) {
-                    propertyNames.add(p.getName());
-                }
-            }
-        }
-
-        for (String s : propertyNames) {
-            nameComboBox.addItem(s);
-        }
-        nameComboBox.setSelectedItem(sel);
-    }
-
-    public String getNameText() {
-        return (String) nameComboBox.getSelectedItem();
-    }
-
-    public String getValueText() {
-        return valueTextField.getText();
-    }
-
-    public void keyTyped(KeyEvent e) {
-    }
-
-    public void keyPressed(KeyEvent e) {
-        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
-            find();
-        }
-    }
-
-    public void find() {
-        EditorTopComponent comp = EditorTopComponent.getActive();
-        if (comp != null) {
-            RegexpPropertyMatcher matcher = new RegexpPropertyMatcher(getNameText(), getValueText());
-            comp.setSelection(matcher);
-        }
-    }
-
-    public void keyReleased(KeyEvent e) {
-
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/GraphViewerImplementation.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/GraphViewerImplementation.java	Mon Feb 27 13:10:13 2012 +0100
@@ -34,6 +34,7 @@
  */
 public class GraphViewerImplementation implements GraphViewer {
 
+    @Override
     public void view(InputGraph graph) {
         Diagram diagram = Diagram.createDiagram(graph, Settings.get().get(Settings.NODE_TEXT, Settings.NODE_TEXT_DEFAULT));
         EditorTopComponent tc = new EditorTopComponent(diagram);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/NodeQuickSearch.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.view;
+
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher;
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import com.sun.hotspot.igv.util.LookupHistory;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+import org.netbeans.spi.quicksearch.SearchProvider;
+import org.netbeans.spi.quicksearch.SearchRequest;
+import org.netbeans.spi.quicksearch.SearchResponse;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.NotifyDescriptor.Message;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class NodeQuickSearch implements SearchProvider {
+
+    private static final String DEFAULT_PROPERTY = "name";
+
+    /**
+     * Method is called by infrastructure when search operation was requested.
+     * Implementors should evaluate given request and fill response object with
+     * apropriate results
+     *
+     * @param request Search request object that contains information what to search for
+     * @param response Search response object that stores search results. Note that it's important to react to return value of SearchResponse.addResult(...) method and stop computation if false value is returned.
+     */
+    @Override
+    public void evaluate(SearchRequest request, SearchResponse response) {
+        String query = request.getText();
+        if (query.trim().isEmpty()) {
+            return;
+        }
+
+        final String[] parts = query.split("=", 2);
+
+        String name;
+        String value;
+
+        if (parts.length == 1) {
+            name = DEFAULT_PROPERTY;
+            value = ".*" + Pattern.quote(parts[0]) + ".*";
+        } else {
+            name = parts[0];
+            value = parts[1];
+        }
+
+        if (value.isEmpty()) {
+            value = ".*";
+        }
+
+        final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);
+        if (p != null && p.getGraph() != null) {
+            List<InputNode> matches = null;
+            try {
+                RegexpPropertyMatcher matcher = new RegexpPropertyMatcher(name, value, Pattern.CASE_INSENSITIVE);
+                Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<>(p.getGraph().getNodes());
+
+                matches = selector.selectMultiple(matcher);
+            } catch (Exception e) {
+                final String msg = e.getMessage();
+                response.addResult(new Runnable() {
+                    @Override
+                        public void run() {
+                            Message desc = new NotifyDescriptor.Message("An exception occurred during the search, "
+                                    + "perhaps due to a malformed query string:\n" + msg,
+                                    NotifyDescriptor.WARNING_MESSAGE);
+                            DialogDisplayer.getDefault().notify(desc);
+                        }
+                    },
+                    "(Error during search)"
+                );
+            }
+
+            if (matches != null) {
+                final Set<InputNode> set = new HashSet<>(matches);
+                response.addResult(new Runnable() {
+                    @Override
+                        public void run() {
+                            final EditorTopComponent comp = EditorTopComponent.getActive();
+                            if (comp != null) {
+                                comp.setSelectedNodes(set);
+                                comp.requestActive();
+                            }
+                        }
+                    },
+                    "All " + matches.size() + " matching nodes (" + name + "=" + value + ")"
+                );
+
+                // Single matches
+                for (final InputNode n : matches) {
+                    response.addResult(new Runnable() {
+                        @Override
+                            public void run() {
+                                final EditorTopComponent comp = EditorTopComponent.getActive();
+                                if (comp != null) {
+                                    final Set<InputNode> tmpSet = new HashSet<>();
+                                    tmpSet.add(n);
+                                    comp.setSelectedNodes(tmpSet);
+                                    comp.requestActive();
+                                }
+                            }
+                        },
+                        n.getProperties().get(name) + " (" + n.getId() + " " + n.getProperties().get("name") + ")"
+                    );
+                }
+            }
+        } else {
+            System.out.println("no input graph provider!");
+        }
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/PreferenceConstants.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.view;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class PreferenceConstants {
-
-    public static final String KEY_LINE_GENERATOR = "lineGenerator";
-    public static final String DEFAULT_LINE_GENERATOR = "com.sun.hotspot.igv.positioning.BasicLineGenerator";
-}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/SlotLayout.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,171 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.view;
-
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.util.Collection;
-import java.util.List;
-import org.netbeans.api.visual.layout.Layout;
-import org.netbeans.api.visual.layout.LayoutFactory;
-import org.netbeans.api.visual.widget.Widget;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class SlotLayout implements Layout {
-
-    public enum HorizontalAlignment {
-
-        Left,
-        Center,
-        Right
-    }
-    private Layout baseLayout;
-    private HorizontalAlignment alignment;
-    private boolean vertical;
-
-    public SlotLayout() {
-        this(HorizontalAlignment.Center, false);
-    }
-
-    public SlotLayout(HorizontalAlignment alignment, boolean vertical) {
-        this.alignment = alignment;
-        baseLayout = LayoutFactory.createVerticalFlowLayout();
-        this.vertical = vertical;
-    }
-
-    public void layout(Widget widget) {
-        if (!vertical) {
-            Collection<Widget> children = widget.getChildren();
-            int gap = 0;
-            int max = 0;
-            for (Widget child : children) {
-                Rectangle preferredBounds = child.getPreferredBounds();
-                int i = preferredBounds.width;
-                if (i > max) {
-                    max = i;
-                }
-            }
-            int pos = 0;
-            for (Widget child : children) {
-                Rectangle preferredBounds = child.getPreferredBounds();
-                int x = preferredBounds.x;
-                int y = preferredBounds.y;
-                int width = preferredBounds.width;
-                int height = preferredBounds.height;
-                if (pos == 0) {
-                    pos += height / 2;
-                }
-                int lx = -x;
-                int ly = pos - y;
-                switch (alignment) {
-                    case Center:
-                        lx += (max - width) / 2;
-                        break;
-                    case Left:
-                        break;
-                    case Right:
-                        lx += max - width;
-                        break;
-                }
-                child.resolveBounds(new Point(lx, ly), new Rectangle(x, y, width, height));
-                pos += height + gap;
-            }
-        } else {
-
-            Collection<Widget> children = widget.getChildren();
-            int gap = 0;
-            int max = 0;
-            for (Widget child : children) {
-                Rectangle preferredBounds = child.getPreferredBounds();
-                int i = preferredBounds.height;
-                if (i > max) {
-                    max = i;
-                }
-            }
-            int pos = 0;
-            for (Widget child : children) {
-                Rectangle preferredBounds = child.getPreferredBounds();
-                int x = preferredBounds.x;
-                int y = preferredBounds.y;
-                int width = preferredBounds.width;
-                int height = preferredBounds.height;
-                if (pos == 0) {
-                    pos += width / 2;
-                }
-                int lx = pos - x;
-                int ly = -y;
-                switch (alignment) {
-                    case Center:
-                        ly += (max - height) / 2;
-                        break;
-                    case Left:
-                        break;
-                    case Right:
-                        ly += max - height;
-                        break;
-                }
-                child.resolveBounds(new Point(lx, ly), new Rectangle(x, y, width, height));
-                pos += width + gap;
-            }
-
-        }
-    }
-
-    public boolean requiresJustification(Widget widget) {
-        return true;
-    }
-
-    public void justify(Widget widget) {
-        baseLayout.justify(widget);
-
-        Rectangle client = widget.getClientArea();
-        List<Widget> children = widget.getChildren();
-
-        int count = children.size();
-        int z = 0;
-
-        int maxWidth = 0;
-        for (Widget c : children) {
-            if (c.getPreferredBounds().width > maxWidth) {
-                maxWidth = c.getPreferredBounds().width;
-            }
-        }
-
-        for (Widget c : children) {
-            z++;
-            Point curLocation = c.getLocation();
-            Rectangle curBounds = c.getBounds();
-
-
-            Point location = new Point(curLocation.x, client.y + client.height * z / (count + 1) - curBounds.height / 2);
-            if (vertical) {
-                location = new Point(client.x + client.width * z / (count + 1) - maxWidth / 2, curLocation.y);
-            }
-            c.resolveBounds(location, null);
-        }
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/Bundle.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,7 +1,6 @@
 CTL_EditorAction=Open Editor Window
-CTL_LineGeneratorAction=Line Generator
 CTL_NextDiagramAction=Show next graph
 CTL_EnableBlockLayoutAction=Enable block layout
 CTL_NodeFindAction=Find
 CTL_PrevDiagramAction=Show previous graph
-CTL_ExportAction=Export...
+CTL_ExportAction=Export current graph...
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/CustomizablePanAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,146 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package com.sun.hotspot.igv.view.actions;
+
+import java.awt.Container;
+import java.awt.Point;
+import java.awt.Rectangle;
+import javax.swing.JComponent;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.action.WidgetAction.State;
+import org.netbeans.api.visual.action.WidgetAction.WidgetMouseEvent;
+import org.netbeans.api.visual.widget.Scene;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ * @author David Kaspar
+ * @author Peter Hofer
+ */
+public class CustomizablePanAction extends WidgetAction.LockedAdapter {
+    private boolean enabled = true;
+    
+    private Scene scene;
+    private JScrollPane scrollPane;
+    private Point lastLocation;
+    
+    private final int modifiersExMask;
+    private final int modifiersEx;
+
+    public CustomizablePanAction(int modifiersExMask, int modifiersEx) {
+        this.modifiersExMask = modifiersExMask;
+        this.modifiersEx = modifiersEx;
+    }
+
+    @Override
+    protected boolean isLocked() {
+        return scrollPane != null;
+    }
+    
+    public void setEnabled(boolean enabled) {
+        if (this.enabled != enabled) {
+            if (isLocked())
+                throw new IllegalStateException();
+            
+            this.enabled = enabled;
+        }
+    }
+
+    @Override
+    public State mousePressed (Widget widget, WidgetMouseEvent event) {
+        if (isLocked ())
+            return State.createLocked (widget, this);
+        if (enabled && (event.getModifiersEx() & modifiersExMask) == modifiersEx) {
+            scene = widget.getScene ();
+            scrollPane = findScrollPane (scene.getView ());
+            if (scrollPane != null) {
+                lastLocation = scene.convertSceneToView (widget.convertLocalToScene (event.getPoint ()));
+                SwingUtilities.convertPointToScreen (lastLocation, scene.getView ());
+                return State.createLocked (widget, this);
+            }
+        }
+        return State.REJECTED;
+    }
+
+    private JScrollPane findScrollPane (JComponent component) {
+        for (;;) {
+            if (component == null)
+                return null;
+            if (component instanceof JScrollPane)
+                return ((JScrollPane) component);
+            Container parent = component.getParent ();
+            if (! (parent instanceof JComponent))
+                return null;
+            component = (JComponent) parent;
+        }
+    }
+
+    @Override
+    public State mouseReleased (Widget widget, WidgetMouseEvent event) {
+        boolean state = pan (widget, event.getPoint ());
+        if (state)
+            scrollPane = null;
+        return state ? State.createLocked (widget, this) : State.REJECTED;
+    }
+
+    @Override
+    public State mouseDragged (Widget widget, WidgetMouseEvent event) {
+        return pan (widget, event.getPoint ()) ? State.createLocked (widget, this) : State.REJECTED;
+    }
+
+    private boolean pan (Widget widget, Point newLocation) {
+        if (scrollPane == null  ||  scene != widget.getScene ())
+            return false;
+        newLocation = scene.convertSceneToView (widget.convertLocalToScene (newLocation));
+        SwingUtilities.convertPointToScreen (newLocation, scene.getView ());
+        JComponent view = scene.getView ();
+        Rectangle rectangle = view.getVisibleRect ();
+        rectangle.x += lastLocation.x - newLocation.x;
+        rectangle.y += lastLocation.y - newLocation.y;
+        view.scrollRectToVisible (rectangle);
+        lastLocation = newLocation;
+        return true;
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/EnableBlockLayoutAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.view.actions;
-
-import java.awt.event.ActionEvent;
-import javax.swing.AbstractAction;
-import javax.swing.Action;
-import javax.swing.ImageIcon;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class EnableBlockLayoutAction extends AbstractAction {
-
-    private boolean state;
-    public static final String STATE = "state";
-
-    public EnableBlockLayoutAction() {
-        state = true;
-        putValue(AbstractAction.SMALL_ICON, new ImageIcon(org.openide.util.Utilities.loadImage(iconResource())));
-        putValue(STATE, true);
-        putValue(Action.SHORT_DESCRIPTION, "Cluster nodes into blocks");
-    }
-
-    public void actionPerformed(ActionEvent ev) {
-        this.state = !state;
-        this.putValue(STATE, state);
-    }
-
-    protected String iconResource() {
-        return "com/sun/hotspot/igv/view/images/blocks.gif";
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExpandPredecessorsAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExpandPredecessorsAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -33,6 +33,7 @@
  */
 public final class ExpandPredecessorsAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         EditorTopComponent editor = EditorTopComponent.getActive();
         if (editor != null) {
@@ -40,8 +41,9 @@
         }
     }
 
+    @Override
     public String getName() {
-        return "Expand Predecessors";
+        return "Expand Above";
     }
 
     @Override
@@ -49,6 +51,7 @@
         super.initialize();
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExpandSuccessorsAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExpandSuccessorsAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -33,6 +33,7 @@
  */
 public final class ExpandSuccessorsAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         EditorTopComponent editor = EditorTopComponent.getActive();
         if (editor != null) {
@@ -40,8 +41,9 @@
         }
     }
 
+    @Override
     public String getName() {
-        return "Expand Successors";
+        return "Expand Below";
     }
 
     @Override
@@ -49,6 +51,7 @@
         super.initialize();
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExportAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExportAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -32,12 +32,7 @@
 import javax.swing.JFileChooser;
 import javax.swing.KeyStroke;
 import javax.swing.filechooser.FileFilter;
-import org.openide.util.HelpCtx;
-import org.openide.util.Lookup;
-import org.openide.util.LookupEvent;
-import org.openide.util.LookupListener;
-import org.openide.util.NbBundle;
-import org.openide.util.Utilities;
+import org.openide.util.*;
 import org.openide.util.actions.CallableSystemAction;
 
 /**
@@ -50,27 +45,31 @@
     private final Lookup.Result<ExportCookie> result;
 
     public ExportAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Export current graph as an SVG file");
+        putValue(Action.SHORT_DESCRIPTION, "Export current graph as SVG file");
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_MASK));
         lookup = Utilities.actionsGlobalContext();
-        result = lookup.lookup(new Lookup.Template<ExportCookie>(ExportCookie.class));
+        result = lookup.lookup(new Lookup.Template<>(ExportCookie.class));
         result.addLookupListener(this);
         resultChanged(null);
     }
 
+    @Override
     public void resultChanged(LookupEvent e) {
         super.setEnabled(result.allInstances().size() > 0);
     }
 
+    @Override
     public void performAction() {
 
         JFileChooser fc = new JFileChooser();
         fc.setFileFilter(new FileFilter() {
 
+            @Override
             public boolean accept(File f) {
                 return true;
             }
 
+            @Override
             public String getDescription() {
                 return "SVG files (*.svg)";
             }
@@ -97,15 +96,17 @@
         }
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(ExportAction.class, "CTL_ExportAction");
     }
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/view/images/export.gif";
+        return "com/sun/hotspot/igv/view/images/export.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExtractAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExtractAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -37,6 +37,7 @@
  */
 public final class ExtractAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         EditorTopComponent editor = EditorTopComponent.getActive();
         if (editor != null) {
@@ -49,6 +50,7 @@
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_X, Event.CTRL_MASK, false));
     }
 
+    @Override
     public String getName() {
         return "Extract action";
     }
@@ -58,6 +60,7 @@
         super.initialize();
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/HideAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/HideAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -37,6 +37,7 @@
  */
 public final class HideAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         EditorTopComponent editor = EditorTopComponent.getActive();
         if (editor != null) {
@@ -49,6 +50,7 @@
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_H, Event.CTRL_MASK, false));
     }
 
+    @Override
     public String getName() {
         return "Hide";
     }
@@ -58,6 +60,7 @@
         super.initialize();
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/NextDiagramAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/NextDiagramAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,15 +23,12 @@
  */
 package com.sun.hotspot.igv.view.actions;
 
-import com.sun.hotspot.igv.view.DiagramViewModel;
 import com.sun.hotspot.igv.data.ChangedListener;
 import com.sun.hotspot.igv.util.ContextAction;
+import com.sun.hotspot.igv.view.DiagramViewModel;
 import javax.swing.Action;
 import javax.swing.ImageIcon;
-import org.openide.util.HelpCtx;
-import org.openide.util.Lookup;
-import org.openide.util.NbBundle;
-import org.openide.util.Utilities;
+import org.openide.util.*;
 
 /**
  *
@@ -47,13 +44,15 @@
 
     public NextDiagramAction(Lookup lookup) {
         putValue(Action.SHORT_DESCRIPTION, "Show next graph of current group");
-        putValue(Action.SMALL_ICON, new ImageIcon(Utilities.loadImage("com/sun/hotspot/igv/view/images/next_diagram.png")));
+        putValue(Action.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage("com/sun/hotspot/igv/view/images/next_diagram.png")));
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(NextDiagramAction.class, "CTL_NextDiagramAction");
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -95,10 +94,12 @@
         return model.getSecondPosition() != model.getPositions().size() - 1;
     }
 
+    @Override
     public Action createContextAwareInstance(Lookup arg0) {
         return new NextDiagramAction(arg0);
     }
 
+    @Override
     public void changed(DiagramViewModel source) {
         update(source);
     }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/NodeFindAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.view.actions;
-
-import com.sun.hotspot.igv.view.EditorTopComponent;
-import javax.swing.Action;
-import org.openide.util.HelpCtx;
-import org.openide.util.NbBundle;
-import org.openide.util.actions.CallableSystemAction;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public final class NodeFindAction extends CallableSystemAction {
-
-    public void performAction() {
-        EditorTopComponent comp = EditorTopComponent.getActive();
-        if (comp != null) {
-            comp.findNode();
-        }
-    }
-
-    public NodeFindAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Find nodes");
-    }
-
-    public String getName() {
-        return NbBundle.getMessage(NodeFindAction.class, "CTL_NodeFindAction");
-    }
-
-    public HelpCtx getHelpCtx() {
-        return HelpCtx.DEFAULT_HELP;
-    }
-
-    @Override
-    protected boolean asynchronous() {
-        return false;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return true;
-    }
-
-    @Override
-    protected String iconResource() {
-        return "com/sun/hotspot/igv/view/images/search.gif";
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/OverviewAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/OverviewAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -27,6 +27,7 @@
 import javax.swing.AbstractAction;
 import javax.swing.Action;
 import javax.swing.ImageIcon;
+import org.openide.util.ImageUtilities;
 
 /**
  *
@@ -38,11 +39,12 @@
     public static final String STATE = "state";
 
     public OverviewAction() {
-        putValue(AbstractAction.SMALL_ICON, new ImageIcon(org.openide.util.Utilities.loadImage(iconResource())));
+        putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource())));
         putValue(Action.SHORT_DESCRIPTION, "Show satellite view of whole graph");
         setState(false);
     }
 
+    @Override
     public void actionPerformed(ActionEvent ev) {
         setState(!state);
     }
@@ -53,6 +55,6 @@
     }
 
     protected String iconResource() {
-        return "com/sun/hotspot/igv/view/images/overview.gif";
+        return "com/sun/hotspot/igv/view/images/overview.png";
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/PanModeAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * 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.sun.hotspot.igv.view.actions;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import org.openide.util.ImageUtilities;
+
+public class PanModeAction extends AbstractAction {
+
+    private boolean state;
+
+    public PanModeAction() {
+        putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource())));
+        putValue(SELECTED_KEY, false);
+        putValue(Action.SHORT_DESCRIPTION, "Panning mode");
+    }
+
+    public boolean isSelected() {
+        return (Boolean)getValue(SELECTED_KEY);
+    }
+
+    public void setSelected(boolean b) {
+        if (isSelected() != b) {
+            this.putValue(SELECTED_KEY, b);
+        }
+    }
+
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/view/images/pan_mode.png";
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/PredSuccAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/PredSuccAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -27,6 +27,7 @@
 import javax.swing.AbstractAction;
 import javax.swing.Action;
 import javax.swing.ImageIcon;
+import org.openide.util.ImageUtilities;
 
 /**
  *
@@ -39,11 +40,12 @@
 
     public PredSuccAction() {
         state = true;
-        putValue(AbstractAction.SMALL_ICON, new ImageIcon(org.openide.util.Utilities.loadImage(iconResource())));
+        putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource())));
         putValue(STATE, true);
         putValue(Action.SHORT_DESCRIPTION, "Show neighboring nodes of fully visible nodes semi-transparent");
     }
 
+    @Override
     public void actionPerformed(ActionEvent ev) {
         this.state = !state;
         this.putValue(STATE, state);
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/PrevDiagramAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/PrevDiagramAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -24,14 +24,11 @@
 package com.sun.hotspot.igv.view.actions;
 
 import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.util.ContextAction;
 import com.sun.hotspot.igv.view.DiagramViewModel;
-import com.sun.hotspot.igv.util.ContextAction;
 import javax.swing.Action;
 import javax.swing.ImageIcon;
-import org.openide.util.HelpCtx;
-import org.openide.util.Lookup;
-import org.openide.util.NbBundle;
-import org.openide.util.Utilities;
+import org.openide.util.*;
 
 /**
  *
@@ -47,13 +44,15 @@
 
     public PrevDiagramAction(Lookup lookup) {
         putValue(Action.SHORT_DESCRIPTION, "Show previous graph of current group");
-        putValue(Action.SMALL_ICON, new ImageIcon(Utilities.loadImage("com/sun/hotspot/igv/view/images/prev_diagram.png")));
+        putValue(Action.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage("com/sun/hotspot/igv/view/images/prev_diagram.png")));
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(PrevDiagramAction.class, "CTL_PrevDiagramAction");
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -95,10 +94,12 @@
         return model.getFirstPosition() != 0;
     }
 
+    @Override
     public Action createContextAwareInstance(Lookup arg0) {
         return new PrevDiagramAction(arg0);
     }
 
+    @Override
     public void changed(DiagramViewModel source) {
         update(source);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/SelectionModeAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * 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.sun.hotspot.igv.view.actions;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import org.openide.util.ImageUtilities;
+
+public class SelectionModeAction extends AbstractAction {
+
+    public SelectionModeAction() {
+        putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource())));
+        putValue(SELECTED_KEY, false);
+        putValue(Action.SHORT_DESCRIPTION, "Selection mode");
+    }
+
+    public boolean isSelected() {
+        return (Boolean)getValue(SELECTED_KEY);
+    }
+
+    public void setSelected(boolean b) {
+        if (isSelected() != b) {
+            this.putValue(SELECTED_KEY, b);
+        }
+    }
+
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/view/images/selection_mode.png";
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ShowAllAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ShowAllAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,7 +23,7 @@
  */
 package com.sun.hotspot.igv.view.actions;
 
-import com.sun.hotspot.igv.view.*;
+import com.sun.hotspot.igv.view.EditorTopComponent;
 import java.awt.event.InputEvent;
 import java.awt.event.KeyEvent;
 import javax.swing.Action;
@@ -37,6 +37,7 @@
  */
 public final class ShowAllAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         EditorTopComponent editor = EditorTopComponent.getActive();
         if (editor != null) {
@@ -49,6 +50,7 @@
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_MASK));
     }
 
+    @Override
     public String getName() {
         return "Show all";
     }
@@ -58,6 +60,7 @@
         super.initialize();
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ZoomInAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ZoomInAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -37,6 +37,7 @@
  */
 public final class ZoomInAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         EditorTopComponent editor = EditorTopComponent.getActive();
         if (editor != null) {
@@ -44,6 +45,7 @@
         }
     }
 
+    @Override
     public String getName() {
         return "Zoom in";
     }
@@ -53,6 +55,7 @@
         putValue(Action.SHORT_DESCRIPTION, "Zoom in");
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -64,6 +67,6 @@
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/view/images/zoomin.gif";
+        return "com/sun/hotspot/igv/view/images/zoom_in.png";
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ZoomOutAction.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ZoomOutAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -37,6 +37,7 @@
  */
 public final class ZoomOutAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         EditorTopComponent editor = EditorTopComponent.getActive();
         if (editor != null) {
@@ -50,6 +51,7 @@
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, Event.CTRL_MASK, false));
     }
 
+    @Override
     public String getName() {
         return "Zoom out";
     }
@@ -59,6 +61,7 @@
         super.initialize();
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -70,6 +73,6 @@
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/view/images/zoomout.gif";
+        return "com/sun/hotspot/igv/view/images/zoom_out.png";
     }
 }
Binary file src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/export.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/export.png has changed
Binary file src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/overview.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/overview.png has changed
Binary file src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/pan_mode.png has changed
Binary file src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/search.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/selection_mode.png has changed
Binary file src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/zoom_in.png has changed
Binary file src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/zoom_out.png has changed
Binary file src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/zoomin.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/zoomout.gif has changed
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/layer.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/layer.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -24,36 +24,57 @@
         <folder name="View">
             <file name="com-sun-hotspot-igv-view-actions-PrevDiagramAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/View/com-sun-hotspot-igv-view-actions-PrevDiagramAction.instance"/>
+                <attr name="position" intvalue="100"/>
             </file>
             <file name="com-sun-hotspot-igv-view-actions-NextDiagramAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/View/com-sun-hotspot-igv-view-actions-NextDiagramAction.instance"/>
+                <attr name="position" intvalue="150"/>
             </file>
             <file name="com-sun-hotspot-igv-view-actions-ShowAllAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/View/com-sun-hotspot-igv-view-actions-ShowAllAction.instance"/>
+                <attr name="position" intvalue="200"/>
             </file>
             <file name="com-sun-hotspot-igv-view-actions-ExtractAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/View/com-sun-hotspot-igv-view-actions-ExtractAction.instance"/>
+                <attr name="position" intvalue="300"/>
             </file>
             <file name="com-sun-hotspot-igv-view-actions-HideAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/View/com-sun-hotspot-igv-view-actions-HideAction.instance"/>
+                <attr name="position" intvalue="400"/>
             </file>
             <file name="com-sun-hotspot-igv-view-actions-ZoomInAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/View/com-sun-hotspot-igv-view-actions-ZoomInAction.instance"/>
+                <attr name="position" intvalue="500"/>
             </file>
             <file name="com-sun-hotspot-igv-view-actions-ZoomOutAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/View/com-sun-hotspot-igv-view-actions-ZoomOutAction.instance"/>
+                <attr name="position" intvalue="550"/>
             </file>
         </folder>
         <folder name="File">
+            <file name="ExportActionSeparator.instance">
+                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
+                <attr name="position" intvalue="700"/>
+            </file>
             <file name="com-sun-hotspot-igv-view-actions-ExportAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/File/com-sun-hotspot-igv-view-actions-ExportAction.instance"/>
-                <attr name="position" intvalue="600"/>
+                <attr name="position" intvalue="710"/>
             </file>
         </folder>
     </folder>
-    <folder name="Toolbars">
-        <folder name="Edit">
-            <attr name="com-sun-hotspot-igv-view-actions-LineGeneratorAction.shadow/com-sun-hotspot-igv-coordinator-actions-OpenGraphAction.shadow" boolvalue="true"/>
+
+    <folder name="QuickSearch">
+        <folder name="Nodes">
+            <attr name="command" stringvalue="n"/>
+            <attr name="position" intvalue="0"/>
+            <file name="com-sun-hotspot-igv-view-NodeQuickSearch.instance" />
         </folder>
     </folder>
+    
+    <folder name="QuickSearchShadow">
+        <file name="org-netbeans-modules-quicksearch-QuickSearchAction.shadow">
+            <attr name="originalFile" stringvalue="Actions/Edit/org-netbeans-modules-quicksearch-QuickSearchAction.instance"/>
+            
+        </file>    
+    </folder>
 </filesystem>
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/BlockWidget.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.view.widgets;
-
-import com.sun.hotspot.igv.data.InputBlock;
-import com.sun.hotspot.igv.graph.Diagram;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.Stroke;
-import java.awt.geom.Rectangle2D;
-import org.netbeans.api.visual.widget.Scene;
-import org.netbeans.api.visual.widget.Widget;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class BlockWidget extends Widget {
-
-    public static final int BORDER = 20;
-    public static final Color BACKGROUND_COLOR = new Color(235, 235, 255);
-    private static final Font titleFont = new Font("Serif", Font.PLAIN, 14).deriveFont(Font.BOLD);
-    private InputBlock blockNode;
-    private Diagram diagram;
-
-    public BlockWidget(Scene scene, Diagram d, InputBlock blockNode) {
-        super(scene);
-        this.blockNode = blockNode;
-        this.diagram = d;
-        this.setBackground(BACKGROUND_COLOR);
-        this.setOpaque(true);
-        this.setCheckClipping(true);
-    }
-
-    @Override
-    protected void paintWidget() {
-        super.paintWidget();
-        Graphics2D g = this.getGraphics();
-        Stroke old = g.getStroke();
-        g.setColor(Color.BLUE);
-        Rectangle r = new Rectangle(this.getPreferredBounds());
-        r.width--;
-        r.height--;
-        if (this.getBounds().width > 0 && this.getBounds().height > 0) {
-            g.setStroke(new BasicStroke(2));
-            g.drawRect(r.x, r.y, r.width, r.height);
-        }
-
-        Color titleColor = Color.BLACK;
-        g.setColor(titleColor);
-        g.setFont(titleFont);
-
-        String s = "B" + blockNode.toString();
-        Rectangle2D r1 = g.getFontMetrics().getStringBounds(s, g);
-        g.drawString(s, r.x + 5, r.y + (int) r1.getHeight());
-        g.setStroke(old);
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/DiagramConnectionWidget.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,251 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.view.widgets;
-
-import com.sun.hotspot.igv.graph.Connection;
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.view.DiagramScene;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Stroke;
-import java.util.ArrayList;
-import java.util.List;
-import org.netbeans.api.visual.anchor.AnchorShape;
-import org.netbeans.api.visual.model.ObjectState;
-import org.netbeans.api.visual.widget.ConnectionWidget;
-import org.netbeans.api.visual.widget.Scene;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class DiagramConnectionWidget extends ConnectionWidget {
-
-    private static Stroke DASHED_STROKE = new BasicStroke(
-            1,
-            BasicStroke.CAP_BUTT,
-            BasicStroke.JOIN_ROUND,
-            0,
-            new float[]{2},
-            0);
-    private static Stroke NORMAL_STROKE = new BasicStroke(1);
-    private static Stroke BOLD_STROKE = new BasicStroke(3);
-    public static int WHITE_FACTOR = 5;
-    private Connection connection;
-    private Color color;
-    private Point lastSourceAnchor;
-    private Point lastTargetAnchor;
-    private List<Point> controlPoints;
-    private Rectangle clientArea;
-    private boolean split;
-    private int[] xPoints;
-    private int[] yPoints;
-    private int pointCount;
-
-    /** Creates a new instance of ConnectionWidget */
-    public DiagramConnectionWidget(Connection connection, Scene scene) {
-        super(scene);
-        this.connection = connection;
-        color = connection.getColor();
-        if (connection.getStyle() == Connection.ConnectionStyle.DASHED) {
-            this.setStroke(DASHED_STROKE);
-        } else if (connection.getStyle() == Connection.ConnectionStyle.BOLD) {
-            this.setStroke(BOLD_STROKE);
-        } else {
-            this.setStroke(NORMAL_STROKE);
-        }
-        this.setCheckClipping(true);
-        clientArea = new Rectangle();
-        updateControlPoints();
-    }
-
-    public Connection getConnection() {
-        return connection;
-    }
-
-    public void updateControlPoints() {
-        List<Point> newControlPoints = connection.getControlPoints();
-        Connection c = connection;
-        Figure f = c.getInputSlot().getFigure();
-        Point p = new Point(f.getPosition());
-        p.translate(c.getInputSlot().getRelativePosition().x, f.getSize().height / 2);
-        Point p4 = new Point(f.getPosition());
-        p4.translate(c.getInputSlot().getRelativePosition().x, c.getInputSlot().getRelativePosition().y);
-
-        Figure f2 = c.getOutputSlot().getFigure();
-        Point p2 = new Point(f2.getPosition());
-        p2.translate(c.getOutputSlot().getRelativePosition().x, f2.getSize().height / 2);
-        Point p3 = new Point(f2.getPosition());
-        p3.translate(c.getOutputSlot().getRelativePosition().x, c.getOutputSlot().getRelativePosition().y);
-
-        /*if(controlPoints.size() >= 2) {
-        String className = Preferences.userNodeForPackage(PreferenceConstants.class).get(PreferenceConstants.KEY_LINE_GENERATOR, PreferenceConstants.DEFAULT_LINE_GENERATOR);
-        try {
-        LineGenerator lg = (LineGenerator)Class.forName(className).newInstance();
-        controlPoints = lg.createLine(controlPoints, p2, p);
-        } catch (InstantiationException ex) {
-        } catch (IllegalAccessException ex) {
-        } catch (ClassNotFoundException ex) {
-        }
-        }*/
-
-        this.controlPoints = newControlPoints;
-        pointCount = newControlPoints.size();
-        xPoints = new int[pointCount];
-        yPoints = new int[pointCount];
-        int minX = Integer.MAX_VALUE;
-        int maxX = Integer.MIN_VALUE;
-        int minY = Integer.MAX_VALUE;
-        int maxY = Integer.MIN_VALUE;
-        split = false;
-        for (int i = 0; i < pointCount; i++) {
-            if (newControlPoints.get(i) == null) {
-                split = true;
-            } else {
-                int curX = newControlPoints.get(i).x;
-                int curY = newControlPoints.get(i).y;
-                this.xPoints[i] = curX;
-                this.yPoints[i] = curY;
-                minX = Math.min(minX, curX);
-                maxX = Math.max(maxX, curX);
-                minY = Math.min(minY, curY);
-                maxY = Math.max(maxY, curY);
-            }
-        }
-
-        this.clientArea = new Rectangle(minX, minY, maxX - minX, maxY - minY);
-    }
-
-    @Override
-    protected void paintWidget() {
-        Graphics2D g = this.getGraphics();
-
-        if (xPoints.length == 0 || Math.abs(xPoints[0] - xPoints[xPoints.length - 1]) > 2000) {
-            return;
-        }
-
-        //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
-        //g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
-        //g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
-
-        DiagramScene ds = (DiagramScene) this.getScene();
-        boolean shouldHide = false;//ds.getShouldHide(this);
-
-        Composite oldComposite = null;
-        if (shouldHide) {
-            Color c = new Color(255 - (255 - color.getRed()) / WHITE_FACTOR, 255 - (255 - color.getGreen()) / WHITE_FACTOR, 255 - (255 - color.getBlue()) / WHITE_FACTOR);
-            g.setPaint(c);
-        } else {
-            g.setPaint(color);
-        }
-
-        if (split) {
-            for (int i = 1; i < controlPoints.size(); i++) {
-                Point prev = controlPoints.get(i - 1);
-                Point cur = controlPoints.get(i);
-                if (cur == null || prev == null) {
-                    continue;
-                }
-
-                g.drawLine(prev.x, prev.y, cur.x, cur.y);
-            }
-        } else {
-            g.drawPolyline(xPoints, yPoints, pointCount);
-        }
-
-        /*for(int i=0; i<xPoints.length; i++) {
-        int x = xPoints[i];
-        int y = yPoints[i];
-        g.fillOval(x - 2, y - 2, 4, 4);
-        }*/
-
-        if (xPoints.length >= 2) {
-            Graphics2D g2 = (Graphics2D) g.create();
-            int xOff = xPoints[xPoints.length - 2] - xPoints[xPoints.length - 1];
-            int yOff = yPoints[yPoints.length - 2] - yPoints[yPoints.length - 1];
-            if (xOff == 0 && yOff == 0 && yPoints.length >= 3) {
-                xOff = xPoints[xPoints.length - 3] - xPoints[xPoints.length - 1];
-                yOff = yPoints[yPoints.length - 3] - yPoints[yPoints.length - 1];
-            }
-            g2.translate(xPoints[xPoints.length - 1], yPoints[yPoints.length - 1]);
-            g2.rotate(Math.atan2(yOff, xOff));
-
-            g2.scale(0.55, 0.80);
-            AnchorShape.TRIANGLE_FILLED.paint(g2, false);
-        }
-    }
-
-    @Override
-    public void notifyStateChanged(ObjectState previousState, ObjectState state) {
-
-        if (previousState.isHovered() != state.isHovered()) {
-            color = connection.getColor();
-            if (state.isHovered()) {
-                this.setStroke(BOLD_STROKE);
-            } else {
-                this.setStroke(NORMAL_STROKE);
-            }
-
-            if (state.isHovered()) {
-                this.setStroke(BOLD_STROKE);
-            } else {
-                this.setStroke(NORMAL_STROKE);
-            }
-
-            repaint();
-        }
-        super.notifyStateChanged(previousState, state);
-    }
-
-    @Override
-    public List<Point> getControlPoints() {
-        if (split) {
-            ArrayList<Point> result = new ArrayList<Point>();
-            for (Point p : controlPoints) {
-                if (p != null) {
-                    result.add(p);
-                }
-            }
-            return result;
-        } else {
-            return controlPoints;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "ConnectionWidget[" + connection + "]";
-    }
-
-    @Override
-    protected Rectangle calculateClientArea() {
-        Rectangle result = new Rectangle(clientArea);
-        result.grow(10, 10);
-        return result;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/FigureWidget.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/FigureWidget.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,19 +23,13 @@
  */
 package com.sun.hotspot.igv.view.widgets;
 
+import com.sun.hotspot.igv.data.Properties;
 import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.view.DiagramScene;
-import com.sun.hotspot.igv.view.SlotLayout;
+import com.sun.hotspot.igv.util.DoubleClickAction;
 import com.sun.hotspot.igv.util.DoubleClickHandler;
-import com.sun.hotspot.igv.data.Properties;
 import com.sun.hotspot.igv.util.PropertiesSheet;
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.Graphics;
-import java.awt.Point;
+import com.sun.hotspot.igv.view.DiagramScene;
+import java.awt.*;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Set;
@@ -43,12 +37,14 @@
 import javax.swing.BorderFactory;
 import javax.swing.JMenu;
 import javax.swing.JPopupMenu;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuListener;
 import org.netbeans.api.visual.action.PopupMenuProvider;
 import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.layout.LayoutFactory;
 import org.netbeans.api.visual.model.ObjectState;
+import org.netbeans.api.visual.widget.LabelWidget;
 import org.netbeans.api.visual.widget.Widget;
-import org.netbeans.api.visual.layout.LayoutFactory;
-import org.netbeans.api.visual.widget.LabelWidget;
 import org.openide.nodes.AbstractNode;
 import org.openide.nodes.Children;
 import org.openide.nodes.Node;
@@ -61,8 +57,7 @@
 public class FigureWidget extends Widget implements Properties.Provider, PopupMenuProvider, DoubleClickHandler {
 
     public static final boolean VERTICAL_LAYOUT = true;
-    public static final int DEPTH = 5;
-    public static final int MAX_STRING_LENGTH = 20;
+    //public static final int MAX_STRING_LENGTH = 20;
     private static final double LABEL_ZOOM_FACTOR = 0.3;
     private static final double ZOOM_FACTOR = 0.1;
     private Font font;
@@ -75,6 +70,7 @@
     private DiagramScene diagramScene;
     private boolean boundary;
     private Node node;
+    private Widget dummyTop;
 
     public void setBoundary(boolean b) {
         boundary = b;
@@ -88,80 +84,69 @@
         return node;
     }
 
-    private String shortenString(String string) {
-        if (string.length() > MAX_STRING_LENGTH) {
-            StringBuilder sb = new StringBuilder();
-            for (int i = 0; i < string.length(); i++) {
-                char c = string.charAt(i);
-                if (!Character.isLetter(c) || Character.isUpperCase(c)) {
-                    sb.append(c);
-                }
-            }
-            string = sb.toString();
-        }
-        return string;
-    }
+	@Override
+	public boolean isHitAt(Point localLocation) {
+		return middleWidget.isHitAt(localLocation);
+	}
+    
 
-    public FigureWidget(final Figure f, DiagramScene s, Widget parent) {
+    public FigureWidget(final Figure f, WidgetAction hoverAction, WidgetAction selectAction, DiagramScene scene, Widget parent) {
+
+        super(scene);
 
-        super(s);
+        assert this.getScene() != null;
+        assert this.getScene().getView() != null;
 
-
+        this.figure = f;
         font = f.getDiagram().getFont();
         boldFont = f.getDiagram().getFont().deriveFont(Font.BOLD);
         this.setCheckClipping(true);
-        this.diagramScene = s;
-
+        this.diagramScene = scene;
         parent.addChild(this);
-        this.figure = f;
-        this.resolveBounds(null, calculateClientArea());
-
-        leftWidget = new Widget(s);
-        this.addChild(leftWidget);
-        leftWidget.setLayout(new SlotLayout(SlotLayout.HorizontalAlignment.Right, VERTICAL_LAYOUT));//LayoutFactory.createVerticalFlowLayout(LayoutFactory.SerialAlignment.JUSTIFY, 0));
 
-        middleWidget = new Widget(s);
-        this.addChild(middleWidget);
-
-        if (VERTICAL_LAYOUT) {
-            this.setLayout(LayoutFactory.createVerticalFlowLayout());
-        } else {
-            this.setLayout(LayoutFactory.createHorizontalFlowLayout());
-        }
-
-        middleWidget.setLayout(LayoutFactory.createVerticalFlowLayout());
-
+	Widget outer = new Widget(scene);
+	outer.setBackground(f.getColor());
+	outer.setLayout(LayoutFactory.createOverlayLayout());
+	
+        middleWidget = new Widget(scene);
+        middleWidget.setLayout(LayoutFactory.createVerticalFlowLayout(LayoutFactory.SerialAlignment.CENTER, 0));
         middleWidget.setBackground(f.getColor());
         middleWidget.setOpaque(true);
-        assert this.getScene() != null;
-        assert this.getScene().getView() != null;
-        middleWidget.setBorder(BorderFactory.createLineBorder(Color.BLACK));
+        //middleWidget.setBorder(BorderFactory.createLineBorder(Color.BLACK));
+        middleWidget.getActions().addAction(new DoubleClickAction(this));
+	middleWidget.setCheckClipping(true);
 
-
-        labelWidgets = new ArrayList<LabelWidget>();
+        labelWidgets = new ArrayList<>();
 
         String[] strings = figure.getLines();
 
+        dummyTop = new Widget(scene);
+        dummyTop.setMinimumSize(new Dimension(Figure.INSET / 2, 1));
+        middleWidget.addChild(dummyTop);
+
+
         for (String cur : strings) {
 
             String displayString = cur;
 
-            LabelWidget lw = new LabelWidget(s);
+            LabelWidget lw = new LabelWidget(scene);
             labelWidgets.add(lw);
             middleWidget.addChild(lw);
             lw.setLabel(displayString);
-
             lw.setFont(font);
             lw.setForeground(Color.BLACK);
             lw.setAlignment(LabelWidget.Alignment.CENTER);
             lw.setVerticalAlignment(LabelWidget.VerticalAlignment.CENTER);
-            lw.setMaximumSize(new Dimension(f.getWidth(), 20000));
-            lw.setMinimumSize(new Dimension(f.getWidth(), 20));
+	    lw.setBorder(BorderFactory.createEmptyBorder());
         }
 
-        rightWidget = new Widget(s);
-        this.addChild(rightWidget);
-        rightWidget.setLayout(new SlotLayout(SlotLayout.HorizontalAlignment.Left, VERTICAL_LAYOUT));//LayoutFactory.createVerticalLayout(LayoutFactory.SerialAlignment.JUSTIFY, 0));
+        Widget dummyBottom = new Widget(scene);
+        dummyBottom.setMinimumSize(new Dimension(Figure.INSET / 2, 1));
+        middleWidget.addChild(dummyBottom);
+
+        middleWidget.setPreferredBounds(new Rectangle(0, Figure.SLOT_WIDTH - Figure.OVERLAPPING, f.getWidth(), f.getHeight()));
+	//outer.addChild(middleWidget);
+        this.addChild(middleWidget);
 
         // Initialize node for property sheet
         node = new AbstractNode(Children.LEAF) {
@@ -175,22 +160,6 @@
         };
         node.setDisplayName(getName());
     }
-    private boolean firstTime = true;
-
-    @Override
-    protected void paintWidget() {
-        if (firstTime) {
-            firstTime = false;
-            for (LabelWidget w : labelWidgets) {
-                String cur = w.getLabel();
-                Graphics graphics = this.getGraphics();
-                if (graphics.getFontMetrics().stringWidth(cur) > figure.getWidth()) {
-                    w.setLabel(shortenString(cur));
-                }
-            }
-        }
-        super.paintWidget();
-    }
 
     public Widget getLeftWidget() {
         return leftWidget;
@@ -205,19 +174,34 @@
         super.notifyStateChanged(previousState, state);
 
         Color borderColor = Color.BLACK;
+	Color innerBorderColor = getFigure().getColor();
         int thickness = 1;
         boolean repaint = false;
         Font f = font;
-        if (state.isSelected()) {
-            thickness = 1;
+        if (state.isSelected() || state.isHighlighted()) {
+            thickness = 2;
+	}
+	if(state.isSelected()) {
             f = boldFont;
-        }
+		innerBorderColor = borderColor;
+        } else {
+	}
 
-        if (state.isHovered()) {
-            borderColor = Color.BLUE;
-        }
+        if (state.isHighlighted()) {
+		innerBorderColor = borderColor = Color.BLUE;
+		repaint = true;
+        } else {
+		repaint = true;
+	}
 
         if (state.isHovered() != previousState.isHovered()) {
+
+		/*
+            if (state.isHovered()) {
+                diagramScene.addAllHighlighted(this.getFigure().getSource().getSourceNodesAsSet());
+            } else {
+                diagramScene.removeAllHighlighted(this.getFigure().getSource().getSourceNodesAsSet());
+            }*/
             repaint = true;
         }
 
@@ -226,7 +210,7 @@
         }
 
         if (repaint) {
-            middleWidget.setBorder(BorderFactory.createLineBorder(borderColor, thickness));
+            middleWidget.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(borderColor, 1), BorderFactory.createLineBorder(innerBorderColor, 1)));
             for (LabelWidget labelWidget : labelWidgets) {
                 labelWidget.setFont(f);
             }
@@ -238,6 +222,7 @@
         return getProperties().get("name");
     }
 
+    @Override
     public Properties getProperties() {
         return figure.getProperties();
     }
@@ -248,11 +233,6 @@
 
     @Override
     protected void paintChildren() {
-
-        if (diagramScene.getRealZoomFactor() < ZOOM_FACTOR && diagramScene.getModel().getShowBlocks()) {
-            return;
-        }
-
         Composite oldComposite = null;
         if (boundary) {
             oldComposite = getScene().getGraphics().getComposite();
@@ -260,7 +240,7 @@
             this.getScene().getGraphics().setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
         }
 
-        if (diagramScene.getRealZoomFactor() < LABEL_ZOOM_FACTOR) {
+        if (diagramScene.getZoomFactor() < LABEL_ZOOM_FACTOR) {
 
             for (LabelWidget labelWidget : labelWidgets) {
                 labelWidget.setVisible(false);
@@ -278,81 +258,106 @@
             getScene().getGraphics().setComposite(oldComposite);
         }
     }
-
+ 
+    @Override
     public JPopupMenu getPopupMenu(Widget widget, Point point) {
-        JPopupMenu m = diagramScene.createPopupMenu();
-
-        JMenu predecessors = new JMenu("Predecessors");
-        addFigureToSubMenu(predecessors, getFigure(), false, DEPTH);
+        JPopupMenu menu = diagramScene.createPopupMenu();
+        menu.addSeparator();
 
-        JMenu successors = new JMenu("Successors");
-        addFigureToSubMenu(successors, getFigure(), true, DEPTH);
+        JMenu predecessors = new JMenu("Nodes Above");
+        predecessors.addMenuListener(new NeighborMenuListener(predecessors, getFigure(), false));
+        menu.add(predecessors);
 
-        m.addSeparator();
-        m.add(predecessors);
-        m.add(successors);
-        return m;
+        JMenu successors = new JMenu("Nodes Below");
+        successors.addMenuListener(new NeighborMenuListener(successors, getFigure(), true));
+        menu.add(successors);
+
+        return menu;
     }
 
-    public void addFigureToSubMenu(JMenu subMenu, final Figure f, boolean successor, int depth) {
-        Set<Figure> set = f.getPredecessorSet();
-        if (successor) {
-            set = f.getSuccessorSet();
-        }
+    /**
+     * Builds the submenu for a figure's neighbors on demand.
+     */
+    private class NeighborMenuListener implements MenuListener {
 
-        int count = set.size();
-        if (set.contains(f)) {
-            count--;
+        private final JMenu menu;
+        private final Figure figure;
+        private final boolean successors;
+
+        public NeighborMenuListener(JMenu menu, Figure figure, boolean successors) {
+            this.menu = menu;
+            this.figure = figure;
+            this.successors = successors;
         }
 
-        for (Figure f2 : set) {
-            if (f2 == f) {
-                continue;
+        @Override
+        public void menuSelected(MenuEvent e) {
+            if (menu.getItemCount() > 0) {
+                // already built before
+                return;
+            }
+
+            Set<Figure> set = figure.getPredecessorSet();
+            if (successors) {
+                set = figure.getSuccessorSet();
             }
 
-            count--;
-            addFigureToMenu(subMenu, f2, successor, depth - 1);
-            if (count > 0) {
-                subMenu.addSeparator();
+            boolean first = true;
+            for (Figure f : set) {
+                if (f == figure) {
+                    continue;
+                }
+
+                if (first) {
+                    first = false;
+                } else {
+                    menu.addSeparator();
+                }
+
+                Action go = diagramScene.createGotoAction(f);
+                menu.add(go);
+
+                JMenu preds = new JMenu("Nodes Above");
+                preds.addMenuListener(new NeighborMenuListener(preds, f, false));
+                menu.add(preds);
+
+                JMenu succs = new JMenu("Nodes Below");
+                succs.addMenuListener(new NeighborMenuListener(succs, f, true));
+                menu.add(succs);
             }
+
+            if (menu.getItemCount() == 0) {
+                menu.add("(none)");
+            }
+        }
+
+        @Override
+        public void menuDeselected(MenuEvent e) {
+            // ignore
+        }
+
+        @Override
+        public void menuCanceled(MenuEvent e) {
+            // ignore
         }
     }
 
-    public void addFigureToMenu(JMenu m, final Figure f, boolean successor, int depth) {
-
-        Action a = diagramScene.createGotoAction(f);
-
-
-        m.add(a);
-
-        if (depth > 0) {
-            String name = "Predecessors";
-            if (successor) {
-                name = "Successors";
-            }
-
-            JMenu subMenu = new JMenu(name);
-            addFigureToSubMenu(subMenu, f, successor, depth);
-            m.add(subMenu);
-        }
-
-    }
-
+    @Override
     public void handleDoubleClick(Widget w, WidgetAction.WidgetMouseEvent e) {
 
         if (diagramScene.isAllVisible()) {
-            Set<Integer> hiddenNodes = new HashSet<Integer>(diagramScene.getModel().getGraphToView().getGroup().getAllNodes());
+            final Set<Integer> hiddenNodes = new HashSet<>(diagramScene.getModel().getGraphToView().getGroup().getAllNodes());
             hiddenNodes.removeAll(this.getFigure().getSource().getSourceNodesAsSet());
-            this.diagramScene.showNot(hiddenNodes);
+            this.diagramScene.getModel().showNot(hiddenNodes);
         } else if (isBoundary()) {
 
-            Set<Integer> hiddenNodes = new HashSet<Integer>(diagramScene.getModel().getHiddenNodes());
+            final Set<Integer> hiddenNodes = new HashSet<>(diagramScene.getModel().getHiddenNodes());
             hiddenNodes.removeAll(this.getFigure().getSource().getSourceNodesAsSet());
-            this.diagramScene.showNot(hiddenNodes);
+            this.diagramScene.getModel().showNot(hiddenNodes);
         } else {
-            Set<Integer> hiddenNodes = new HashSet<Integer>(diagramScene.getModel().getHiddenNodes());
+            final Set<Integer> hiddenNodes = new HashSet<>(diagramScene.getModel().getHiddenNodes());
             hiddenNodes.addAll(this.getFigure().getSource().getSourceNodesAsSet());
-            this.diagramScene.showNot(hiddenNodes);
+            this.diagramScene.getModel().showNot(hiddenNodes);
         }
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/InputSlotWidget.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/InputSlotWidget.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,6 +23,7 @@
  */
 package com.sun.hotspot.igv.view.widgets;
 
+import com.sun.hotspot.igv.graph.Figure;
 import com.sun.hotspot.igv.graph.InputSlot;
 import com.sun.hotspot.igv.view.DiagramScene;
 import java.awt.Point;
@@ -40,14 +41,25 @@
     public InputSlotWidget(InputSlot slot, DiagramScene scene, Widget parent, FigureWidget fw) {
         super(slot, scene, parent, fw);
         inputSlot = slot;
-        init();
-        getFigureWidget().getLeftWidget().addChild(this);
+        //init();
+        //getFigureWidget().getLeftWidget().addChild(this);
+        Point p = inputSlot.getRelativePosition();
+        p.x -= this.calculateClientArea().width / 2;
+        p.y += Figure.SLOT_START;
+        this.setPreferredLocation(p);
     }
 
     public InputSlot getInputSlot() {
         return inputSlot;
     }
-
+    
+    @Override
+    protected int calculateSlotWidth() {
+        List<InputSlot> slots = getSlot().getFigure().getInputSlots();
+        assert slots.contains(getSlot());
+        return calculateWidth(slots.size());
+    }
+/*
     protected Point calculateRelativeLocation() {
         if (getFigureWidget().getBounds() == null) {
             return new Point(0, 0);
@@ -57,5 +69,5 @@
         List<InputSlot> slots = inputSlot.getFigure().getInputSlots();
         assert slots.contains(inputSlot);
         return new Point((int) x, (int) (calculateRelativeY(slots.size(), slots.indexOf(inputSlot))));
-    }
+    }*/
 }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/LineWidget.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/LineWidget.java	Mon Feb 27 13:10:13 2012 +0100
@@ -24,23 +24,22 @@
 package com.sun.hotspot.igv.view.widgets;
 
 import com.sun.hotspot.igv.graph.Connection;
+import com.sun.hotspot.igv.graph.Figure;
 import com.sun.hotspot.igv.graph.InputSlot;
 import com.sun.hotspot.igv.graph.OutputSlot;
 import com.sun.hotspot.igv.view.DiagramScene;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Stroke;
+import java.awt.*;
 import java.awt.geom.Line2D;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import javax.swing.JPopupMenu;
 import javax.swing.event.PopupMenuEvent;
 import javax.swing.event.PopupMenuListener;
 import org.netbeans.api.visual.action.ActionFactory;
 import org.netbeans.api.visual.action.PopupMenuProvider;
+import org.netbeans.api.visual.action.SelectProvider;
 import org.netbeans.api.visual.animator.SceneAnimator;
 import org.netbeans.api.visual.model.ObjectState;
 import org.netbeans.api.visual.widget.Widget;
@@ -51,7 +50,7 @@
  */
 public class LineWidget extends Widget implements PopupMenuProvider {
 
-    public final int BORDER = 8;
+    public final int BORDER = 5;
     public final int ARROW_SIZE = 6;
     public final int BOLD_ARROW_SIZE = 7;
     public final int HOVER_ARROW_SIZE = 8;
@@ -80,7 +79,7 @@
         this.from = from;
         this.to = to;
         this.predecessor = predecessor;
-        this.successors = new ArrayList<LineWidget>();
+        this.successors = new ArrayList<>();
         if (predecessor != null) {
             predecessor.addSuccessor(this);
         }
@@ -111,6 +110,8 @@
             color = connections.get(0).getColor();
         }
 
+        this.setToolTipText("<HTML>" + generateToolTipText(this.connections) + "</HTML>");
+
         this.setCheckClipping(true);
 
         this.getActions().addAction(ActionFactory.createPopupMenuAction(this));
@@ -120,6 +121,38 @@
             this.setBackground(Color.WHITE);
             animator.animateBackgroundColor(this, color);
         }
+
+        this.getActions().addAction(ActionFactory.createSelectAction(new SelectProvider() {
+
+            @Override
+            public boolean isAimingAllowed(Widget arg0, Point arg1, boolean arg2) {
+                return true;
+            }
+
+            @Override
+            public boolean isSelectionAllowed(Widget arg0, Point arg1, boolean arg2) {
+                return true;
+            }
+
+            @Override
+            public void select(Widget arg0, Point arg1, boolean arg2) {
+                Set<Figure> set = new HashSet<>();
+                for (Connection c : LineWidget.this.connections) {
+                    set.add(c.getInputSlot().getFigure());
+                    set.add(c.getOutputSlot().getFigure());
+                }
+                LineWidget.this.scene.setSelectedObjects(set);
+            }
+        }));
+    }
+
+    private String generateToolTipText(List<Connection> conn) {
+        StringBuilder sb = new StringBuilder();
+        for (Connection c : conn) {
+            sb.append(c.getToolTipText());
+            sb.append("<br>");
+        }
+        return sb.toString();
     }
 
     public Point getFrom() {
@@ -141,13 +174,12 @@
 
     @Override
     protected void paintWidget() {
-        if (scene.getRealZoomFactor() < ZOOM_FACTOR) {
+        if (scene.getZoomFactor() < ZOOM_FACTOR) {
             return;
         }
 
         Graphics2D g = getScene().getGraphics();
         g.setPaint(this.getBackground());
-        ObjectState state = this.getState();
         float width = 1.0f;
 
         if (isBold) {
@@ -207,6 +239,20 @@
 
     private void setHighlighted(boolean b) {
         this.highlighted = b;
+	Set<Object> highlightedObjects = new HashSet<>(scene.getHighlightedObjects());
+	Set<Object> highlightedObjectsChange = new HashSet<>();
+        for (Connection c : connections) {
+		highlightedObjectsChange.add(c.getInputSlot().getFigure());
+		highlightedObjectsChange.add(c.getInputSlot());
+		highlightedObjectsChange.add(c.getOutputSlot().getFigure());
+		highlightedObjectsChange.add(c.getOutputSlot());
+        }
+	if(b) {
+		highlightedObjects.addAll(highlightedObjectsChange);
+	} else {
+		highlightedObjects.removeAll(highlightedObjectsChange);
+	}
+	scene.setHighlightedObjects(highlightedObjects);
         this.revalidate(true);
     }
 
@@ -263,6 +309,7 @@
         }
     }
 
+    @Override
     public JPopupMenu getPopupMenu(Widget widget, Point localLocation) {
         JPopupMenu menu = new JPopupMenu();
         menu.add(scene.createGotoAction(outputSlot.getFigure()));
@@ -276,14 +323,17 @@
         final LineWidget w = this;
         menu.addPopupMenuListener(new PopupMenuListener() {
 
+            @Override
             public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                 w.setRecursivePopupVisible(true);
             }
 
+            @Override
             public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                 w.setRecursivePopupVisible(false);
             }
 
+            @Override
             public void popupMenuCanceled(PopupMenuEvent e) {
             }
         });
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/MultiConnectionWidget.java	Fri Feb 24 18:08:59 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,281 +0,0 @@
-/*
- * Copyright (c) 2008, 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.sun.hotspot.igv.view.widgets;
-
-import com.sun.hotspot.igv.graph.Connection;
-import com.sun.hotspot.igv.graph.InputSlot;
-import com.sun.hotspot.igv.graph.OutputSlot;
-import com.sun.hotspot.igv.graph.Slot;
-import com.sun.hotspot.igv.view.DiagramScene;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Stroke;
-import java.awt.geom.Line2D;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import javax.swing.JPopupMenu;
-import javax.swing.event.PopupMenuEvent;
-import javax.swing.event.PopupMenuListener;
-import org.netbeans.api.visual.action.PopupMenuProvider;
-import org.netbeans.api.visual.model.ObjectState;
-import org.netbeans.api.visual.widget.Widget;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class MultiConnectionWidget extends Widget implements PopupMenuProvider {
-
-    public final int BORDER = 4;
-    public final int HOVER_STROKE_WIDTH = 3;
-
-    private static class Route {
-
-        public Point from;
-        public Point to;
-        public SortedSet<InputSlot> inputSlots;
-        public boolean decorateStart;
-        public boolean decorateEnd;
-
-        public Route(Point from, Point to) {
-            assert from != null;
-            assert to != null;
-            this.from = from;
-            this.to = to;
-            this.inputSlots = new TreeSet<InputSlot>();
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-
-            if (obj instanceof Route) {
-                Route r = (Route) obj;
-                return r.from.equals(from) && r.to.equals(to);
-            }
-
-            return super.equals(obj);
-        }
-
-        @Override
-        public int hashCode() {
-            return ((((from.x * 1711) + from.y) * 1711 + to.x) * 1711 + to.y);
-        }
-    }
-    private Rectangle clientArea;
-    private OutputSlot outputSlot;
-    private Map<Route, SortedSet<InputSlot>> routeMap;
-    private List<Route> routeList;
-    private Color color;
-    private DiagramScene diagramScene;
-    private boolean popupVisible;
-
-    /** Creates a new instance of MultiConnectionWidget */
-    public MultiConnectionWidget(OutputSlot outputSlot, DiagramScene scene) {
-        super(scene);
-
-        this.diagramScene = scene;
-        this.outputSlot = outputSlot;
-        this.setCheckClipping(true);
-
-        routeMap = new HashMap<Route, SortedSet<InputSlot>>();
-        routeList = new ArrayList<Route>();
-        color = Color.BLACK;
-
-        for (Connection c : outputSlot.getConnections()) {
-            List<Point> controlPoints = c.getControlPoints();
-            InputSlot inputSlot = (InputSlot) c.getTo();
-            color = c.getColor();
-
-            for (int i = 1; i < controlPoints.size(); i++) {
-                Point prev = controlPoints.get(i - 1);
-                Point cur = controlPoints.get(i);
-
-                if (prev != null && cur != null) {
-                    Route r = new Route(prev, cur);
-                    if (routeMap.containsKey(r)) {
-                        SortedSet<InputSlot> set = routeMap.get(r);
-                        set.add(inputSlot);
-                    } else {
-                        SortedSet<InputSlot> set = new TreeSet<InputSlot>(Slot.slotFigureComparator);
-                        set.add(inputSlot);
-                        routeMap.put(r, set);
-                        routeList.add(r);
-                    }
-                }
-            }
-        }
-
-        if (routeList.size() == 0) {
-            clientArea = new Rectangle();
-        } else {
-            for (Route r : routeList) {
-
-                int x = r.from.x;
-                int y = r.from.y;
-
-                int x2 = r.to.x;
-                int y2 = r.to.y;
-
-                if (x > x2) {
-                    int tmp = x;
-                    x = x2;
-                    x2 = tmp;
-                }
-
-                if (y > y2) {
-                    int tmp = y;
-                    y = y2;
-                    y2 = tmp;
-                }
-
-                int width = x2 - x + 1;
-                int height = y2 - y + 1;
-
-                Rectangle rect = new Rectangle(x, y, width, height);
-                if (clientArea == null) {
-                    clientArea = rect;
-                } else {
-                    clientArea = clientArea.union(rect);
-                }
-            }
-
-            clientArea.grow(BORDER, BORDER);
-        }
-    }
-
-    private void setHoverPosition(Point location) {
-        Route r = getNearest(location);
-    }
-
-    private Route getNearest(Point localLocation) {
-
-        double minDist = Double.MAX_VALUE;
-        Route result = null;
-        for (Route r : routeList) {
-            double dist = Line2D.ptSegDistSq((double) r.from.x, (double) r.from.y, (double) r.to.x, (double) r.to.y, (double) localLocation.x, (double) localLocation.y);
-            if (dist < minDist) {
-                result = r;
-                minDist = dist;
-            }
-        }
-
-        assert result != null;
-
-        return result;
-    }
-
-    @Override
-    public boolean isHitAt(Point localLocation) {
-        if (!super.isHitAt(localLocation)) {
-            return false;
-        }
-
-        for (Route r : routeList) {
-            double dist = Line2D.ptSegDistSq((double) r.from.x, (double) r.from.y, (double) r.to.x, (double) r.to.y, (double) localLocation.x, (double) localLocation.y);
-            if (dist < BORDER * BORDER) {
-                setHoverPosition(localLocation);
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    protected Rectangle calculateClientArea() {
-        return clientArea;
-    }
-
-    @Override
-    protected void paintWidget() {
-        Graphics2D g = getScene().getGraphics();
-        //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
-        g.setColor(this.color);
-        ObjectState state = this.getState();
-        float width = 1.0f;
-        if (state.isHovered() || this.popupVisible) {
-            width = HOVER_STROKE_WIDTH;
-        }
-
-        Stroke oldStroke = g.getStroke();
-        g.setStroke(new BasicStroke(width));
-        for (Route r : routeList) {
-            g.drawLine(r.from.x, r.from.y, r.to.x, r.to.y);
-        }
-        g.setStroke(oldStroke);
-    }
-
-    @Override
-    protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
-
-        boolean repaint = false;
-
-        if (state.isHovered() != previousState.isHovered()) {
-            repaint = true;
-        }
-
-        repaint();
-    }
-
-    public JPopupMenu getPopupMenu(Widget widget, Point localLocation) {
-        JPopupMenu menu = new JPopupMenu();
-        Route r = getNearest(localLocation);
-        assert r != null;
-        assert routeMap.containsKey(r);
-
-        menu.add(diagramScene.createGotoAction(outputSlot.getFigure()));
-        menu.addSeparator();
-
-        SortedSet<InputSlot> set = this.routeMap.get(r);
-        for (InputSlot s : set) {
-            menu.add(diagramScene.createGotoAction(s.getFigure()));
-        }
-
-        final MultiConnectionWidget w = this;
-        menu.addPopupMenuListener(new PopupMenuListener() {
-
-            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
-                w.popupVisible = true;
-                w.repaint();
-            }
-
-            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
-                w.popupVisible = false;
-                w.repaint();
-            }
-
-            public void popupMenuCanceled(PopupMenuEvent e) {
-            }
-        });
-
-        return menu;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/OutputSlotWidget.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/OutputSlotWidget.java	Mon Feb 27 13:10:13 2012 +0100
@@ -23,6 +23,7 @@
  */
 package com.sun.hotspot.igv.view.widgets;
 
+import com.sun.hotspot.igv.graph.Figure;
 import com.sun.hotspot.igv.graph.OutputSlot;
 import com.sun.hotspot.igv.view.DiagramScene;
 import java.awt.Point;
@@ -40,14 +41,28 @@
     public OutputSlotWidget(OutputSlot slot, DiagramScene scene, Widget parent, FigureWidget fw) {
         super(slot, scene, parent, fw);
         outputSlot = slot;
-        init();
-        getFigureWidget().getRightWidget().addChild(this);
+        //init();
+        //getFigureWidget().getRightWidget().addChild(this);
+        Point p = outputSlot.getRelativePosition();
+        p.y += getSlot().getFigure().getHeight() - Figure.SLOT_START;
+        p.x -= this.calculateClientArea().width / 2;
+        //p.x += this.calculateClientArea().width / 2;
+        this.setPreferredLocation(p);
     }
 
     public OutputSlot getOutputSlot() {
         return outputSlot;
     }
 
+    @Override
+    protected int calculateSlotWidth() {
+        
+        List<OutputSlot> slots = getSlot().getFigure().getOutputSlots();
+        assert slots.contains(getSlot());
+        return calculateWidth(slots.size());
+        
+    }
+    /*
     protected Point calculateRelativeLocation() {
         if (getFigureWidget().getBounds() == null) {
             return new Point(0, 0);
@@ -57,5 +72,5 @@
         List<OutputSlot> slots = outputSlot.getFigure().getOutputSlots();
         assert slots.contains(outputSlot);
         return new Point((int) x, (int) (calculateRelativeY(slots.size(), slots.indexOf(outputSlot))));
-    }
+    }*/
 }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/SlotWidget.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/SlotWidget.java	Mon Feb 27 13:10:13 2012 +0100
@@ -26,53 +26,50 @@
 import com.sun.hotspot.igv.graph.Figure;
 import com.sun.hotspot.igv.graph.OutputSlot;
 import com.sun.hotspot.igv.graph.Slot;
-import com.sun.hotspot.igv.view.*;
+import com.sun.hotspot.igv.util.DoubleClickHandler;
+import com.sun.hotspot.igv.view.DiagramScene;
 import java.awt.Color;
 import java.awt.Font;
 import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.geom.Rectangle2D;
+import java.util.HashSet;
+import java.util.Set;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.model.ObjectState;
 import org.netbeans.api.visual.widget.Widget;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public abstract class SlotWidget extends Widget {
+public abstract class SlotWidget extends Widget implements DoubleClickHandler {
 
     private Slot slot;
     private FigureWidget figureWidget;
-    private Image bufferImage;
     private static double TEXT_ZOOM_FACTOR = 0.9;
     private static double ZOOM_FACTOR = 0.6;
-    private DiagramScene scene;
+    private DiagramScene diagramScene;
 
     public SlotWidget(Slot slot, DiagramScene scene, Widget parent, FigureWidget fw) {
         super(scene);
-        this.scene = scene;
+        this.diagramScene = scene;
         this.slot = slot;
         figureWidget = fw;
-        this.setToolTipText("<HTML>" + slot.getName() + "</HTML>");
+        this.setToolTipText("<HTML>" + slot.getToolTipText() + "</HTML>");
         this.setCheckClipping(true);
-    }
-
-    public Point getAnchorPosition() {
-        Point p = new Point(figureWidget.getFigure().getPosition());
-        Point p2 = slot.getRelativePosition();
-        p.translate(p2.x, p2.y);
-        return p;
+        parent.addChild(this);
+        
+        //this.setPreferredBounds(this.calculateClientArea());
     }
-
-    protected void init() {
-
-        Point p = calculateRelativeLocation();
-        Rectangle r = calculateClientArea();
-        p = new Point(p.x, p.y - r.height / 2);
-        this.setPreferredLocation(p);
+    
+    
+    @Override
+    protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
+        super.notifyStateChanged(previousState, state);
+	repaint();
     }
-
+    
     public Slot getSlot() {
         return slot;
     }
@@ -84,43 +81,97 @@
     @Override
     protected void paintWidget() {
 
-        if (scene.getRealZoomFactor() < ZOOM_FACTOR) {
+        if (getScene().getZoomFactor() < ZOOM_FACTOR) {
             return;
         }
 
-        if (bufferImage == null) {
-            Graphics2D g = this.getGraphics();
-            g.setColor(Color.DARK_GRAY);
-            int w = this.getBounds().width;
-            int h = this.getBounds().height;
+        Graphics2D g = this.getGraphics();
+       // g.setColor(Color.DARK_GRAY);
+        int w = this.getBounds().width;
+        int h = this.getBounds().height;
+
+        if(getSlot().getSource().getSourceNodes().size() > 0) {
+            final int SMALLER = 0;
+            g.setColor(getSlot().getColor());
 
-            if (getSlot().getShortName() != null && getSlot().getShortName().length() > 0 && scene.getRealZoomFactor() >= TEXT_ZOOM_FACTOR) {
-                Font f = new Font("Arial", Font.PLAIN, 8);
-                g.setFont(f.deriveFont(7.5f));
+            int FONT_OFFSET = 2;
+            
+            int s = h - SMALLER;
+            int rectW = s;
+            
+            Font font = this.getSlot().getFigure().getDiagram().getSlotFont();
+            if(this.getState().isSelected()) {
+                font = font.deriveFont(Font.BOLD);
+            }
+            
+            if (getSlot().getShortName() != null && getSlot().getShortName().length() > 0) {
+                g.setFont(font);
                 Rectangle2D r1 = g.getFontMetrics().getStringBounds(getSlot().getShortName(), g);
-                g.drawString(getSlot().getShortName(), (int) (this.getBounds().width - r1.getWidth()) / 2, (int) (this.getBounds().height + r1.getHeight()) / 2);
+                rectW = (int)r1.getWidth() + FONT_OFFSET * 2;
+            }
+            g.fillRect(w/2 - rectW/2, 0, rectW-1, s-1);
+            
+            if(this.getState().isHighlighted()) {
+                g.setColor(Color.BLUE);
             } else {
+                g.setColor(Color.BLACK);
+            }
+            g.drawRect(w/2 - rectW/2, 0, rectW-1, s-1);
+            
+            
+            if (getSlot().getShortName() != null && getSlot().getShortName().length() > 0 && getScene().getZoomFactor() >= TEXT_ZOOM_FACTOR) {
+                Rectangle2D r1 = g.getFontMetrics().getStringBounds(getSlot().getShortName(), g);
+                g.drawString(getSlot().getShortName(), (int) (w - r1.getWidth()) / 2, g.getFontMetrics().getAscent()-1);//(int) (r1.getHeight()));
+            }
+            
+        } else {
 
-                if (slot instanceof OutputSlot) {
-                    g.fillArc(w / 4, -h / 4 - 1, w / 2, h / 2, 180, 180);
-                } else {
-                    g.fillArc(w / 4, 3 * h / 4, w / 2, h / 2, 0, 180);
-                }
+            if(this.getState().isHighlighted()) {
+                g.setColor(Color.BLUE);
+            } else {
+                g.setColor(Color.BLACK);
+            }
+            int r = 2;
+            if (slot instanceof OutputSlot) {
+                g.fillOval(w/2-r, Figure.SLOT_WIDTH - Figure.SLOT_START - r, 2*r, 2*r);
+                //g.fillArc(w / 2 - r, -r, 2*r, 2*r, 180, 180);
+            } else {
+                g.fillOval(w/2-r, Figure.SLOT_START - r, 2*r, 2*r);
+                //g.fillArc(w / 2 - r, h - r, 2*r, 2*r, 0, 180);
             }
         }
     }
 
     @Override
     protected Rectangle calculateClientArea() {
-        return new Rectangle(0, 0, Figure.SLOT_WIDTH, Figure.SLOT_WIDTH);
+        return new Rectangle(0, 0, slot.getWidth(), Figure.SLOT_WIDTH);
+    }
+ 
+    protected abstract int calculateSlotWidth();
+    
+    protected int calculateWidth(int count) {
+        return getFigureWidget().getFigure().getWidth() / count;
     }
 
-    protected abstract Point calculateRelativeLocation();
+    @Override
+    public void handleDoubleClick(Widget w, WidgetAction.WidgetMouseEvent e) {
+        Set<Integer> hiddenNodes = new HashSet<>(diagramScene.getModel().getHiddenNodes());
+        if (diagramScene.isAllVisible()) {
+            hiddenNodes = new HashSet<>(diagramScene.getModel().getGraphToView().getGroup().getAllNodes());
+        } 
 
-    protected double calculateRelativeY(int size, int index) {
-        assert index >= 0 && index < size;
-        assert size > 0;
-        double height = getFigureWidget().getBounds().getHeight();
-        return height * (index + 1) / (size + 1);
+        boolean progress = false;
+        for(Figure f : diagramScene.getModel().getDiagramToView().getFigures()) {
+            for(Slot s : f.getSlots()) {
+                if(DiagramScene.doesIntersect(s.getSource().getSourceNodesAsSet(), slot.getSource().getSourceNodesAsSet())) {
+                    progress = true;
+                    hiddenNodes.removeAll(f.getSource().getSourceNodesAsSet());
+                }
+            }
+        }
+
+        if(progress) {
+            this.diagramScene.getModel().showNot(hiddenNodes);
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/branding.jnlp	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE jnlp PUBLIC "-//Sun Microsystems, Inc//DTD JNLP Descriptor 6.0//EN" "http://java.sun.com/dtd/JNLP-6.0.dtd">
+<jnlp spec="1.0+" codebase="$$codebase">
+  <information>
+      <title>${app.title}</title>
+      <vendor>${app.title} vendor</vendor>
+      <description>${app.name} application</description>
+      <icon href="${app.icon}"/>
+  </information>
+  ${jnlp.permissions}
+  <resources>
+    ${jnlp.branding.jars}
+  </resources>
+  <component-desc/>
+</jnlp>  
--- a/src/share/tools/IdealGraphVisualizer/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,7 +1,7 @@
 currentVersion=IdealGraphVisualizer {0}
 LBL_splash_window_title=Starting IdealGraphVisualizer
 SPLASH_WIDTH=475
-SplashProgressBarBounds=0,268,473,6
+SplashProgressBarBounds=0,273,475,6
 SplashProgressBarColor=0xFFFFFF
-SplashRunningTextBounds=269,253,205,12
+SplashRunningTextBounds=10,283,460,12
 SplashRunningTextColor=0xFFFFFF
Binary file src/share/tools/IdealGraphVisualizer/branding/core/core.jar/org/netbeans/core/startup/frame.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/branding/core/core.jar/org/netbeans/core/startup/frame32.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/branding/core/core.jar/org/netbeans/core/startup/frame48.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/branding/core/core.jar/org/netbeans/core/startup/splash.gif has changed
--- a/src/share/tools/IdealGraphVisualizer/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,2 +1,2 @@
-CTL_MainWindow_Title=IdealGraphVisualizer {0}
-CTL_MainWindow_Title_No_Project=IdealGraphVisualizer {0}
+CTL_MainWindow_Title=IdealGraphVisualizer
+CTL_MainWindow_Title_No_Project=IdealGraphVisualizer
--- a/src/share/tools/IdealGraphVisualizer/build.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -5,4 +5,12 @@
 <project name="IdealGraphVisualizer" basedir=".">
     <description>Builds the module suite IdealGraphVisualizer.</description>
     <import file="nbproject/build-impl.xml"/>
+    
+    <target name="build-launchers" depends="suite.build-launchers">
+        <!-- Drop memory presets (-Xms, -Xmx) from default_options of packaged builds and let the executing VM choose reasonable defaults -->
+        <replaceregexp file="${build.launcher.dir}/etc/${app.name}.conf" byline="true" match="^default_options=.*" replace='default_options="--branding idealgraphvisualizer"' />
+    </target>
+    
+    <!-- Local (environment-specific) extensions/modifications to the build -->
+    <import file="build-local.xml" optional="true" />
 </project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/master.jnlp	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE jnlp PUBLIC "-//Sun Microsystems, Inc//DTD JNLP Descriptor 6.0//EN" "http://java.sun.com/dtd/JNLP-6.0.dtd">
+<jnlp spec="1.0+" codebase="$$codebase" href="master.jnlp">
+  <information>
+      <title>Ideal Graph Visualizer</title>
+      <vendor>Ideal Graph Visualizer Team</vendor>
+      <description>A graph visualization tool designed for analyzing evolving compiler graphs. It was originally designed for the ideal graph in the HotSpot server compiler, but can be used to visualize arbitrary graph data structures.</description>
+      <icon href="${app.icon}"/>
+  </information>
+  <security><all-permissions/></security>
+  <resources>
+    <!-- The following property is needed when running with unsigned jars: -->
+    <property name="netbeans.jnlp.fixPolicy" value="${netbeans.jnlp.fixPolicy}"/>
+    <extension name='branding' href='branding.jnlp' />
+<!-- The following line will be replaced with an automatically generated list of resources: -->
+<!--${jnlp.resources}-->
+  </resources>
+  <resources os="Mac OS X">
+      <property name="netbeans.user" value="${user.home}/Library/Application Support/${app.name}"/>
+  </resources>
+  <application-desc>
+    <argument>--branding</argument>
+    <argument>${branding.token}</argument>
+  </application-desc>
+</jnlp>  
--- a/src/share/tools/IdealGraphVisualizer/nbproject/build-impl.xml	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -4,6 +4,13 @@
 ***         EDIT ../build.xml INSTEAD         ***
 -->
 <project name="IdealGraphVisualizer-impl" basedir=".." xmlns:sproject="http://www.netbeans.org/ns/nb-module-suite-project/1">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
     <property file="nbproject/private/platform-private.properties"/>
     <property file="nbproject/platform.properties"/>
     <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">
@@ -13,13 +20,29 @@
             <property name="@{name}" value="${@{value}}"/>
         </sequential>
     </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
     <property file="${user.properties.file}"/>
     <sproject:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir"/>
-    <sproject:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir"/>
-    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+    <sproject:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir"/>
+    <sproject:evalprops property="cluster.path.evaluated" value="${cluster.path}"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
         <condition>
             <not>
-                <available file="${harness.dir}" type="dir"/>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <ant antfile="nbproject/platform.xml"/>
+    <fail message="Cannot find NetBeans build harness. ${line.separator}Check that nbplatform.${nbplatform.active}.netbeans.dest.dir and nbplatform.${nbplatform.active}.harness.dir are defined. ${line.separator}On a developer machine these are normally defined in ${user.properties.file}=${netbeans.user}/build.properties ${line.separator}but for automated builds you should pass these properties to Ant explicitly. ${line.separator}You may instead download the harness and platform: -Dbootstrap.url=.../tasks.jar -Dautoupdate.catalog.url=.../updates.xml">
+        <condition>
+            <not>
+                <available file="${harness.dir}/suite.xml"/>
             </not>
         </condition>
     </fail>
--- a/src/share/tools/IdealGraphVisualizer/nbproject/genfiles.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,8 +1,11 @@
-build.xml.data.CRC32=72833581
-build.xml.script.CRC32=e9c757c5
-build.xml.stylesheet.CRC32=531c622b
+build.xml.data.CRC32=3c2c6126
+build.xml.script.CRC32=48934e60
+build.xml.stylesheet.CRC32=eaf9f76a@1.45.1
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=72833581
-nbproject/build-impl.xml.script.CRC32=1b6f3648
-nbproject/build-impl.xml.stylesheet.CRC32=196c7090
+nbproject/build-impl.xml.data.CRC32=3c2c6126
+nbproject/build-impl.xml.script.CRC32=b26e57e5
+nbproject/build-impl.xml.stylesheet.CRC32=0f381476@2.47.1
+nbproject/platform.xml.data.CRC32=3c2c6126
+nbproject/platform.xml.script.CRC32=db9e1f43
+nbproject/platform.xml.stylesheet.CRC32=df8ac4dd@2.47.1
--- a/src/share/tools/IdealGraphVisualizer/nbproject/platform.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/nbproject/platform.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,29 +1,204 @@
-# Deprecated since 5.0u1; for compatibility with 5.0:
-disabled.clusters=\
-    apisupport1,\
-    gsf1,\
-    harness,\
-    ide9,\
-    java2,\
-    nb6.1,\
-    profiler3
+cluster.path=\
+    ${nbplatform.active.dir}/ide:\
+    ${nbplatform.active.dir}/platform
 disabled.modules=\
+    com.jcraft.jsch,\
+    com.jcraft.jzlib,\
+    org.apache.commons.codec,\
+    org.apache.commons.httpclient,\
+    org.apache.commons.io,\
+    org.apache.commons.lang,\
+    org.apache.commons.logging,\
+    org.apache.ws.commons.util,\
+    org.apache.xml.resolver,\
+    org.apache.xmlrpc,\
+    org.eclipse.core.contenttype,\
+    org.eclipse.core.jobs,\
+    org.eclipse.core.net,\
+    org.eclipse.core.runtime,\
+    org.eclipse.core.runtime.compatibility.auth,\
+    org.eclipse.equinox.app,\
+    org.eclipse.equinox.common,\
+    org.eclipse.equinox.preferences,\
+    org.eclipse.equinox.registry,\
+    org.eclipse.equinox.security,\
+    org.eclipse.jgit,\
+    org.eclipse.mylyn.bugzilla.core,\
+    org.eclipse.mylyn.commons.core,\
+    org.eclipse.mylyn.commons.net,\
+    org.eclipse.mylyn.commons.xmlrpc,\
+    org.eclipse.mylyn.tasks.core,\
+    org.mozilla.rhino.patched,\
+    org.netbeans.api.debugger,\
+    org.netbeans.api.java.classpath,\
+    org.netbeans.api.xml,\
+    org.netbeans.core.browser,\
     org.netbeans.core.execution,\
+    org.netbeans.core.ide,\
+    org.netbeans.core.io.ui,\
     org.netbeans.core.multiview,\
-    org.netbeans.core.output2,\
+    org.netbeans.core.nativeaccess,\
+    org.netbeans.core.osgi,\
+    org.netbeans.lib.cvsclient,\
+    org.netbeans.lib.terminalemulator,\
+    org.netbeans.libs.antlr3.runtime,\
+    org.netbeans.libs.bytelist,\
+    org.netbeans.libs.commons_net,\
+    org.netbeans.libs.freemarker,\
+    org.netbeans.libs.git,\
+    org.netbeans.libs.ini4j,\
+    org.netbeans.libs.jaxb,\
+    org.netbeans.libs.jsr223,\
+    org.netbeans.libs.junit4,\
+    org.netbeans.libs.jvyamlb,\
+    org.netbeans.libs.lucene,\
+    org.netbeans.libs.smack,\
+    org.netbeans.libs.svnClientAdapter,\
+    org.netbeans.libs.svnClientAdapter.javahl,\
+    org.netbeans.libs.svnClientAdapter.svnkit,\
+    org.netbeans.libs.swingx,\
+    org.netbeans.libs.xerces,\
     org.netbeans.modules.autoupdate.services,\
     org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.bugtracking,\
+    org.netbeans.modules.bugtracking.bridge,\
+    org.netbeans.modules.bugzilla,\
     org.netbeans.modules.core.kit,\
+    org.netbeans.modules.csl.api,\
+    org.netbeans.modules.css.editor,\
+    org.netbeans.modules.css.lib,\
+    org.netbeans.modules.css.visual,\
+    org.netbeans.modules.db,\
+    org.netbeans.modules.db.core,\
+    org.netbeans.modules.db.dataview,\
+    org.netbeans.modules.db.drivers,\
+    org.netbeans.modules.db.kit,\
+    org.netbeans.modules.db.metadata.model,\
+    org.netbeans.modules.db.mysql,\
+    org.netbeans.modules.db.sql.editor,\
+    org.netbeans.modules.db.sql.visualeditor,\
+    org.netbeans.modules.dbapi,\
+    org.netbeans.modules.defaults,\
+    org.netbeans.modules.derby,\
+    org.netbeans.modules.dlight.nativeexecution,\
+    org.netbeans.modules.dlight.terminal,\
+    org.netbeans.modules.editor.bookmarks,\
+    org.netbeans.modules.editor.bracesmatching,\
+    org.netbeans.modules.editor.codetemplates,\
+    org.netbeans.modules.editor.completion,\
+    org.netbeans.modules.editor.guards,\
+    org.netbeans.modules.editor.indent.project,\
+    org.netbeans.modules.editor.kit,\
+    org.netbeans.modules.editor.macros,\
+    org.netbeans.modules.editor.structure,\
+    org.netbeans.modules.extbrowser,\
+    org.netbeans.modules.extexecution,\
+    org.netbeans.modules.extexecution.destroy,\
     org.netbeans.modules.favorites,\
-    org.netbeans.modules.javahelp,\
-    org.netbeans.modules.masterfs,\
-    org.netbeans.modules.options.keymap,\
-    org.netbeans.modules.sendopts,\
-    org.netbeans.modules.templates,\
+    org.netbeans.modules.git,\
+    org.netbeans.modules.glassfish.common,\
+    org.netbeans.modules.gototest,\
+    org.netbeans.modules.gsf.codecoverage,\
+    org.netbeans.modules.gsf.testrunner,\
+    org.netbeans.modules.html,\
+    org.netbeans.modules.html.editor,\
+    org.netbeans.modules.html.editor.lib,\
+    org.netbeans.modules.html.lexer,\
+    org.netbeans.modules.html.parser,\
+    org.netbeans.modules.html.validation,\
+    org.netbeans.modules.httpserver,\
+    org.netbeans.modules.hudson,\
+    org.netbeans.modules.hudson.git,\
+    org.netbeans.modules.hudson.mercurial,\
+    org.netbeans.modules.hudson.subversion,\
+    org.netbeans.modules.hudson.tasklist,\
+    org.netbeans.modules.ide.kit,\
+    org.netbeans.modules.image,\
+    org.netbeans.modules.javascript.editing,\
+    org.netbeans.modules.javascript.hints,\
+    org.netbeans.modules.javascript.kit,\
+    org.netbeans.modules.javascript.refactoring,\
+    org.netbeans.modules.jellytools.ide,\
+    org.netbeans.modules.jumpto,\
+    org.netbeans.modules.keyring.impl,\
+    org.netbeans.modules.languages,\
+    org.netbeans.modules.languages.diff,\
+    org.netbeans.modules.languages.manifest,\
+    org.netbeans.modules.languages.yaml,\
+    org.netbeans.modules.lexer.nbbridge,\
+    org.netbeans.modules.localhistory,\
+    org.netbeans.modules.mercurial,\
+    org.netbeans.modules.netbinox,\
+    org.netbeans.modules.parsing.api,\
+    org.netbeans.modules.parsing.lucene,\
+    org.netbeans.modules.print.editor,\
+    org.netbeans.modules.project.ant,\
+    org.netbeans.modules.project.libraries,\
+    org.netbeans.modules.projectui,\
+    org.netbeans.modules.projectui.buildmenu,\
+    org.netbeans.modules.projectuiapi,\
+    org.netbeans.modules.properties,\
+    org.netbeans.modules.properties.syntax,\
+    org.netbeans.modules.refactoring.api,\
+    org.netbeans.modules.schema2beans,\
+    org.netbeans.modules.server,\
+    org.netbeans.modules.servletapi,\
+    org.netbeans.modules.spellchecker,\
+    org.netbeans.modules.spellchecker.apimodule,\
+    org.netbeans.modules.spellchecker.bindings.htmlxml,\
+    org.netbeans.modules.spellchecker.bindings.properties,\
+    org.netbeans.modules.spellchecker.dictionary_en,\
+    org.netbeans.modules.spellchecker.kit,\
+    org.netbeans.modules.spi.actions,\
+    org.netbeans.modules.subversion,\
+    org.netbeans.modules.swing.validation,\
+    org.netbeans.modules.target.iterator,\
+    org.netbeans.modules.tasklist.kit,\
+    org.netbeans.modules.tasklist.projectint,\
+    org.netbeans.modules.tasklist.todo,\
+    org.netbeans.modules.tasklist.ui,\
+    org.netbeans.modules.terminal,\
+    org.netbeans.modules.usersguide,\
+    org.netbeans.modules.utilities,\
+    org.netbeans.modules.utilities.project,\
+    org.netbeans.modules.versioning,\
+    org.netbeans.modules.versioning.indexingbridge,\
+    org.netbeans.modules.versioning.system.cvss.installer,\
+    org.netbeans.modules.versioning.util,\
+    org.netbeans.modules.web.client.tools.api,\
+    org.netbeans.modules.web.common,\
+    org.netbeans.modules.web.indent,\
+    org.netbeans.modules.xml,\
+    org.netbeans.modules.xml.axi,\
+    org.netbeans.modules.xml.catalog,\
+    org.netbeans.modules.xml.core,\
+    org.netbeans.modules.xml.jaxb.api,\
+    org.netbeans.modules.xml.lexer,\
+    org.netbeans.modules.xml.multiview,\
+    org.netbeans.modules.xml.retriever,\
+    org.netbeans.modules.xml.schema.completion,\
+    org.netbeans.modules.xml.schema.model,\
+    org.netbeans.modules.xml.tax,\
+    org.netbeans.modules.xml.text,\
+    org.netbeans.modules.xml.tools,\
+    org.netbeans.modules.xml.wsdl.model,\
+    org.netbeans.modules.xml.xam,\
+    org.netbeans.modules.xml.xdm,\
+    org.netbeans.modules.xsl,\
+    org.netbeans.spi.debugger.ui,\
+    org.netbeans.spi.editor.hints,\
+    org.netbeans.spi.navigator,\
+    org.netbeans.spi.palette,\
+    org.netbeans.spi.tasklist,\
+    org.netbeans.spi.viewmodel,\
+    org.netbeans.swing.dirchooser,\
     org.openide.compat,\
     org.openide.execution,\
+    org.openide.options,\
     org.openide.util.enumerations
-enabled.clusters=\
-    platform8
-nbjdk.active=default
+## Not disabled because of NetBeans bug 206347:
+## Applications not using OSGi don't start on NbP 7.1
+#   org.netbeans.core.netigso,\
+#   org.netbeans.libs.felix,\
+#   org.netbeans.libs.osgi,\
 nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/nbproject/platform.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="platform" default="download" basedir="..">
+    <condition property="download.required">
+        <and>
+            <not>
+                <available file="${harness.dir}/suite.xml"/>
+            </not>
+            <isset property="bootstrap.url"/>
+            <isset property="autoupdate.catalog.url"/>
+        </and>
+    </condition>
+    <target name="download" if="download.required">
+        <mkdir dir="${harness.dir}"/>
+        <pathconvert pathsep="|" property="download.clusters">
+            <mapper type="flatten"/>
+            <path path="${cluster.path}"/>
+        </pathconvert>
+        <property name="disabled.modules" value=""/>
+        <pathconvert property="module.includes" pathsep="">
+            <mapper type="glob" from="${basedir}${file.separator}*" to="(?!\Q*\E)"/>
+            <path>
+                <filelist files="${disabled.modules}" dir="."/>
+            </path>
+        </pathconvert>
+        <echo message="Downloading clusters ${download.clusters}"/>
+        <property name="tasks.jar" location="${java.io.tmpdir}/tasks.jar"/>
+        <get src="${bootstrap.url}" dest="${tasks.jar}" usetimestamp="true" verbose="true"/>
+        <taskdef name="autoupdate" classname="org.netbeans.nbbuild.AutoUpdate" classpath="${tasks.jar}"/>
+        <autoupdate installdir="${nbplatform.active.dir}" updatecenter="${autoupdate.catalog.url}">
+            <modules includes="${module.includes}.*" clusters="${download.clusters}"/>
+            <modules includes="org[.]netbeans[.]modules[.]apisupport[.]harness" clusters="harness"/>
+        </autoupdate>
+    </target>
+</project>
--- a/src/share/tools/IdealGraphVisualizer/nbproject/project.properties	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/IdealGraphVisualizer/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -1,39 +1,44 @@
-app.icon=branding/core/core.jar/org/netbeans/core/startup/frame48.gif
-app.name=idealgraphvisualizer
-app.title=IdealGraphVisualizer
-branding.token=${app.name}
-modules=\
-    ${project.com.sun.hotspot.igv.graph}:\
-    ${project.com.sun.hotspot.igv.coordinator}:\
-    ${project.com.sun.hotspot.igv.filter}:\
-    ${project.com.sun.hotspot.igv.hierarchicallayout}:\
-    ${project.com.sun.hotspot.igv.layout}:\
-    ${project.com.sun.hotspot.igv.controlflow}:\
-    ${project.com.sun.hotspot.igv.data}:\
-    ${project.com.sun.hotspot.igv.view}:\
-    ${project.com.sun.hotspot.igv.bytecodes}:\
-    ${project.com.sun.hotspot.igv.difference}:\
-    ${project.com.sun.hotspot.igv.settings}:\
-    ${project.com.sun.hotspot.igv.util}:\
-    ${project.com.sun.hotspot.igv.svg}:\
-    ${project.com.sun.hotspot.connection}:\
-    ${project.com.sun.hotspot.igv.servercompilerscheduler}:\
-    ${project.com.sun.hotspot.igv.filterwindow}
-project.com.sun.hotspot.connection=NetworkConnection
-project.com.sun.hotspot.igv.bytecodes=Bytecodes
-project.com.sun.hotspot.igv.controlflow=ControlFlow
-project.com.sun.hotspot.igv.coordinator=Coordinator
-project.com.sun.hotspot.igv.data=Data
-project.com.sun.hotspot.igv.difference=Difference
-project.com.sun.hotspot.igv.filter=Filter
-project.com.sun.hotspot.igv.filterwindow=FilterWindow
-project.com.sun.hotspot.igv.graph=Graph
-project.com.sun.hotspot.igv.hierarchicallayout=HierarchicalLayout
-project.com.sun.hotspot.igv.layout=Layout
-project.com.sun.hotspot.igv.servercompilerscheduler=ServerCompiler
-project.com.sun.hotspot.igv.settings=Settings
-project.com.sun.hotspot.igv.svg=BatikSVGProxy
-project.com.sun.hotspot.igv.view=View
-project.com.sun.hotspot.igv.util=Util
-run.args = -J-server -J-Xms64m -J-Xmx1g -J-da
-run.args.extra = -J-server -J-Xms64m -J-Xmx1g -J-da
+app.icon=branding/core/core.jar/org/netbeans/core/startup/frame48.gif
+app.name=idealgraphvisualizer
+app.title=IdealGraphVisualizer
+branding.token=${app.name}
+modules=\
+    ${project.com.sun.hotspot.igv.graph}:\
+    ${project.com.sun.hotspot.igv.coordinator}:\
+    ${project.com.sun.hotspot.igv.filter}:\
+    ${project.com.sun.hotspot.igv.hierarchicallayout}:\
+    ${project.com.sun.hotspot.igv.layout}:\
+    ${project.com.sun.hotspot.igv.data}:\
+    ${project.com.sun.hotspot.igv.view}:\
+    ${project.com.sun.hotspot.igv.bytecodes}:\
+    ${project.com.sun.hotspot.igv.difference}:\
+    ${project.com.sun.hotspot.igv.settings}:\
+    ${project.com.sun.hotspot.igv.util}:\
+    ${project.com.sun.hotspot.igv.svg}:\
+    ${project.com.sun.hotspot.connection}:\
+    ${project.com.sun.hotspot.igv.servercompilerscheduler}:\
+    ${project.com.sun.hotspot.igv.filterwindow}:\
+    ${project.com.sun.hotspot.igv.selectioncoordinator}:\
+    ${project.com.sun.hotspot.igv.graal}
+project.com.sun.hotspot.connection=NetworkConnection
+project.com.sun.hotspot.igv.bytecodes=Bytecodes
+project.com.sun.hotspot.igv.coordinator=Coordinator
+project.com.sun.hotspot.igv.data=Data
+project.com.sun.hotspot.igv.difference=Difference
+project.com.sun.hotspot.igv.filter=Filter
+project.com.sun.hotspot.igv.filterwindow=FilterWindow
+project.com.sun.hotspot.igv.graal=Graal
+project.com.sun.hotspot.igv.graph=Graph
+project.com.sun.hotspot.igv.hierarchicallayout=HierarchicalLayout
+project.com.sun.hotspot.igv.layout=Layout
+project.com.sun.hotspot.igv.selectioncoordinator=SelectionCoordinator
+project.com.sun.hotspot.igv.servercompilerscheduler=ServerCompiler
+project.com.sun.hotspot.igv.settings=Settings
+project.com.sun.hotspot.igv.svg=BatikSVGProxy
+project.com.sun.hotspot.igv.view=View
+project.com.sun.hotspot.igv.util=Util
+
+# Disable assertions for RequestProcessor to prevent annoying messages in case
+# of multiple SceneAnimator update tasks in the default RequestProcessor.
+run.args.extra = -J-server -J-da:org.openide.util.RequestProcessor -J-Xms2g -J-Xmx2g
+debug.args.extra = -J-server -J-da:org.openide.util.RequestProcessor
--- a/src/share/tools/ProjectCreator/BuildConfig.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/ProjectCreator/BuildConfig.java	Mon Feb 27 13:10:13 2012 +0100
@@ -64,6 +64,25 @@
         String buildBase = expandFormat(getFieldString(null, "BuildBase"));
         String sourceBase = getFieldString(null, "SourceBase");
         String outDir = buildBase;
+        String value = System.getenv("OUT_DIR");
+        if (value != null) {
+            outDir = value;
+        }
+        
+        int lastDirectorySeparator = Math.max(outDir.lastIndexOf("/"), outDir.lastIndexOf("\\"));
+        if (lastDirectorySeparator >= 0) {
+            outDir = outDir.substring(0, lastDirectorySeparator);
+        }
+        
+        outDir += Util.sep + build + Util.sep + "jre" + Util.sep + "bin";
+        if (flavour.equals("graal")) {
+            outDir += Util.sep + "graal";
+        } else if (flavour.equals("compiler1")) {
+            outDir += Util.sep + "client";
+        } else {
+            outDir += Util.sep + "server";
+        }
+        buildBase = outDir;
 
         put("Id", flavourBuild);
         put("OutputDir", outDir);
@@ -106,7 +125,6 @@
         tree.addSubdirToIgnore("Codemgr_wsdata");
         tree.addSubdirToIgnore("deleted_files");
         tree.addSubdirToIgnore("SCCS");
-        tree.setVerbose(true);
         if (startAt != null) {
             tree.readDirectory(sourceBase + File.separator + startAt);
         } else {
@@ -239,7 +257,19 @@
 
     void initDefaultDefines(Vector defines) {
         Vector sysDefines = new Vector();
-        sysDefines.add("WIN32");
+
+        if( vars.get("PlatformName").equals("Win32")) {
+            sysDefines.add("WIN32");
+        } else {
+            sysDefines.add("_AMD64_");
+            sysDefines.add("AMD64");
+            sysDefines.add("_WIN64");
+            sysDefines.add("_LP64");
+            if (System.getenv("MSC_VER") != null)
+               sysDefines.add("MSC_VER=" + System.getenv("MSC_VER"));
+            sysDefines.add("HOTSPOT_LIB_ARCH=\\\"amd64\\\"");
+        }
+	
         sysDefines.add("_WINDOWS");
         sysDefines.add("HOTSPOT_BUILD_USER=\\\""+System.getProperty("user.name")+"\\\"");
         sysDefines.add("HOTSPOT_BUILD_TARGET=\\\""+get("Build")+"\\\"");
@@ -315,6 +345,10 @@
         return get("Build");
     }
 
+    String outputDir() {
+        return get("OutputDir");
+    }
+
     Object getSpecificField(String field) {
         return getField(get("Id"), field);
     }
@@ -503,6 +537,9 @@
                 case 'f':
                     sb.append(flavour());
                     break;
+		case 'o':
+		    sb.append(outputDir());
+		    break;
                 default:
                     sb.append(ch);
                     sb.append(ch1);
@@ -538,6 +575,28 @@
    }
 }
 
+class GraalDebugConfig extends GenericDebugNonKernelConfig {
+    String getOptFlag() {
+        return getCI().getNoOptFlag();
+    }
+
+    GraalDebugConfig() {
+        initNames("graal", "debug", "jvm.dll");
+        init(getIncludes(), getDefines());
+    }
+}
+
+class GraalFastDebugConfig extends GenericDebugNonKernelConfig {
+    String getOptFlag() {
+        return getCI().getOptFlag();
+    }
+
+    GraalFastDebugConfig() {
+        initNames("graal", "fastdebug", "jvm.dll");
+        init(getIncludes(), getDefines());
+    }
+}
+
 class C1DebugConfig extends GenericDebugNonKernelConfig {
     String getOptFlag() {
         return getCI().getNoOptFlag();
@@ -617,6 +676,13 @@
     }
 }
 
+class GraalProductConfig extends ProductConfig {
+    GraalProductConfig() {
+        initNames("graal", "product", "jvm.dll");
+        init(getIncludes(), getDefines());
+    }
+}
+
 class C1ProductConfig extends ProductConfig {
     C1ProductConfig() {
         initNames("compiler1", "product", "jvm.dll");
--- a/src/share/tools/ProjectCreator/WinGammaPlatform.java	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/tools/ProjectCreator/WinGammaPlatform.java	Mon Feb 27 13:10:13 2012 +0100
@@ -586,6 +586,10 @@
     Vector createAllConfigs(String platform) {
         Vector allConfigs = new Vector();
 
+        allConfigs.add(new GraalDebugConfig());
+        allConfigs.add(new GraalFastDebugConfig());
+        allConfigs.add(new GraalProductConfig());
+
         allConfigs.add(new C1DebugConfig());
         allConfigs.add(new C1FastDebugConfig());
         allConfigs.add(new C1ProductConfig());
--- a/src/share/vm/c1/c1_IR.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/c1/c1_IR.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -240,7 +240,8 @@
     // reexecute allowed only for the topmost frame
     bool reexecute = topmost ? should_reexecute() : false;
     bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis.
-    recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, is_method_handle_invoke, return_oop, locvals, expvals, monvals);
+    methodHandle null_mh;
+    recorder->describe_scope(pc_offset, null_mh, scope()->method(), bci(), reexecute, false, is_method_handle_invoke, return_oop, locvals, expvals, monvals);
   }
 };
 
--- a/src/share/vm/c1/c1_LIRAssembler.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/c1/c1_LIRAssembler.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -405,7 +405,8 @@
     if (s == NULL)  break;
     IRScope* scope = s->scope();
     //Always pass false for reexecute since these ScopeDescs are never used for deopt
-    debug_info->describe_scope(pc_offset, scope->method(), s->bci(), false/*reexecute*/);
+    methodHandle null_mh;
+    debug_info->describe_scope(pc_offset, null_mh, scope->method(), s->bci(), false/*reexecute*/);
   }
 
   debug_info->end_non_safepoint(pc_offset);
--- a/src/share/vm/c1/c1_LIRGenerator.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -2798,7 +2798,7 @@
 
       // Load CallSite object from constant pool cache.
       __ oop2reg(cpcache->constant_encoding(), tmp);
-      __ move_wide(new LIR_Address(tmp, call_site_offset, T_OBJECT), tmp);
+      __ move_wide(new LIR_Address(tmp, (int)call_site_offset, T_OBJECT), tmp);
 
       // Load target MethodHandle from CallSite object.
       __ load(new LIR_Address(tmp, java_lang_invoke_CallSite::target_offset_in_bytes(), T_OBJECT), receiver);
--- a/src/share/vm/c1/c1_Runtime1.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/c1/c1_Runtime1.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -201,8 +201,16 @@
     case slow_subtype_check_id:
     case fpu2long_stub_id:
     case unwind_exception_id:
-    case counter_overflow_id:
-#if defined(SPARC) || defined(PPC)
+    case graal_verify_pointer_id:
+    case graal_unwind_exception_call_id:
+    case graal_slow_subtype_check_id:
+    case graal_arithmetic_frem_id:
+    case graal_arithmetic_drem_id:
+    case graal_set_deopt_info_id:
+#ifndef TIERED
+    case counter_overflow_id: // Not generated outside the tiered world
+#endif
+#ifdef SPARC
     case handle_exception_nofpu_id:  // Unused on sparc
 #endif
       break;
@@ -546,7 +554,7 @@
     thread->set_exception_pc(pc);
 
     // the exception cache is used only by non-implicit exceptions
-    if (continuation != NULL) {
+    if (continuation != NULL && !SharedRuntime::deopt_blob()->contains(continuation)) {
       nm->add_handler_for_exception_and_pc(exception, pc, continuation);
     }
   }
@@ -583,7 +591,6 @@
     continuation = exception_handler_for_pc_helper(thread, exception, pc, nm);
   }
   // Back in JAVA, use no oops DON'T safepoint
-
   // Now check to see if the nmethod we were called from is now deoptimized.
   // If so we must return to the deopt blob and deoptimize the nmethod
   if (nm != NULL && caller_is_deopted()) {
@@ -640,15 +647,86 @@
 JRT_END
 
 
-JRT_ENTRY_NO_ASYNC(void, Runtime1::monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock))
+JRT_ENTRY_NO_ASYNC(void, Runtime1::graal_monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock))
   NOT_PRODUCT(_monitorenter_slowcase_cnt++;)
+#ifdef ASSERT
+  if (TraceGraal >= 3) {
+    tty->print_cr("entered locking slow case with obj=" INTPTR_FORMAT " and lock= " INTPTR_FORMAT, obj, lock);
+  }
   if (PrintBiasedLockingStatistics) {
     Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
   }
+#endif
   Handle h_obj(thread, obj);
   assert(h_obj()->is_oop(), "must be NULL or an object");
   if (UseBiasedLocking) {
     // Retry fast entry if bias is revoked to avoid unnecessary inflation
+    ObjectSynchronizer::fast_enter(h_obj, lock, true, CHECK);
+  } else {
+    if (UseFastLocking) {
+      // When using fast locking, the compiled code has already tried the fast case
+      ObjectSynchronizer::slow_enter(h_obj, lock, THREAD);
+    } else {
+      ObjectSynchronizer::fast_enter(h_obj, lock, false, THREAD);
+    }
+  }
+#ifdef ASSERT
+  if (TraceGraal >= 3) {
+    tty->print_cr("exiting locking");
+    tty->print_cr("");
+    tty->print_cr("done");
+  }
+#endif
+JRT_END
+
+
+JRT_LEAF(void, Runtime1::graal_monitorexit(JavaThread* thread, oopDesc* obj, BasicLock* lock))
+  NOT_PRODUCT(_monitorexit_slowcase_cnt++;)
+  assert(thread == JavaThread::current(), "threads must correspond");
+  assert(thread->last_Java_sp(), "last_Java_sp must be set");
+  // monitorexit is non-blocking (leaf routine) => no exceptions can be thrown
+  EXCEPTION_MARK;
+
+#ifdef DEBUG
+  if (!obj->is_oop()) {
+    ResetNoHandleMark rhm;
+    nmethod* method = thread->last_frame().cb()->as_nmethod_or_null();
+    if (method != NULL) {
+      tty->print_cr("ERROR in monitorexit in method %s wrong obj " INTPTR_FORMAT, method->name(), obj);
+    }
+    thread->print_stack_on(tty);
+    assert(false, "invalid lock object pointer dected");
+  }
+#endif
+
+  if (UseFastLocking) {
+    // When using fast locking, the compiled code has already tried the fast case
+    ObjectSynchronizer::slow_exit(obj, lock, THREAD);
+  } else {
+    ObjectSynchronizer::fast_exit(obj, lock, THREAD);
+  }
+JRT_END
+
+
+JRT_ENTRY_NO_ASYNC(void, Runtime1::monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock))
+  NOT_PRODUCT(_monitorenter_slowcase_cnt++;)
+#ifdef ASSERT
+  if (TraceGraal >= 3) {
+    tty->print_cr("entered locking slow case with obj=" INTPTR_FORMAT " and lock= " INTPTR_FORMAT, obj, lock);
+  }
+  if (PrintBiasedLockingStatistics) {
+    Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
+  }
+#endif
+  Handle h_obj(thread, obj);
+  assert(h_obj()->is_oop(), "must be NULL or an object");
+  if (UseBiasedLocking) {
+    if (UseFastLocking) {
+      assert(obj == lock->obj(), "must match");
+    } else {
+      lock->set_obj(obj);
+    }
+    // Retry fast entry if bias is revoked to avoid unnecessary inflation
     ObjectSynchronizer::fast_enter(h_obj, lock->lock(), true, CHECK);
   } else {
     if (UseFastLocking) {
@@ -660,6 +738,14 @@
       ObjectSynchronizer::fast_enter(h_obj, lock->lock(), false, THREAD);
     }
   }
+#ifdef ASSERT
+  if (TraceGraal >= 3) {
+    tty->print_cr("exiting locking lock state: obj=" INTPTR_FORMAT, lock->obj());
+    lock->lock()->print_on(tty);
+    tty->print_cr("");
+    tty->print_cr("done");
+  }
+#endif
 JRT_END
 
 
@@ -671,7 +757,19 @@
   EXCEPTION_MARK;
 
   oop obj = lock->obj();
-  assert(obj->is_oop(), "must be NULL or an object");
+
+#ifdef DEBUG
+  if (!obj->is_oop()) {
+    ResetNoHandleMark rhm;
+    nmethod* method = thread->last_frame().cb()->as_nmethod_or_null();
+    if (method != NULL) {
+      tty->print_cr("ERROR in monitorexit in method %s wrong obj " INTPTR_FORMAT, method->name(), obj);
+    }
+    thread->print_stack_on(tty);
+    assert(false, "invalid lock object pointer dected");
+  }
+#endif
+
   if (UseFastLocking) {
     // When using fast locking, the compiled code has already tried the fast case
     ObjectSynchronizer::slow_exit(obj, lock->lock(), THREAD);
@@ -880,7 +978,9 @@
           assert(k != NULL && !k->is_klass(), "must be class mirror or other Java constant");
         }
         break;
-      default: Unimplemented();
+      default:
+        tty->print_cr("Unhandled bytecode: %d stub_id=%d caller=%s bci=%d pc=%d", code, stub_id, caller_method->name()->as_C_string(), bci, caller_frame.pc());
+        Unimplemented();
     }
     // convert to handle
     load_klass = Handle(THREAD, k);
--- a/src/share/vm/c1/c1_Runtime1.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/c1/c1_Runtime1.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -70,6 +70,17 @@
   stub(g1_post_barrier_slow)         \
   stub(fpu2long_stub)                \
   stub(counter_overflow)             \
+  stub(graal_unwind_exception_call)  \
+  stub(graal_slow_subtype_check)     \
+  stub(graal_arithmetic_frem)        \
+  stub(graal_arithmetic_drem)        \
+  stub(graal_monitorenter)           \
+  stub(graal_monitorexit)            \
+  stub(graal_verify_pointer)         \
+  stub(graal_set_deopt_info)         \
+  stub(graal_create_null_pointer_exception) \
+  stub(graal_create_out_of_bounds_exception) \
+  stub(graal_generic_callback)       \
   last_entry(number_of_ids)
 
 #define DECLARE_STUB_ID(x)       x ## _id ,
@@ -150,6 +161,9 @@
   static void throw_incompatible_class_change_error(JavaThread* thread);
   static void throw_array_store_exception(JavaThread* thread, oopDesc* object);
 
+  static void graal_monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock);
+  static void graal_monitorexit (JavaThread* thread, oopDesc* obj, BasicLock* lock);
+
   static void monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock);
   static void monitorexit (JavaThread* thread, BasicObjectLock* lock);
 
--- a/src/share/vm/c1/c1_globals.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/c1/c1_globals.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -56,6 +56,14 @@
 //
 #define C1_FLAGS(develop, develop_pd, product, product_pd, notproduct)      \
                                                                             \
+  product(bool, DebugGraal, true,                                           \
+          "Enable JVMTI for the compiler thread")                           \
+  product(bool, BootstrapGraal, true,                                       \
+          "Bootstrap graal before running Java main method")                \
+  product(intx, TraceGraal, 0,                                              \
+          "Trace level for graal")                                          \
+  product(bool, TraceSignals, false,                                        \
+          "Trace signals and implicit exception handling")                  \
   /* Printing */                                                            \
   notproduct(bool, PrintC1Statistics, false,                                \
           "Print Compiler1 statistics" )                                    \
--- a/src/share/vm/ci/ciCallProfile.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/ci/ciCallProfile.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -61,6 +61,7 @@
   // Note:  The following predicates return false for invalid profiles:
   bool      has_receiver(int i) const { return _limit > i; }
   int       morphism() const          { return _morphism; }
+  int       limit() const             { return _limit; }
 
   int       count() const             { return _count; }
   int       receiver_count(int i)  {
--- a/src/share/vm/ci/ciEnv.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/ci/ciEnv.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -94,7 +94,7 @@
 // ciEnv::ciEnv
 ciEnv::ciEnv(CompileTask* task, int system_dictionary_modification_counter) {
   VM_ENTRY_MARK;
-
+  CompilerThread* compiler_thread = CompilerThread::current();
   // Set up ciEnv::current immediately, for the sake of ciObjectFactory, etc.
   thread->set_env(this);
   assert(ciEnv::current() == this, "sanity");
@@ -106,13 +106,13 @@
   _compilable = MethodCompilable;
   _break_at_compile = false;
   _compiler_data = NULL;
-#ifndef PRODUCT
-  assert(!firstEnv, "not initialized properly");
-#endif /* !PRODUCT */
+//#ifndef PRODUCT
+//  assert(!firstEnv, "not initialized properly");
+//#endif /* !PRODUCT */
 
   _system_dictionary_modification_counter = system_dictionary_modification_counter;
   _num_inlined_bytecodes = 0;
-  assert(task == NULL || thread->task() == task, "sanity");
+  assert(task == NULL || compiler_thread->task() == task, "sanity");
   _task = task;
   _log = NULL;
 
@@ -149,7 +149,7 @@
   ASSERT_IN_VM;
 
   // Set up ciEnv::current immediately, for the sake of ciObjectFactory, etc.
-  CompilerThread* current_thread = CompilerThread::current();
+  JavaThread* current_thread = JavaThread::current();
   assert(current_thread->env() == NULL, "must be");
   current_thread->set_env(this);
   assert(ciEnv::current() == this, "sanity");
@@ -161,10 +161,10 @@
   _compilable = MethodCompilable_never;
   _break_at_compile = false;
   _compiler_data = NULL;
-#ifndef PRODUCT
-  assert(firstEnv, "must be first");
-  firstEnv = false;
-#endif /* !PRODUCT */
+//#ifndef PRODUCT
+//  assert(firstEnv, "must be first");
+//  firstEnv = false;
+//#endif /* !PRODUCT */
 
   _system_dictionary_modification_counter = 0;
   _num_inlined_bytecodes = 0;
@@ -201,9 +201,8 @@
 }
 
 ciEnv::~ciEnv() {
-  CompilerThread* current_thread = CompilerThread::current();
   _factory->remove_symbols();
-  current_thread->set_env(NULL);
+  JavaThread::current()->set_env(NULL);
 }
 
 // ------------------------------------------------------------------
@@ -950,7 +949,7 @@
 
 // ------------------------------------------------------------------
 // ciEnv::register_method
-void ciEnv::register_method(ciMethod* target,
+nmethod* ciEnv::register_method(ciMethod* target,
                             int entry_bci,
                             CodeOffsets* offsets,
                             int orig_pc_offset,
@@ -1017,7 +1016,7 @@
       // If the code buffer is created on each compile attempt
       // as in C2, then it must be freed.
       code_buffer->free_blob();
-      return;
+      return NULL;
     }
 
     assert(offsets->value(CodeOffsets::Deopt) != -1, "must have deopt entry");
@@ -1104,6 +1103,7 @@
     nm->post_compiled_method_load_event();
   }
 
+  return nm;
 }
 
 
--- a/src/share/vm/ci/ciEnv.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/ci/ciEnv.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -105,6 +105,8 @@
   ciInstance* _the_null_string;      // The Java string "null"
   ciInstance* _the_min_jint_string; // The Java string "-2147483648"
 
+public:
+
   // Look up a klass by name from a particular class loader (the accessor's).
   // If require_local, result must be defined in that class loader, or NULL.
   // If !require_local, a result from remote class loader may be reported,
@@ -135,6 +137,8 @@
                                  int method_index, Bytecodes::Code bc,
                                  ciInstanceKlass* loading_klass);
 
+private:
+
   // Implementation methods for loading and constant pool access.
   ciKlass* get_klass_by_name_impl(ciKlass* accessing_klass,
                                   constantPoolHandle cpool,
@@ -165,6 +169,7 @@
                            Symbol*         sig,
                            Bytecodes::Code bc);
 
+  public:
   // Get a ciObject from the object factory.  Ensures uniqueness
   // of ciObjects.
   ciObject* get_object(oop o) {
@@ -174,6 +179,7 @@
       return _factory->get(o);
     }
   }
+  private:
 
   ciSymbol* get_symbol(Symbol* o) {
     if (o == NULL) {
@@ -322,7 +328,7 @@
   uint compile_id();  // task()->compile_id()
 
   // Register the result of a compilation.
-  void register_method(ciMethod*                 target,
+  nmethod* register_method(ciMethod*             target,
                        int                       entry_bci,
                        CodeOffsets*              offsets,
                        int                       orig_pc_offset,
@@ -393,10 +399,10 @@
   Arena*    arena() { return _arena; }
 
   // What is the current compilation environment?
-  static ciEnv* current() { return CompilerThread::current()->env(); }
+  static ciEnv* current() { return JavaThread::current()->env(); }
 
   // Overload with current thread argument
-  static ciEnv* current(CompilerThread *thread) { return thread->env(); }
+  static ciEnv* current(JavaThread *thread) { return thread->env(); }
 
   // Per-compiler data.  (Used by C2 to publish the Compile* pointer.)
   void* compiler_data() { return _compiler_data; }
--- a/src/share/vm/ci/ciField.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/ci/ciField.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -306,15 +306,20 @@
   return type;
 }
 
+bool ciField::will_link(ciInstanceKlass* accessing_klass,
+                        Bytecodes::Code bc) {
+  VM_ENTRY_MARK;
+  return will_link_from_vm(accessing_klass, bc);
+}
 
 // ------------------------------------------------------------------
 // ciField::will_link
 //
 // Can a specific access to this field be made without causing
 // link errors?
-bool ciField::will_link(ciInstanceKlass* accessing_klass,
+bool ciField::will_link_from_vm(ciInstanceKlass* accessing_klass,
                         Bytecodes::Code bc) {
-  VM_ENTRY_MARK;
+  Thread* THREAD = Thread::current();
   if (_offset == -1) {
     // at creation we couldn't link to our holder so we need to
     // maintain that stance, otherwise there's no safe way to use this
--- a/src/share/vm/ci/ciField.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/ci/ciField.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -165,6 +165,8 @@
   // at each point of access.
   bool will_link(ciInstanceKlass* accessing_klass,
                  Bytecodes::Code bc);
+  bool will_link_from_vm(ciInstanceKlass* accessing_klass,
+                 Bytecodes::Code bc);
 
   // Java access flags
   bool is_public      () { return flags().is_public(); }
--- a/src/share/vm/ci/ciKlass.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/ci/ciKlass.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -73,7 +73,7 @@
     return true;
   }
 
-  VM_ENTRY_MARK;
+  //VM_ENTRY_MARK;
   Klass* this_klass = get_Klass();
   klassOop that_klass = that->get_klassOop();
   bool result = this_klass->is_subtype_of(that_klass);
--- a/src/share/vm/ci/ciObject.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/ci/ciObject.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -70,12 +70,14 @@
   ciObject(Handle h);
   ciObject(ciKlass* klass);
 
+public:
   jobject      handle()  const { return _handle; }
   // Get the VM oop that this object holds.
   oop get_oop() const {
     assert(_handle != NULL, "null oop");
     return JNIHandles::resolve_non_null(_handle);
   }
+protected:
 
   void init_flags_from(oop x) {
     int flags = 0;
--- a/src/share/vm/ci/ciObjectFactory.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/ci/ciObjectFactory.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -88,9 +88,9 @@
 
   // If the shared ci objects exist append them to this factory's objects
 
-  if (_shared_ci_objects != NULL) {
+  /*if (_shared_ci_objects != NULL) {
     _ci_objects->appendAll(_shared_ci_objects);
-  }
+  }*/
 
   _unloaded_methods = new (arena) GrowableArray<ciMethod*>(arena, 4, 0, NULL);
   _unloaded_klasses = new (arena) GrowableArray<ciKlass*>(arena, 8, 0, NULL);
@@ -219,13 +219,15 @@
 
 
 ciSymbol* ciObjectFactory::get_symbol(Symbol* key) {
-  vmSymbols::SID sid = vmSymbols::find_sid(key);
+  /*vmSymbols::SID sid = vmSymbols::find_sid(key);
   if (sid != vmSymbols::NO_SID) {
     // do not pollute the main cache with it
-    return vm_symbol_at(sid);
-  }
+    ciSymbol* result = vm_symbol_at(sid);
+    assert(result != NULL, "");
+    return result;
+  }*/
 
-  assert(vmSymbols::find_sid(key) == vmSymbols::NO_SID, "");
+  //assert(vmSymbols::find_sid(key) == vmSymbols::NO_SID, "");
   ciSymbol* s = new (arena()) ciSymbol(key, vmSymbols::NO_SID);
   _symbols->push(s);
   return s;
--- a/src/share/vm/ci/ciSymbol.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/ci/ciSymbol.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -48,7 +48,7 @@
 
 private:
   const vmSymbols::SID _sid;
-  DEBUG_ONLY( bool sid_ok() { return vmSymbols::find_sid(get_symbol()) == _sid; } )
+  DEBUG_ONLY( bool sid_ok() { return true;/*vmSymbols::find_sid(get_symbol()) == _sid;*/ } )
 
   ciSymbol(Symbol* s);  // normal case, for symbols not mentioned in vmSymbols
   ciSymbol(Symbol* s, vmSymbols::SID sid);   // for use with vmSymbols
--- a/src/share/vm/ci/ciUtilities.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/ci/ciUtilities.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -36,7 +36,7 @@
 
 // Bring the compilation thread into the VM state.
 #define VM_ENTRY_MARK                       \
-  CompilerThread* thread=CompilerThread::current(); \
+  JavaThread* thread=JavaThread::current(); \
   ThreadInVMfromNative __tiv(thread);       \
   ResetNoHandleMark rnhm;                   \
   HandleMarkCleaner __hm(thread);           \
@@ -47,7 +47,7 @@
 
 // Bring the compilation thread into the VM state.  No handle mark.
 #define VM_QUICK_ENTRY_MARK                 \
-  CompilerThread* thread=CompilerThread::current(); \
+  JavaThread* thread=JavaThread::current(); \
   ThreadInVMfromNative __tiv(thread);       \
 /*                                          \
  * [TODO] The NoHandleMark line does nothing but declare a function prototype \
@@ -60,7 +60,7 @@
 
 
 #define EXCEPTION_CONTEXT \
-  CompilerThread* thread=CompilerThread::current(); \
+  JavaThread* thread=JavaThread::current(); \
   Thread* THREAD = thread;
 
 
--- a/src/share/vm/classfile/classLoader.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/classfile/classLoader.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -442,10 +442,23 @@
 void ClassLoader::setup_bootstrap_search_path() {
   assert(_first_entry == NULL, "should not setup bootstrap class search path twice");
   char* sys_class_path = os::strdup(Arguments::get_sysclasspath());
+#ifdef GRAAL
+  char* compiler_class_path = os::strdup(Arguments::get_compilerclasspath());
+#endif
   if (TraceClassLoading && Verbose) {
     tty->print_cr("[Bootstrap loader class path=%s]", sys_class_path);
+#ifdef GRAAL
+    tty->print_cr("[Compiler loader class path=%s]", compiler_class_path);
+#endif
   }
 
+  setup_bootstrap_search_path(sys_class_path);
+#ifdef GRAAL
+  setup_bootstrap_search_path(compiler_class_path);
+#endif
+}
+
+void ClassLoader::setup_bootstrap_search_path(char* sys_class_path) {
   int len = (int)strlen(sys_class_path);
   int end = 0;
 
@@ -553,7 +566,7 @@
   ClassPathEntry* e = _first_entry;
   while (e != NULL) {
     // assume zip entries have been canonicalized
-    if (strcmp(entry->name(), e->name()) == 0) {
+	if (strcmp(entry->name(), e->name()) == 0) {
       return true;
     }
     e = e->next();
@@ -893,7 +906,23 @@
     PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(),
                                ((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(),
                                PerfClassTraceTime::CLASS_LOAD);
-    ClassPathEntry* e = _first_entry;
+    ClassPathEntry* e = _first_entry; 
+    while (e != NULL) {
+      stream = e->open_stream(name);
+      if (stream != NULL) {
+        break;
+      }
+      e = e->next();
+      ++classpath_index;
+    }
+  }
+
+  if (stream == NULL && !(THREAD->is_Compiler_thread())) {  
+	  classpath_index = 0;
+    PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(),
+                               ((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(),
+                               PerfClassTraceTime::CLASS_LOAD);
+    ClassPathEntry* e = _first_entry; 
     while (e != NULL) {
       stream = e->open_stream(name);
       if (stream != NULL) {
--- a/src/share/vm/classfile/classLoader.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/classfile/classLoader.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -206,6 +206,7 @@
   // Initialization
   static void setup_meta_index();
   static void setup_bootstrap_search_path();
+  static void setup_bootstrap_search_path(char* sys_class_path);
   static void load_zip_library();
   static void create_class_path_entry(char *path, struct stat st, ClassPathEntry **new_entry, bool lazy);
 
--- a/src/share/vm/classfile/systemDictionary.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/classfile/systemDictionary.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -193,7 +193,8 @@
 // Forwards to resolve_instance_class_or_null
 
 klassOop SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) {
-  assert(!THREAD->is_Compiler_thread(), "Can not load classes with the Compiler thread");
+  // (tw) May we do this?
+  //assert(!THREAD->is_Compiler_thread(), "Can not load classes with the Compiler thread");
   if (FieldType::is_array(class_name)) {
     return resolve_array_class_or_null(class_name, class_loader, protection_domain, CHECK_NULL);
   } else if (FieldType::is_obj(class_name)) {
@@ -2369,8 +2370,9 @@
   if (spe == NULL || spe->property_oop() == NULL) {
     spe = NULL;
     // Must create lots of stuff here, but outside of the SystemDictionary lock.
-    if (THREAD->is_Compiler_thread())
-      return NULL;              // do not attempt from within compiler
+    // (tw) May we do this?
+	//if (THREAD->is_Compiler_thread())
+    //  return NULL;              // do not attempt from within compiler
     bool for_invokeGeneric = (name_id != vmSymbols::VM_SYMBOL_ENUM_NAME(invokeExact_name));
     bool found_on_bcp = false;
     Handle mt = find_method_handle_type(signature, accessing_klass,
--- a/src/share/vm/classfile/systemDictionary.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/classfile/systemDictionary.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -186,6 +186,46 @@
   template(Short_klass,                  java_lang_Short,                Pre) \
   template(Integer_klass,                java_lang_Integer,              Pre) \
   template(Long_klass,                   java_lang_Long,                 Pre) \
+                                                                                                                         \
+  /* Support for Graal */                                                                                                \
+  template(HotSpotTypeResolved_klass,             com_oracle_max_graal_hotspot_HotSpotTypeResolved,                 Opt) \
+  template(HotSpotType_klass,                     com_oracle_max_graal_hotspot_HotSpotType,                         Opt) \
+  template(HotSpotField_klass,                    com_oracle_max_graal_hotspot_HotSpotField,                        Opt) \
+  template(HotSpotCompiledMethod_klass,           com_oracle_max_graal_hotspot_HotSpotCompiledMethod,               Opt) \
+  template(HotSpotMethodResolved_klass,           com_oracle_max_graal_hotspot_ri_HotSpotMethodResolved,            Opt) \
+  template(HotSpotMethodData_klass,               com_oracle_max_graal_hotspot_ri_HotSpotMethodData,                Opt) \
+  template(HotSpotTargetMethod_klass,             com_oracle_max_graal_hotspot_HotSpotTargetMethod,                 Opt) \
+  template(HotSpotExceptionHandler_klass,         com_oracle_max_graal_hotspot_HotSpotExceptionHandler,             Opt) \
+  template(HotSpotProxy_klass,                    com_oracle_max_graal_hotspot_HotSpotProxy,                        Opt) \
+  template(CiAssumptions_klass,                   com_oracle_max_cri_ci_CiAssumptions,                              Opt) \
+  template(CiAssumptions_MethodContents_klass,    com_oracle_max_cri_ci_CiAssumptions_MethodContents,               Opt) \
+  template(CiAssumptions_ConcreteSubtype_klass,   com_oracle_max_cri_ci_CiAssumptions_ConcreteSubtype,              Opt) \
+  template(CiAssumptions_ConcreteMethod_klass,    com_oracle_max_cri_ci_CiAssumptions_ConcreteMethod,               Opt) \
+  template(CiTargetMethod_klass,                  com_oracle_max_cri_ci_CiTargetMethod,                             Opt) \
+  template(CiTargetMethod_Site_klass,             com_oracle_max_cri_ci_CiTargetMethod_Site,                        Opt) \
+  template(CiTargetMethod_Call_klass,             com_oracle_max_cri_ci_CiTargetMethod_Call,                        Opt) \
+  template(CiTargetMethod_DataPatch_klass,        com_oracle_max_cri_ci_CiTargetMethod_DataPatch,                   Opt) \
+  template(CiTargetMethod_Safepoint_klass,        com_oracle_max_cri_ci_CiTargetMethod_Safepoint,                   Opt) \
+  template(CiTargetMethod_ExceptionHandler_klass, com_oracle_max_cri_ci_CiTargetMethod_ExceptionHandler,            Opt) \
+  template(CiTargetMethod_Mark_klass,             com_oracle_max_cri_ci_CiTargetMethod_Mark,                        Opt) \
+  template(GraalBitMap_klass,                     com_oracle_max_cri_ci_CiBitMap,                                   Opt) \
+  template(CiDebugInfo_klass,                     com_oracle_max_cri_ci_CiDebugInfo,                                Opt) \
+  template(CiFrame_klass,                         com_oracle_max_cri_ci_CiFrame,                                    Opt) \
+  template(CiValue_klass,                         com_oracle_max_cri_ci_CiValue,                                    Opt) \
+  template(CiStackSlot_klass,                     com_oracle_max_cri_ci_CiStackSlot,                                Opt) \
+  template(CiRegisterValue_klass,                 com_oracle_max_cri_ci_CiRegisterValue,                            Opt) \
+  template(CiRegister_klass,                      com_oracle_max_cri_ci_CiRegister,                                 Opt) \
+  template(CiCodePos_klass,                       com_oracle_max_cri_ci_CiCodePos,                                  Opt) \
+  template(CiConstant_klass,                      com_oracle_max_cri_ci_CiConstant,                                 Opt) \
+  template(CiVirtualObject_klass,                 com_oracle_max_cri_ci_CiVirtualObject,                            Opt) \
+  template(CiMonitorValue_klass,                  com_oracle_max_cri_ci_CiMonitorValue,                             Opt) \
+  template(CiKind_klass,                          com_oracle_max_cri_ci_CiKind,                                     Opt) \
+  template(CiRuntimeCall_klass,                   com_oracle_max_cri_ci_CiRuntimeCall,                              Opt) \
+  template(RiMethod_klass,                        com_oracle_max_cri_ri_RiMethod,                                   Opt) \
+  template(RiType_klass,                          com_oracle_max_cri_ri_RiType,                                     Opt) \
+  template(RiResolvedField_klass,                 com_oracle_max_cri_ri_RiResolvedField,                            Opt) \
+  template(RiExceptionHandler_klass,              com_oracle_max_cri_ri_RiExceptionHandler,                         Opt) \
+
   /*end*/
 
 
--- a/src/share/vm/classfile/vmSymbols.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/classfile/vmSymbols.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -267,6 +267,91 @@
   NOT_LP64(  do_alias(intptr_signature,               int_signature)  )                           \
   LP64_ONLY( do_alias(intptr_signature,               long_signature) )                           \
   template(selectAlternative_signature, "(ZLjava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;") \
+                                                                                                                                          \
+  /* Support for Graal */                                                                                                                 \
+  template(com_oracle_max_graal_hotspot_bridge_VMToCompiler,          "com/oracle/max/graal/hotspot/bridge/VMToCompiler")                 \
+  template(com_oracle_max_graal_hotspot_ri_HotSpotMethodResolved,     "com/oracle/max/graal/hotspot/ri/HotSpotMethodResolvedImpl")        \
+  template(com_oracle_max_graal_hotspot_HotSpotTargetMethod,          "com/oracle/max/graal/hotspot/HotSpotTargetMethod")                 \
+  template(com_oracle_max_graal_hotspot_ri_HotSpotMethodData,         "com/oracle/max/graal/hotspot/ri/HotSpotMethodData")                \
+  template(com_oracle_max_graal_hotspot_HotSpotField,                 "com/oracle/max/graal/hotspot/ri/HotSpotField")                     \
+  template(com_oracle_max_graal_hotspot_HotSpotCompiledMethod,        "com/oracle/max/graal/hotspot/ri/HotSpotCompiledMethod")            \
+  template(com_oracle_max_graal_hotspot_HotSpotOptions,               "com/oracle/max/graal/hotspot/HotSpotOptions")                      \
+  template(com_oracle_max_graal_hotspot_HotSpotTypeResolved,          "com/oracle/max/graal/hotspot/ri/HotSpotTypeResolvedImpl")          \
+  template(com_oracle_max_graal_hotspot_HotSpotType,                  "com/oracle/max/graal/hotspot/ri/HotSpotType")                      \
+  template(com_oracle_max_graal_hotspot_HotSpotExceptionHandler,      "com/oracle/max/graal/hotspot/ri/HotSpotExceptionHandler")          \
+  template(com_oracle_max_graal_hotspot_HotSpotProxy,                 "com/oracle/max/graal/hotspot/HotSpotProxy")                        \
+  template(com_oracle_max_graal_hotspot_Compiler,                     "com/oracle/max/graal/hotspot/Compiler")                            \
+  template(com_oracle_max_graal_hotspot_CompilerImpl,                 "com/oracle/max/graal/hotspot/CompilerImpl")                        \
+  template(com_oracle_max_cri_ri_RiMethod,                            "com/oracle/max/cri/ri/RiMethod")                                   \
+  template(com_oracle_max_cri_ri_RiResolvedField,                     "com/oracle/max/cri/ri/RiResolvedField")                            \
+  template(com_oracle_max_cri_ri_RiType,                              "com/oracle/max/cri/ri/RiType")                                     \
+  template(com_oracle_max_cri_ri_RiConstantPool,                      "com/oracle/max/cri/ri/RiConstantPool")                             \
+  template(com_oracle_max_cri_ri_RiExceptionHandler,                  "com/oracle/max/cri/ri/RiExceptionHandler")                         \
+  template(com_oracle_max_cri_ci_CiAssumptions,                       "com/oracle/max/cri/ci/CiAssumptions")                              \
+  template(com_oracle_max_cri_ci_CiAssumptions_MethodContents,        "com/oracle/max/cri/ci/CiAssumptions$MethodContents")               \
+  template(com_oracle_max_cri_ci_CiAssumptions_ConcreteSubtype,       "com/oracle/max/cri/ci/CiAssumptions$ConcreteSubtype")              \
+  template(com_oracle_max_cri_ci_CiAssumptions_ConcreteMethod,        "com/oracle/max/cri/ci/CiAssumptions$ConcreteMethod")               \
+  template(com_oracle_max_cri_ci_CiGenericCallback,                   "com/oracle/max/cri/ci/CiGenericCallback")                          \
+  template(com_oracle_max_cri_ci_CiTargetMethod,                      "com/oracle/max/cri/ci/CiTargetMethod")                             \
+  template(com_oracle_max_cri_ci_CiTargetMethod_Site,                 "com/oracle/max/cri/ci/CiTargetMethod$Site")                        \
+  template(com_oracle_max_cri_ci_CiTargetMethod_Call,                 "com/oracle/max/cri/ci/CiTargetMethod$Call")                        \
+  template(com_oracle_max_cri_ci_CiTargetMethod_DataPatch,            "com/oracle/max/cri/ci/CiTargetMethod$DataPatch")                   \
+  template(com_oracle_max_cri_ci_CiTargetMethod_Safepoint,            "com/oracle/max/cri/ci/CiTargetMethod$Safepoint")                   \
+  template(com_oracle_max_cri_ci_CiTargetMethod_ExceptionHandler,     "com/oracle/max/cri/ci/CiTargetMethod$ExceptionHandler")            \
+  template(com_oracle_max_cri_ci_CiTargetMethod_Mark,                 "com/oracle/max/cri/ci/CiTargetMethod$Mark")                        \
+  template(com_oracle_max_graal_graph_BitMap,                         "com/oracle/max/graal/graph/BitMap")                                \
+  template(com_oracle_max_cri_ci_CiBitMap,	                          "com/oracle/max/cri/ci/CiBitMap")                                   \
+  template(com_oracle_max_cri_ci_CiDebugInfo,                         "com/oracle/max/cri/ci/CiDebugInfo")                                \
+  template(com_oracle_max_cri_ci_CiFrame,                             "com/oracle/max/cri/ci/CiFrame")                                    \
+  template(com_oracle_max_cri_ci_CiValue,                             "com/oracle/max/cri/ci/CiValue")                                    \
+  template(com_oracle_max_cri_ci_CiStackSlot,                         "com/oracle/max/cri/ci/CiStackSlot")                                \
+  template(com_oracle_max_cri_ci_CiRegisterValue,                     "com/oracle/max/cri/ci/CiRegisterValue")                            \
+  template(com_oracle_max_cri_ci_CiRegister,                          "com/oracle/max/cri/ci/CiRegister")                                 \
+  template(com_oracle_max_cri_ci_CiCodePos,                           "com/oracle/max/cri/ci/CiCodePos")                                  \
+  template(com_oracle_max_cri_ci_CiConstant,                          "com/oracle/max/cri/ci/CiConstant")                                 \
+  template(com_oracle_max_cri_ci_CiVirtualObject,                     "com/oracle/max/cri/ci/CiVirtualObject")                            \
+  template(com_oracle_max_cri_ci_CiMonitorValue,                      "com/oracle/max/cri/ci/CiMonitorValue")                             \
+  template(com_oracle_max_cri_ci_CiKind,                              "com/oracle/max/cri/ci/CiKind")                                     \
+  template(com_oracle_max_cri_ci_CiRuntimeCall,                       "com/oracle/max/cri/ci/CiRuntimeCall")                              \
+  template(startCompiler_name,                        "startCompiler")                                                  \
+  template(bootstrap_name,                            "bootstrap")                                                      \
+  template(shutdownCompiler_name,                     "shutdownCompiler")                                               \
+  template(compileMethod_name,                        "compileMethod")                                                  \
+  template(compileMethod_signature,                   "(Lcom/oracle/max/graal/hotspot/ri/HotSpotMethodResolved;IZ)V")   \
+  template(setOption_name,                            "setOption")                                                      \
+  template(setDefaultOptions_name,                    "setDefaultOptions")                                              \
+  template(setOption_signature,                       "(Ljava/lang/String;)Z")                                          \
+  template(createRiMethodResolved_name,               "createRiMethodResolved")                                         \
+  template(createRiMethodResolved_signature,          "(JLjava/lang/String;)Lcom/oracle/max/cri/ri/RiMethod;")          \
+  template(createRiMethodUnresolved_name,             "createRiMethodUnresolved")                                       \
+  template(createRiMethodUnresolved_signature,        "(Ljava/lang/String;Ljava/lang/String;Lcom/oracle/max/cri/ri/RiType;)Lcom/oracle/max/cri/ri/RiMethod;") \
+  template(createRiSignature_name,                    "createRiSignature")                                              \
+  template(createRiSignature_signature,               "(Ljava/lang/String;)Lcom/oracle/max/cri/ri/RiSignature;")        \
+  template(createRiField_name,                        "createRiField")                                                  \
+  template(createRiField_signature,                   "(Lcom/oracle/max/cri/ri/RiType;Ljava/lang/String;Lcom/oracle/max/cri/ri/RiType;II)Lcom/oracle/max/cri/ri/RiField;") \
+  template(createRiType_name,                         "createRiType")                                                   \
+  template(createRiType_signature,                    "(JLjava/lang/String;)Lcom/oracle/max/cri/ri/RiType;")            \
+  template(createRiTypePrimitive_name,                "createRiTypePrimitive")                                          \
+  template(createRiTypePrimitive_signature,           "(I)Lcom/oracle/max/cri/ri/RiType;")                              \
+  template(createRiTypeUnresolved_name,               "createRiTypeUnresolved")                                         \
+  template(createRiTypeUnresolved_signature,          "(Ljava/lang/String;)Lcom/oracle/max/cri/ri/RiType;")             \
+  template(createCiConstant_name,                     "createCiConstant")                                               \
+  template(createCiConstant_signature,                "(Lcom/oracle/max/cri/ci/CiKind;J)Lcom/oracle/max/cri/ci/CiConstant;") \
+  template(createCiConstantFloat_name,                "createCiConstantFloat")                                          \
+  template(createCiConstantFloat_signature,           "(F)Lcom/oracle/max/cri/ci/CiConstant;")                          \
+  template(createCiConstantDouble_name,               "createCiConstantDouble")                                         \
+  template(createCiConstantDouble_signature,          "(D)Lcom/oracle/max/cri/ci/CiConstant;")                          \
+  template(createCiConstantObject_name,               "createCiConstantObject")                                         \
+  template(createCiConstantObject_signature,          "(Ljava/lang/Object;)Lcom/oracle/max/cri/ci/CiConstant;")         \
+  template(getVMExits_name,                           "getVMExits")                                                     \
+  template(getVMExits_signature,                      "()Lcom/oracle/max/graal/hotspot/bridge/VMToCompiler;")           \
+  template(getInstance_name,                          "getInstance")                                                    \
+  template(initialize_name,                           "initialize")                                                     \
+  template(getInstance_signature,                     "()Lcom/oracle/max/graal/hotspot/Compiler;")                      \
+  template(forObject_name,                            "forObject")                                                      \
+  template(callbackInternal_name,                     "callbackInternal")                                               \
+  template(callback_signature,                        "(Ljava/lang/Object;)Ljava/lang/Object;")                         \
+                                                                                                                        \
                                                                                                   \
   /* common method and field names */                                                             \
   template(object_initializer_name,                   "<init>")                                   \
@@ -346,6 +431,7 @@
   template(bitCount_name,                             "bitCount")                                 \
   template(profile_name,                              "profile")                                  \
   template(equals_name,                               "equals")                                   \
+  template(length_name,                               "length")                                   \
   template(target_name,                               "target")                                   \
   template(toString_name,                             "toString")                                 \
   template(values_name,                               "values")                                   \
@@ -390,6 +476,7 @@
   template(void_long_signature,                       "()J")                                      \
   template(void_float_signature,                      "()F")                                      \
   template(void_double_signature,                     "()D")                                      \
+  template(bool_void_signature,                       "(Z)V")                                     \
   template(int_void_signature,                        "(I)V")                                     \
   template(int_int_signature,                         "(I)I")                                     \
   template(char_char_signature,                       "(C)C")                                     \
--- a/src/share/vm/code/codeBlob.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/code/codeBlob.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -405,6 +405,11 @@
 
   int _unpack_with_exception_in_tls;
 
+  // (tw) Offset when graal calls uncommon_trap.
+  int _uncommon_trap_offset;
+  int _jmp_uncommon_trap_offset;
+
+
   // Creation support
   DeoptimizationBlob(
     CodeBuffer* cb,
@@ -457,6 +462,19 @@
     assert(code_contains(code_begin() + _unpack_with_exception_in_tls), "must be PC inside codeblob");
   }
   address unpack_with_exception_in_tls() const   { return code_begin() + _unpack_with_exception_in_tls; }
+
+  // (tw) Offset when graal calls uncommon_trap.
+  void set_uncommon_trap_offset(int offset) {
+    _uncommon_trap_offset = offset;
+    assert(contains(code_begin() + _uncommon_trap_offset), "must be PC inside codeblob");
+  }
+  address uncommon_trap() const                  { return code_begin() + _uncommon_trap_offset;     }
+  void set_jmp_uncommon_trap_offset(int offset) {
+    _jmp_uncommon_trap_offset = offset;
+    assert(contains(code_begin() + _jmp_uncommon_trap_offset), "must be PC inside codeblob");
+  }
+  address jmp_uncommon_trap() const                  { return code_begin() + _jmp_uncommon_trap_offset;     }
+
 };
 
 
--- a/src/share/vm/code/compiledIC.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/code/compiledIC.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -528,7 +528,10 @@
   NativeJump*        jump          = nativeJump_at(method_holder->next_instruction_address());
 
   assert(method_holder->data()    == 0           || method_holder->data()    == (intptr_t)callee(), "a) MT-unsafe modification of inline cache");
+// XXX GRAAL : ??
+#ifndef GRAAL
   assert(jump->jump_destination() == (address)-1 || jump->jump_destination() == entry, "b) MT-unsafe modification of inline cache");
+#endif
 
   // Update stub
   method_holder->set_data((intptr_t)callee());
--- a/src/share/vm/code/debugInfoRec.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/code/debugInfoRec.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -280,9 +280,11 @@
 // must call add_safepoint before: it sets PcDesc and this routine uses
 // the last PcDesc set
 void DebugInformationRecorder::describe_scope(int         pc_offset,
+                                              methodHandle methodH,
                                               ciMethod*   method,
                                               int         bci,
                                               bool        reexecute,
+                                              bool        rethrow_exception,
                                               bool        is_method_handle_invoke,
                                               bool        return_oop,
                                               DebugToken* locals,
@@ -298,6 +300,7 @@
 
   // Record flags into pcDesc.
   last_pd->set_should_reexecute(reexecute);
+  last_pd->set_rethrow_exception(rethrow_exception);
   last_pd->set_is_method_handle_invoke(is_method_handle_invoke);
   last_pd->set_return_oop(return_oop);
 
@@ -305,13 +308,24 @@
   stream()->write_int(sender_stream_offset);
 
   // serialize scope
-  jobject method_enc = (method == NULL)? NULL: method->constant_encoding();
+  jobject method_enc;
+  if (method != NULL) {
+    method_enc = method->constant_encoding();
+  } else if (methodH.not_null()) {
+    method_enc = JNIHandles::make_local(Thread::current(), methodH());
+  } else {
+    method_enc = NULL;
+  }
   stream()->write_int(oop_recorder()->find_index(method_enc));
   stream()->write_bci(bci);
   assert(method == NULL ||
          (method->is_native() && bci == 0) ||
          (!method->is_native() && 0 <= bci && bci < method->code_size()) ||
          bci == -1, "illegal bci");
+  assert(methodH.is_null() ||
+         (methodH->is_native() && bci == 0) ||
+         (!methodH->is_native() && 0 <= bci && bci < methodH->code_size()) ||
+         bci == -1, "illegal bci");
 
   // serialize the locals/expressions/monitors
   stream()->write_int((intptr_t) locals);
--- a/src/share/vm/code/debugInfoRec.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/code/debugInfoRec.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -98,9 +98,11 @@
   // by add_non_safepoint, and the locals, expressions, and monitors
   // must all be null.
   void describe_scope(int         pc_offset,
+                      methodHandle methodH,
                       ciMethod*   method,
                       int         bci,
                       bool        reexecute,
+                      bool        rethrow_exception = false,
                       bool        is_method_handle_invoke = false,
                       bool        return_oop = false,
                       DebugToken* locals      = NULL,
--- a/src/share/vm/code/exceptionHandlerTable.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/code/exceptionHandlerTable.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -88,12 +88,12 @@
   int                _length;   // the current length of the table
   int                _size;     // the number of allocated entries
   ReallocMark        _nesting;  // assertion check for reallocations
-
+  
+ public:
   // add the entry & grow the table if needed
   void add_entry(HandlerTableEntry entry);
   HandlerTableEntry* subtable_for(int catch_pco) const;
 
- public:
   // (compile-time) construction within compiler
   ExceptionHandlerTable(int initial_size = 8);
 
--- a/src/share/vm/code/nmethod.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/code/nmethod.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -45,6 +45,9 @@
 #ifdef SHARK
 #include "shark/sharkCompiler.hpp"
 #endif
+#ifdef GRAAL
+#include "graal/graalJavaAccess.hpp"
+#endif
 
 #ifdef DTRACE_ENABLED
 
@@ -116,7 +119,6 @@
 //   PrintC1Statistics, PrintOptoStatistics, LogVMOutput, and LogCompilation.
 // (In the latter two cases, they like other stats are printed to the log only.)
 
-#ifndef PRODUCT
 // These variables are put into one block to reduce relocations
 // and make it simpler to print from the debugger.
 static
@@ -206,7 +208,6 @@
                   pc_desc_tests, pc_desc_searches, pc_desc_adds);
   }
 } nmethod_stats;
-#endif //PRODUCT
 
 
 //---------------------------------------------------------------------------------
@@ -480,6 +481,8 @@
   _saved_nmethod_link      = NULL;
   _compiler                = NULL;
 
+  _graal_compiled_method   = NULL;
+
 #ifdef HAVE_DTRACE_H
   _trap_offset             = 0;
 #endif // def HAVE_DTRACE_H
@@ -508,7 +511,7 @@
               code_buffer, frame_size,
               basic_lock_owner_sp_offset, basic_lock_sp_offset,
               oop_maps);
-    NOT_PRODUCT(if (nm != NULL)  nmethod_stats.note_native_nmethod(nm));
+    if (nm != NULL)  nmethod_stats.note_native_nmethod(nm);
     if (PrintAssembly && nm != NULL)
       Disassembler::decode(nm);
   }
@@ -541,7 +544,7 @@
 
     nm = new (nmethod_size) nmethod(method(), nmethod_size, &offsets, code_buffer, frame_size);
 
-    NOT_PRODUCT(if (nm != NULL)  nmethod_stats.note_nmethod(nm));
+    if (nm != NULL)  nmethod_stats.note_nmethod(nm);
     if (PrintAssembly && nm != NULL)
       Disassembler::decode(nm);
   }
@@ -608,7 +611,7 @@
         instanceKlass::cast(klass)->add_dependent_nmethod(nm);
       }
     }
-    NOT_PRODUCT(if (nm != NULL)  nmethod_stats.note_nmethod(nm));
+    if (nm != NULL)  nmethod_stats.note_nmethod(nm);
     if (PrintAssembly && nm != NULL)
       Disassembler::decode(nm);
   }
@@ -833,13 +836,24 @@
     // Exception handler and deopt handler are in the stub section
     assert(offsets->value(CodeOffsets::Exceptions) != -1, "must be set");
     assert(offsets->value(CodeOffsets::Deopt     ) != -1, "must be set");
-    _exception_offset        = _stub_offset          + offsets->value(CodeOffsets::Exceptions);
-    _deoptimize_offset       = _stub_offset          + offsets->value(CodeOffsets::Deopt);
-    if (offsets->value(CodeOffsets::DeoptMH) != -1) {
-      _deoptimize_mh_offset  = _stub_offset          + offsets->value(CodeOffsets::DeoptMH);
-    } else {
-      _deoptimize_mh_offset  = -1;
-    }
+#ifdef GRAAL
+      // graal produces no (!) stub section
+      _exception_offset        = code_offset()          + offsets->value(CodeOffsets::Exceptions);
+      _deoptimize_offset       = code_offset()          + offsets->value(CodeOffsets::Deopt);
+      if (offsets->value(CodeOffsets::DeoptMH) != -1) {
+        _deoptimize_mh_offset  = code_offset()          + offsets->value(CodeOffsets::DeoptMH);
+      } else {
+        _deoptimize_mh_offset  = -1;
+      }
+#else
+      _exception_offset        = _stub_offset          + offsets->value(CodeOffsets::Exceptions);
+      _deoptimize_offset       = _stub_offset          + offsets->value(CodeOffsets::Deopt);
+      if (offsets->value(CodeOffsets::DeoptMH) != -1) {
+        _deoptimize_mh_offset  = _stub_offset          + offsets->value(CodeOffsets::DeoptMH);
+      } else {
+        _deoptimize_mh_offset  = -1;
+      }
+#endif
     if (offsets->value(CodeOffsets::UnwindHandler) != -1) {
       _unwind_handler_offset = code_offset()         + offsets->value(CodeOffsets::UnwindHandler);
     } else {
@@ -1076,7 +1090,7 @@
   PcDesc* pd = pc_desc_at(pc);
   guarantee(pd != NULL, "scope must be present");
   return new ScopeDesc(this, pd->scope_decode_offset(),
-                       pd->obj_decode_offset(), pd->should_reexecute(),
+                       pd->obj_decode_offset(), pd->should_reexecute(), pd->rethrow_exception(),
                        pd->return_oop());
 }
 
@@ -1211,6 +1225,14 @@
     }
     _method = NULL;            // Clear the method of this dead nmethod
   }
+
+#ifdef GRAAL
+    if (_graal_compiled_method != NULL) {
+      HotSpotCompiledMethod::set_nmethod(_graal_compiled_method, 0);
+      _graal_compiled_method = NULL;
+    }
+#endif
+
   // Make the class unloaded - i.e., change state and notify sweeper
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   if (is_in_use()) {
@@ -1292,6 +1314,13 @@
       return false;
     }
 
+#ifdef GRAAL
+    if (_graal_compiled_method != NULL) {
+      HotSpotCompiledMethod::set_nmethod(_graal_compiled_method, 0);
+      _graal_compiled_method = NULL;
+    }
+#endif
+
     // The caller can be calling the method statically or through an inline
     // cache call.
     if (!is_osr_method() && !is_not_entrant()) {
@@ -1601,6 +1630,10 @@
     return;
   }
 
+  if (_graal_compiled_method != NULL && can_unload(is_alive, keep_alive, (oop*)&_graal_compiled_method, unloading_occurred)) {
+    return;
+  }
+
   // Exception cache
   ExceptionCache* ec = exception_cache();
   while (ec != NULL) {
@@ -1715,6 +1748,7 @@
 
   // Compiled code
   f->do_oop((oop*) &_method);
+  f->do_oop((oop*) &_graal_compiled_method);
   if (!do_strong_roots_only) {
     // weak roots processing phase -- update ExceptionCache oops
     ExceptionCache* ec = exception_cache();
@@ -2277,7 +2311,7 @@
   PcDesc* pd = pc_desc_at(ic->end_of_call());
   assert(pd != NULL, "PcDesc must exist");
   for (ScopeDesc* sd = new ScopeDesc(this, pd->scope_decode_offset(),
-                                     pd->obj_decode_offset(), pd->should_reexecute(),
+                                     pd->obj_decode_offset(), pd->should_reexecute(), pd->rethrow_exception(),
                                      pd->return_oop());
        !sd->is_top(); sd = sd->sender()) {
     sd->verify();
@@ -2311,7 +2345,9 @@
         // information in a table.
         break;
     }
+#ifndef GRAAL
     assert(stub == NULL || stub_contains(stub), "static call stub outside stub section");
+#endif
   }
 }
 
@@ -2543,7 +2579,7 @@
   PcDesc* p = pc_desc_near(begin+1);
   if (p != NULL && p->real_pc(this) <= end) {
     return new ScopeDesc(this, p->scope_decode_offset(),
-                         p->obj_decode_offset(), p->should_reexecute(),
+                         p->obj_decode_offset(), p->should_reexecute(), p->rethrow_exception(),
                          p->return_oop());
   }
   return NULL;
@@ -2788,6 +2824,8 @@
   ImplicitExceptionTable(this).print(code_begin());
 }
 
+#endif // PRODUCT
+
 void nmethod::print_statistics() {
   ttyLocker ttyl;
   if (xtty != NULL)  xtty->head("statistics type='nmethod'");
@@ -2798,5 +2836,3 @@
   Dependencies::print_statistics();
   if (xtty != NULL)  xtty->tail("statistics");
 }
-
-#endif // PRODUCT
--- a/src/share/vm/code/nmethod.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/code/nmethod.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -116,6 +116,8 @@
   int       _entry_bci;        // != InvocationEntryBci if this nmethod is an on-stack replacement method
   jmethodID _jmethod_id;       // Cache of method()->jmethod_id()
 
+  oop       _graal_compiled_method;
+
   // To support simple linked-list chaining of nmethods:
   nmethod*  _osr_link;         // from instanceKlass::osr_nmethods_head
   nmethod*  _scavenge_root_link; // from CodeCache::scavenge_root_nmethods
@@ -536,6 +538,10 @@
   // Evolution support. We make old (discarded) compiled methods point to new methodOops.
   void set_method(methodOop method) { _method = method; }
 
+
+  oop graal_compiled_method() { return _graal_compiled_method; }
+  void set_graal_compiled_method(oop compiled_method) { _graal_compiled_method = compiled_method; }
+
   // GC support
   void do_unloading(BoolObjectClosure* is_alive, OopClosure* keep_alive,
                     bool unloading_occurred);
@@ -587,7 +593,10 @@
   // Deopt
   // Return true is the PC is one would expect if the frame is being deopted.
   bool is_deopt_pc      (address pc) { return is_deopt_entry(pc) || is_deopt_mh_entry(pc); }
-  bool is_deopt_entry   (address pc) { return pc == deopt_handler_begin(); }
+
+  // (tw) When using graal, the address might be off by 5 (because this is the size of the call instruction.
+  // (tw) TODO: Replace this by a more general mechanism.
+  bool is_deopt_entry   (address pc) { return pc == deopt_handler_begin() IS_GRAAL( || pc == deopt_handler_begin() + 5); }
   bool is_deopt_mh_entry(address pc) { return pc == deopt_mh_handler_begin(); }
   // Accessor/mutator for the original pc of a frame before a frame was deopted.
   address get_original_pc(const frame* fr) { return *orig_pc_addr(fr); }
@@ -638,7 +647,7 @@
 
   // Prints a comment for one native instruction (reloc info, pc desc)
   void print_code_comment_on(outputStream* st, int column, address begin, address end);
-  static void print_statistics()                  PRODUCT_RETURN;
+  static void print_statistics();
 
   // Compiler task identification.  Note that all OSR methods
   // are numbered in an independent sequence if CICountOSR is true,
--- a/src/share/vm/code/pcDesc.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/code/pcDesc.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -42,7 +42,8 @@
   enum {
     PCDESC_reexecute               = 1 << 0,
     PCDESC_is_method_handle_invoke = 1 << 1,
-    PCDESC_return_oop              = 1 << 2
+    PCDESC_return_oop              = 1 << 2,
+    PCDESC_rethrow_exception       = 1 << 3
   };
 
   int _flags;
@@ -71,6 +72,8 @@
   };
 
   // Flags
+  bool     rethrow_exception()              const { return (_flags & PCDESC_rethrow_exception) != 0; }
+  void set_rethrow_exception(bool z)              { set_flag(PCDESC_rethrow_exception, z);    }
   bool     should_reexecute()              const { return (_flags & PCDESC_reexecute) != 0; }
   void set_should_reexecute(bool z)              { set_flag(PCDESC_reexecute, z); }
 
--- a/src/share/vm/code/scopeDesc.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/code/scopeDesc.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -31,21 +31,23 @@
 #include "runtime/handles.inline.hpp"
 
 
-ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop) {
+ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool rethrow_exception, bool return_oop) {
   _code          = code;
   _decode_offset = decode_offset;
   _objects       = decode_object_values(obj_decode_offset);
   _reexecute     = reexecute;
   _return_oop    = return_oop;
+  _rethrow_exception = rethrow_exception;
   decode_body();
 }
 
-ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool return_oop) {
+ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool rethrow_exception, bool return_oop) {
   _code          = code;
   _decode_offset = decode_offset;
   _objects       = decode_object_values(DebugInformationRecorder::serialized_null);
   _reexecute     = reexecute;
   _return_oop    = return_oop;
+  _rethrow_exception = rethrow_exception;
   decode_body();
 }
 
@@ -55,6 +57,7 @@
   _decode_offset = parent->_sender_decode_offset;
   _objects       = parent->_objects;
   _reexecute     = false; //reexecute only applies to the first scope
+  _rethrow_exception = false;
   _return_oop    = false;
   decode_body();
 }
--- a/src/share/vm/code/scopeDesc.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/code/scopeDesc.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -60,17 +60,18 @@
 class ScopeDesc : public ResourceObj {
  public:
   // Constructor
-  ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop);
+  ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool rethrow_exception, bool return_oop);
 
   // Calls above, giving default value of "serialized_null" to the
   // "obj_decode_offset" argument.  (We don't use a default argument to
   // avoid a .hpp-.hpp dependency.)
-  ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool return_oop);
+  ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool rethrow_exception, bool return_oop);
 
   // JVM state
   methodHandle method()   const { return _method; }
   int          bci()      const { return _bci;    }
   bool should_reexecute() const { return _reexecute; }
+  bool rethrow_exception() const { return _rethrow_exception; }
   bool return_oop()       const { return _return_oop; }
 
   GrowableArray<ScopeValue*>*   locals();
@@ -97,6 +98,7 @@
   methodHandle  _method;
   int           _bci;
   bool          _reexecute;
+  bool          _rethrow_exception;
   bool          _return_oop;
 
   // Decoding offsets
--- a/src/share/vm/compiler/abstractCompiler.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/compiler/abstractCompiler.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -72,9 +72,6 @@
 #endif // SHARK
 #endif // TIERED
 
-  // Customization
-  virtual bool needs_stubs            ()         = 0;
-
   void mark_initialized()                        { _is_initialized = true; }
   bool is_initialized()                          { return _is_initialized; }
 
--- a/src/share/vm/compiler/compileBroker.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/compiler/compileBroker.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -44,6 +44,9 @@
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/sweeper.hpp"
 #include "utilities/dtrace.hpp"
+#ifdef GRAAL
+#include "graal/graalCompiler.hpp"
+#endif
 #include "utilities/events.hpp"
 #ifdef COMPILER1
 #include "c1/c1_Compiler.hpp"
@@ -724,11 +727,15 @@
   // Set the interface to the current compiler(s).
   int c1_count = CompilationPolicy::policy()->compiler_count(CompLevel_simple);
   int c2_count = CompilationPolicy::policy()->compiler_count(CompLevel_full_optimization);
+#ifdef GRAAL
+  _compilers[0] = new GraalCompiler();
+#else
 #ifdef COMPILER1
   if (c1_count > 0) {
     _compilers[0] = new Compiler();
   }
 #endif // COMPILER1
+#endif
 
 #ifdef COMPILER2
   if (c2_count > 0) {
@@ -979,6 +986,7 @@
 // ------------------------------------------------------------------
 // CompileBroker::is_idle
 bool CompileBroker::is_idle() {
+#ifndef GRAAL
   if (_c2_method_queue != NULL && !_c2_method_queue->is_empty()) {
     return false;
   } else if (_c1_method_queue != NULL && !_c1_method_queue->is_empty()) {
@@ -990,10 +998,10 @@
         return false;
       }
     }
-
-    // No pending or active compilations.
-    return true;
   }
+#endif
+  // No pending or active compilations.
+  return true;
 }
 
 
@@ -1085,6 +1093,14 @@
   {
     MutexLocker locker(queue->lock(), thread);
 
+    if (JavaThread::current()->is_compiling() && !BackgroundCompilation) {
+#ifdef GRAAL
+      TRACE_graal_1("Recursive compile %s!", method->name_and_sig_as_C_string());
+#endif
+      method->set_not_compilable();
+      return;
+    }
+
     // Make sure the method has not slipped into the queues since
     // last we checked; note that those checks were "fast bail-outs".
     // Here we need to be more careful, see 14012000 below.
@@ -1149,16 +1165,28 @@
     // and in that case it's best to protect both the testing (here) of
     // these bits, and their updating (here and elsewhere) under a
     // common lock.
+#ifndef GRAAL
     task = create_compile_task(queue,
                                compile_id, method,
                                osr_bci, comp_level,
                                hot_method, hot_count, comment,
                                blocking);
+#endif
   }
 
+#ifdef GRAAL
+  if (!JavaThread::current()->is_compiling()) {
+    method->set_queued_for_compilation();
+    GraalCompiler::instance()->compile_method(method, osr_bci, blocking);
+  } else {
+    // Recursive compile request => ignore.
+  }
+#endif
+#ifndef GRAAL
   if (blocking) {
     wait_for_completion(task);
   }
+#endif
 }
 
 
--- a/src/share/vm/compiler/oopMap.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/compiler/oopMap.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -255,7 +255,7 @@
   if(om_count() > 0) {
     OopMap* last = at(om_count()-1);
     if (last->offset() == map->offset() ) {
-      fatal("OopMap inserted twice");
+      fatal(err_msg("OopMap inserted twice (offset=%d)", last->offset()));
     }
     if(last->offset() > map->offset()) {
       tty->print_cr( "WARNING, maps not sorted: pc[%d]=%d, pc[%d]=%d",
--- a/src/share/vm/compiler/oopMap.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/compiler/oopMap.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -47,7 +47,7 @@
 class OopMapValue: public StackObj {
   friend class VMStructs;
 private:
-  short _value;
+  int _value;
   int value() const                                 { return _value; }
   void set_value(int value)                         { _value = value; }
   short _content_reg;
@@ -55,7 +55,7 @@
 public:
   // Constants
   enum { type_bits                = 5,
-         register_bits            = BitsPerShort - type_bits };
+         register_bits            = BitsPerJavaInteger - type_bits };
 
   enum { type_shift               = 0,
          register_shift           = type_bits };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,885 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "graal/graalCompiler.hpp"
+#include "graal/graalCodeInstaller.hpp"
+#include "graal/graalJavaAccess.hpp"
+#include "graal/graalCompilerToVM.hpp"
+#include "graal/graalVmIds.hpp"
+#include "graal/graalEnv.hpp"
+#include "c1/c1_Runtime1.hpp"
+#include "classfile/vmSymbols.hpp"
+#include "vmreg_x86.inline.hpp"
+
+
+// TODO this should be handled in a more robust way - not hard coded...
+Register CPU_REGS[] = { rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15 };
+bool OOP_ALLOWED[] = {true, true, true, true, false, false, true, true, true, true, false, true, true, true, true, true};
+const static int NUM_CPU_REGS = sizeof(CPU_REGS) / sizeof(Register);
+XMMRegister XMM_REGS[] = { xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 };
+const static int NUM_XMM_REGS = sizeof(XMM_REGS) / sizeof(XMMRegister);
+const static int NUM_REGS = NUM_CPU_REGS + NUM_XMM_REGS;
+const static jlong NO_REF_MAP = 0x8000000000000000L;
+
+// convert graal register indices (as used in oop maps) to hotspot registers
+VMReg get_hotspot_reg(jint graal_reg) {
+
+  assert(graal_reg >= 0 && graal_reg < NUM_REGS, "invalid register number");
+  if (graal_reg < NUM_CPU_REGS) {
+    return CPU_REGS[graal_reg]->as_VMReg();
+  } else {
+    return XMM_REGS[graal_reg - NUM_CPU_REGS]->as_VMReg();
+  }
+}
+
+static bool is_bit_set(oop bit_map, int i) {
+  const int MapWordBits = 64;
+  if (i < MapWordBits) {
+    jlong low = GraalBitMap::low(bit_map);
+    return (low & (1LL << i)) != 0;
+  } else {
+    jint extra_idx = (i - MapWordBits) / MapWordBits;
+    arrayOop extra = (arrayOop) GraalBitMap::extra(bit_map);
+    assert(extra_idx >= 0 && extra_idx < extra->length(), "unexpected index");
+    jlong word = ((jlong*) extra->base(T_LONG))[extra_idx];
+    return (word & (1LL << (i % MapWordBits))) != 0;
+  }
+}
+
+// creates a hotspot oop map out of the byte arrays provided by CiDebugInfo
+static OopMap* create_oop_map(jint total_frame_size, jint parameter_count, oop debug_info) {
+  OopMap* map = new OopMap(total_frame_size, parameter_count);
+  oop register_map = (oop) CiDebugInfo::registerRefMap(debug_info);
+  oop frame_map = (oop) CiDebugInfo::frameRefMap(debug_info);
+
+  if (register_map != NULL) {
+    assert(GraalBitMap::size(register_map) == (unsigned) NUM_CPU_REGS, "unexpected register_map length");
+    for (jint i = 0; i < NUM_CPU_REGS; i++) {
+      bool is_oop = is_bit_set(register_map, i);
+      VMReg reg = get_hotspot_reg(i);
+      if (is_oop) {
+        assert(OOP_ALLOWED[i], "this register may never be an oop, register map misaligned?");
+        map->set_oop(reg);
+      } else {
+        map->set_value(reg);
+      }
+    }
+  }
+
+  for (jint i = 0; i < GraalBitMap::size(frame_map); i++) {
+    bool is_oop = is_bit_set(frame_map, i);
+    // hotspot stack slots are 4 bytes
+    VMReg reg = VMRegImpl::stack2reg(i * 2);
+    if (is_oop) {
+      map->set_oop(reg);
+    } else {
+      map->set_value(reg);
+    }
+  }
+
+  return map;
+}
+
+// TODO: finish this - graal doesn't provide any scope values at the moment
+static ScopeValue* get_hotspot_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, ScopeValue* &second) {
+  second = NULL;
+  if (value == CiValue::IllegalValue()) {
+    return new LocationValue(Location::new_stk_loc(Location::invalid, 0));
+  }
+
+  BasicType type = GraalCompiler::kindToBasicType(CiKind::typeChar(CiValue::kind(value)));
+  Location::Type locationType = Location::normal;
+  if (type == T_OBJECT || type == T_ARRAY) locationType = Location::oop;
+
+  if (value->is_a(CiRegisterValue::klass())) {
+    jint number = CiRegister::number(CiRegisterValue::reg(value));
+    if (number < 16) {
+      if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BOOLEAN || type == T_BYTE || type == T_ADDRESS) {
+        locationType = Location::int_in_long;
+      } else if (type == T_LONG) {
+        locationType = Location::lng;
+      } else {
+        assert(type == T_OBJECT || type == T_ARRAY, "unexpected type in cpu register");
+      }
+      ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, as_Register(number)->as_VMReg()));
+      if (type == T_LONG) {
+        second = value;
+      }
+      return value;
+    } else {
+      assert(type == T_FLOAT || type == T_DOUBLE, "only float and double expected in xmm register");
+      if (type == T_FLOAT) {
+        // this seems weird, but the same value is used in c1_LinearScan
+        locationType = Location::normal;
+      } else {
+        locationType = Location::dbl;
+      }
+      ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, as_XMMRegister(number - 16)->as_VMReg()));
+      if (type == T_DOUBLE) {
+        second = value;
+      }
+      return value;
+    }
+  } else if (value->is_a(CiStackSlot::klass())) {
+    if (type == T_DOUBLE) {
+      locationType = Location::dbl;
+    } else if (type == T_LONG) {
+      locationType = Location::lng;
+    }
+    jint offset = CiStackSlot::offset(value);
+    if (CiStackSlot::addFrameSize(value)) {
+      offset += total_frame_size;
+    }
+    ScopeValue* value = new LocationValue(Location::new_stk_loc(locationType, offset));
+    if (type == T_DOUBLE || type == T_LONG) {
+      second = value;
+    }
+    return value;
+  } else if (value->is_a(CiConstant::klass())){
+    oop obj = CiConstant::object(value);
+    jlong prim = CiConstant::primitive(value);
+    if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BOOLEAN || type == T_BYTE) {
+      return new ConstantIntValue(*(jint*)&prim);
+    } else if (type == T_LONG || type == T_DOUBLE) {
+      second = new ConstantIntValue(0);
+      return new ConstantLongValue(prim);
+    } else if (type == T_OBJECT) {
+      oop obj = CiConstant::object(value);
+      if (obj == NULL) {
+        return new ConstantOopWriteValue(NULL);
+      } else {
+        return new ConstantOopWriteValue(JNIHandles::make_local(obj));
+      }
+    } else if (type == T_ADDRESS) {
+      return new ConstantLongValue(prim);
+    }
+    tty->print("%i", type);
+  } else if (value->is_a(CiVirtualObject::klass())) {
+    oop type = CiVirtualObject::type(value);
+    int id = CiVirtualObject::id(value);
+    klassOop klass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type));
+
+    for (jint i = 0; i < objects->length(); i++) {
+      ObjectValue* obj = (ObjectValue*) objects->at(i);
+      if (obj->id() == id) {
+        return obj;
+      }
+    }
+
+    ObjectValue* sv = new ObjectValue(id, new ConstantOopWriteValue(JNIHandles::make_local(Thread::current(), klass)));
+
+    arrayOop values = (arrayOop) CiVirtualObject::values(value);
+    for (jint i = 0; i < values->length(); i++) {
+      ((oop*) values->base(T_OBJECT))[i];
+    }
+
+    for (jint i = 0; i < values->length(); i++) {
+      ScopeValue* cur_second = NULL;
+      ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], total_frame_size, objects, cur_second);
+      
+      if (cur_second != NULL) {
+        sv->field_values()->append(cur_second);
+      }
+      sv->field_values()->append(value);
+    }
+    objects->append(sv);
+    return sv;
+  } else {
+    value->klass()->print();
+    value->print();
+  }
+  ShouldNotReachHere();
+  return NULL;
+}
+
+static MonitorValue* get_monitor_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects) {
+  guarantee(value->is_a(CiMonitorValue::klass()), "Monitors must be of type CiMonitorValue");
+
+  ScopeValue* second = NULL;
+  ScopeValue* owner_value = get_hotspot_value(CiMonitorValue::owner(value), total_frame_size, objects, second);
+  assert(second == NULL, "monitor cannot occupy two stack slots");
+
+  ScopeValue* lock_data_value = get_hotspot_value(CiMonitorValue::lockData(value), total_frame_size, objects, second);
+  assert(second == lock_data_value, "monitor is LONG value that occupies two stack slots");
+  assert(lock_data_value->is_location(), "invalid monitor location");
+  Location lock_data_loc = ((LocationValue*)lock_data_value)->location();
+
+  bool eliminated = false;
+  if (CiMonitorValue::eliminated(value)) {
+    eliminated = true;
+  }
+
+  return new MonitorValue(owner_value, lock_data_loc, eliminated);
+}
+
+void CodeInstaller::initialize_assumptions(oop target_method) {
+  _oop_recorder = new OopRecorder(_env->arena());
+  _env->set_oop_recorder(_oop_recorder);
+  _env->set_dependencies(_dependencies);
+  _dependencies = new Dependencies(_env);
+  Handle assumptions_handle = CiTargetMethod::assumptions(HotSpotTargetMethod::targetMethod(target_method));
+  if (!assumptions_handle.is_null()) {
+    objArrayHandle assumptions(Thread::current(), (objArrayOop)CiAssumptions::list(assumptions_handle()));
+    int length = assumptions->length();
+    for (int i = 0; i < length; ++i) {
+      Handle assumption = assumptions->obj_at(i);
+      if (!assumption.is_null()) {
+        if (assumption->klass() == CiAssumptions_MethodContents::klass()) {
+          assumption_MethodContents(assumption);
+        } else if (assumption->klass() == CiAssumptions_ConcreteSubtype::klass()) {
+          assumption_ConcreteSubtype(assumption);
+        } else if (assumption->klass() == CiAssumptions_ConcreteMethod::klass()) {
+          assumption_ConcreteMethod(assumption);
+        } else {
+          assumption->print();
+          fatal("unexpected Assumption subclass");
+        }
+      }
+    }
+  }
+}
+
+// constructor used to create a method
+CodeInstaller::CodeInstaller(Handle& target_method, nmethod*& nm, bool install_code) {
+  _env = CURRENT_ENV;
+  GraalCompiler::initialize_buffer_blob();
+  CodeBuffer buffer(JavaThread::current()->get_buffer_blob());
+  jobject target_method_obj = JNIHandles::make_local(target_method());
+  initialize_assumptions(JNIHandles::resolve(target_method_obj));
+
+  {
+    No_Safepoint_Verifier no_safepoint;
+    initialize_fields(JNIHandles::resolve(target_method_obj));
+    initialize_buffer(buffer);
+    process_exception_handlers();
+  }
+
+  int stack_slots = _total_frame_size / HeapWordSize; // conversion to words
+  methodHandle method = getMethodFromHotSpotMethod(HotSpotTargetMethod::method(JNIHandles::resolve(target_method_obj))); 
+
+  nm = GraalEnv::register_method(method, -1, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
+    &_implicit_exception_table, GraalCompiler::instance(), _debug_recorder, _dependencies, NULL, -1, true, false, install_code);
+
+  method->clear_queued_for_compilation();
+}
+
+// constructor used to create a stub
+CodeInstaller::CodeInstaller(Handle& target_method, jlong& id) {
+  No_Safepoint_Verifier no_safepoint;
+  _env = CURRENT_ENV;
+  
+  _oop_recorder = new OopRecorder(_env->arena());
+  _env->set_oop_recorder(_oop_recorder);
+  initialize_fields(target_method());
+  assert(_hotspot_method == NULL && _name != NULL, "installMethod needs NON-NULL name and NULL method");
+
+  // (very) conservative estimate: each site needs a relocation
+  GraalCompiler::initialize_buffer_blob();
+  CodeBuffer buffer(JavaThread::current()->get_buffer_blob());
+  initialize_buffer(buffer);
+
+  const char* cname = java_lang_String::as_utf8_string(_name);
+  BufferBlob* blob = BufferBlob::create(strdup(cname), &buffer); // this is leaking strings... but only a limited number of stubs will be created
+  IF_TRACE_graal_3 Disassembler::decode((CodeBlob*) blob);
+  id = VmIds::addStub(blob->code_begin());
+}
+
+void CodeInstaller::initialize_fields(oop target_method) {
+  _citarget_method = HotSpotTargetMethod::targetMethod(target_method);
+  _hotspot_method = HotSpotTargetMethod::method(target_method);
+  if (_hotspot_method != NULL) {
+    _parameter_count = getMethodFromHotSpotMethod(_hotspot_method)->size_of_parameters();
+  }
+  _name = HotSpotTargetMethod::name(target_method);
+  _sites = (arrayOop) HotSpotTargetMethod::sites(target_method);
+  _exception_handlers = (arrayOop) HotSpotTargetMethod::exceptionHandlers(target_method);
+
+  _code = (arrayOop) CiTargetMethod::targetCode(_citarget_method);
+  _code_size = CiTargetMethod::targetCodeSize(_citarget_method);
+  // The frame size we get from the target method does not include the return address, so add one word for it here.
+  _total_frame_size = CiTargetMethod::frameSize(_citarget_method) + HeapWordSize;
+  _custom_stack_area_offset = CiTargetMethod::customStackAreaOffset(_citarget_method);
+
+
+  // (very) conservative estimate: each site needs a constant section entry
+  _constants_size = _sites->length() * (BytesPerLong*2);
+  _total_size = align_size_up(_code_size, HeapWordSize) + _constants_size;
+
+  _next_call_type = MARK_INVOKE_INVALID;
+}
+
+// perform data and call relocation on the CodeBuffer
+void CodeInstaller::initialize_buffer(CodeBuffer& buffer) {
+  int locs_buffer_size = _sites->length() * (relocInfo::length_limit + sizeof(relocInfo));
+  char* locs_buffer = NEW_RESOURCE_ARRAY(char, locs_buffer_size);
+  buffer.insts()->initialize_shared_locs((relocInfo*)locs_buffer, locs_buffer_size / sizeof(relocInfo));
+  buffer.initialize_stubs_size(256);
+  buffer.initialize_consts_size(_constants_size);
+
+  _debug_recorder = new DebugInformationRecorder(_env->oop_recorder());
+  _debug_recorder->set_oopmaps(new OopMapSet());
+  
+  _env->set_debug_info(_debug_recorder);
+  buffer.initialize_oop_recorder(_oop_recorder);
+
+  _instructions = buffer.insts();
+  _constants = buffer.consts();
+
+  // copy the code into the newly created CodeBuffer
+  memcpy(_instructions->start(), _code->base(T_BYTE), _code_size);
+  _instructions->set_end(_instructions->start() + _code_size);
+
+  oop* sites = (oop*) _sites->base(T_OBJECT);
+  for (int i = 0; i < _sites->length(); i++) {
+    oop site = sites[i];
+    jint pc_offset = CiTargetMethod_Site::pcOffset(site);
+
+    if (site->is_a(CiTargetMethod_Call::klass())) {
+      TRACE_graal_4("call at %i", pc_offset);
+      site_Call(buffer, pc_offset, site);
+    } else if (site->is_a(CiTargetMethod_Safepoint::klass())) {
+      TRACE_graal_4("safepoint at %i", pc_offset);
+      site_Safepoint(buffer, pc_offset, site);
+    } else if (site->is_a(CiTargetMethod_DataPatch::klass())) {
+      TRACE_graal_4("datapatch at %i", pc_offset);
+      site_DataPatch(buffer, pc_offset, site);
+    } else if (site->is_a(CiTargetMethod_Mark::klass())) {
+      TRACE_graal_4("mark at %i", pc_offset);
+      site_Mark(buffer, pc_offset, site);
+    } else {
+      fatal("unexpected Site subclass");
+    }
+  }
+}
+
+void CodeInstaller::assumption_MethodContents(Handle assumption) {
+  Handle method_handle = CiAssumptions_MethodContents::method(assumption());
+  methodHandle method = getMethodFromHotSpotMethod(method_handle());
+  ciMethod* m = (ciMethod*) CURRENT_ENV->get_object(method());
+
+  _dependencies->assert_evol_method(m);
+}
+
+void CodeInstaller::assumption_ConcreteSubtype(Handle assumption) {
+  Handle context_handle = CiAssumptions_ConcreteSubtype::context(assumption());
+  ciKlass* context = (ciKlass*) CURRENT_ENV->get_object(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(context_handle)));
+
+  Handle type_handle = CiAssumptions_ConcreteSubtype::subtype(assumption());
+  ciKlass* type = (ciKlass*) CURRENT_ENV->get_object(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type_handle)));
+
+  _dependencies->assert_leaf_type(type);
+  if (context != type) {
+    assert(context->is_abstract(), "");
+    _dependencies->assert_abstract_with_unique_concrete_subtype(context, type);
+  }
+}
+
+void CodeInstaller::assumption_ConcreteMethod(Handle assumption) {
+  Handle impl_handle = CiAssumptions_ConcreteMethod::impl(assumption());
+  methodHandle impl = getMethodFromHotSpotMethod(impl_handle());
+  ciMethod* m = (ciMethod*) CURRENT_ENV->get_object(impl());
+  
+  Handle context_handle = CiAssumptions_ConcreteMethod::context(assumption());
+  ciKlass* context = (ciKlass*) CURRENT_ENV->get_object(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(context_handle)));
+  _dependencies->assert_unique_concrete_method(context, m);
+}
+
+void CodeInstaller::process_exception_handlers() {
+  // allocate some arrays for use by the collection code.
+  const int num_handlers = 5;
+  GrowableArray<intptr_t>* bcis = new GrowableArray<intptr_t> (num_handlers);
+  GrowableArray<intptr_t>* scope_depths = new GrowableArray<intptr_t> (num_handlers);
+  GrowableArray<intptr_t>* pcos = new GrowableArray<intptr_t> (num_handlers);
+
+  if (_exception_handlers != NULL) {
+    oop* exception_handlers = (oop*) _exception_handlers->base(T_OBJECT);
+    for (int i = 0; i < _exception_handlers->length(); i++) {
+      oop exc = exception_handlers[i];
+      jint pc_offset = CiTargetMethod_Site::pcOffset(exc);
+      jint handler_offset = CiTargetMethod_ExceptionHandler::handlerPos(exc);
+
+      // Subtable header
+      _exception_handler_table.add_entry(HandlerTableEntry(1, pc_offset, 0));
+
+      // Subtable entry
+      _exception_handler_table.add_entry(HandlerTableEntry(-1, handler_offset, 0));
+    }
+  }
+}
+
+void CodeInstaller::record_scope(jint pc_offset, oop code_pos, GrowableArray<ScopeValue*>* objects) {
+  oop caller_pos = CiCodePos::caller(code_pos);
+  if (caller_pos != NULL) {
+    record_scope(pc_offset, caller_pos, objects);
+  }
+  oop frame = NULL;
+  if (code_pos->klass()->klass_part()->name() == vmSymbols::com_oracle_max_cri_ci_CiFrame()) {
+    frame = code_pos;
+  }
+
+  oop hotspot_method = CiCodePos::method(code_pos);
+  methodOop method = getMethodFromHotSpotMethod(hotspot_method);
+  jint bci = CiCodePos::bci(code_pos);
+  bool reexecute;
+  if (bci == -1) {
+     reexecute = false;
+  } else {
+    Bytecodes::Code code = Bytecodes::java_code_at(method, method->bcp_from(bci));
+    reexecute = Interpreter::bytecode_should_reexecute(code);
+    if (frame != NULL) {
+      reexecute = (CiFrame::duringCall(frame) == 0);
+    }
+  }
+
+  if (TraceGraal >= 2) {
+    tty->print_cr("Recording scope pc_offset=%d bci=%d frame=%d", pc_offset, bci, frame);
+  }
+
+  if (frame != NULL) {
+    jint local_count = CiFrame::numLocals(frame);
+    jint expression_count = CiFrame::numStack(frame);
+    jint monitor_count = CiFrame::numLocks(frame);
+    arrayOop values = (arrayOop) CiFrame::values(frame);
+
+    assert(local_count + expression_count + monitor_count == values->length(), "unexpected values length");
+
+    GrowableArray<ScopeValue*>* locals = new GrowableArray<ScopeValue*> ();
+    GrowableArray<ScopeValue*>* expressions = new GrowableArray<ScopeValue*> ();
+    GrowableArray<MonitorValue*>* monitors = new GrowableArray<MonitorValue*> ();
+
+    if (TraceGraal >= 2) {
+      tty->print_cr("Scope at bci %d with %d values", bci, values->length());
+      tty->print_cr("%d locals %d expressions, %d monitors", local_count, expression_count, monitor_count);
+    }
+
+    for (jint i = 0; i < values->length(); i++) {
+      ScopeValue* second = NULL;
+      oop value = ((oop*) values->base(T_OBJECT))[i];
+
+      if (i < local_count) {
+        ScopeValue* first = get_hotspot_value(value, _total_frame_size, objects, second);
+        if (second != NULL) {
+          locals->append(second);
+        }
+        locals->append(first);
+      } else if (i < local_count + expression_count) {
+        ScopeValue* first = get_hotspot_value(value, _total_frame_size, objects, second);
+        if (second != NULL) {
+          expressions->append(second);
+        }
+        expressions->append(first);
+      } else {
+        monitors->append(get_monitor_value(value, _total_frame_size, objects));
+      }
+      if (second != NULL) {
+        i++;
+        assert(i < values->length(), "double-slot value not followed by CiValue.IllegalValue");
+        assert(((oop*) values->base(T_OBJECT))[i] == CiValue::IllegalValue(), "double-slot value not followed by CiValue.IllegalValue");
+      }
+    }
+
+    _debug_recorder->dump_object_pool(objects);
+
+    DebugToken* locals_token = _debug_recorder->create_scope_values(locals);
+    DebugToken* expressions_token = _debug_recorder->create_scope_values(expressions);
+    DebugToken* monitors_token = _debug_recorder->create_monitor_values(monitors);
+
+    bool throw_exception = false;
+    if (CiFrame::rethrowException(frame)) {
+      throw_exception = true;
+    }
+
+    _debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, false, locals_token, expressions_token, monitors_token);
+  } else {
+    _debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, false, false, false, NULL, NULL, NULL);
+  }
+}
+
+void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) {
+  oop debug_info = CiTargetMethod_Safepoint::debugInfo(site);
+  assert(debug_info != NULL, "debug info expected");
+
+  // address instruction = _instructions->start() + pc_offset;
+  // jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start();
+  _debug_recorder->add_safepoint(pc_offset, create_oop_map(_total_frame_size, _parameter_count, debug_info));
+
+  oop code_pos = CiDebugInfo::codePos(debug_info);
+  record_scope(pc_offset, code_pos, new GrowableArray<ScopeValue*>());
+
+  _debug_recorder->end_safepoint(pc_offset);
+}
+
+address CodeInstaller::runtime_call_target_address(oop runtime_call) {
+  address target_addr = 0x0;
+  if (runtime_call == CiRuntimeCall::Debug()) {
+    TRACE_graal_3("CiRuntimeCall::Debug()");
+  } else if (runtime_call == CiRuntimeCall::UnwindException()) {
+    target_addr = Runtime1::entry_for(Runtime1::graal_unwind_exception_call_id);
+    TRACE_graal_3("CiRuntimeCall::UnwindException()");
+  } else if (runtime_call == CiRuntimeCall::SetDeoptInfo()) {
+    target_addr = Runtime1::entry_for(Runtime1::graal_set_deopt_info_id);
+    TRACE_graal_3("CiRuntimeCall::SetDeoptInfo()");
+  } else if (runtime_call == CiRuntimeCall::CreateNullPointerException()) {
+    target_addr = Runtime1::entry_for(Runtime1::graal_create_null_pointer_exception_id);
+    TRACE_graal_3("CiRuntimeCall::CreateNullPointerException()");
+  } else if (runtime_call == CiRuntimeCall::CreateOutOfBoundsException()) {
+    target_addr = Runtime1::entry_for(Runtime1::graal_create_out_of_bounds_exception_id);
+    TRACE_graal_3("CiRuntimeCall::CreateOutOfBoundsException()");
+  } else if (runtime_call == CiRuntimeCall::JavaTimeMillis()) {
+    target_addr = CAST_FROM_FN_PTR(address, os::javaTimeMillis);
+    TRACE_graal_3("CiRuntimeCall::JavaTimeMillis()");
+  } else if (runtime_call == CiRuntimeCall::JavaTimeNanos()) {
+    target_addr = CAST_FROM_FN_PTR(address, os::javaTimeNanos);
+    TRACE_graal_3("CiRuntimeCall::JavaTimeNanos()");
+  } else if (runtime_call == CiRuntimeCall::ArithmeticFrem()) {
+    target_addr = Runtime1::entry_for(Runtime1::graal_arithmetic_frem_id);
+    TRACE_graal_3("CiRuntimeCall::ArithmeticFrem()");
+  } else if (runtime_call == CiRuntimeCall::ArithmeticDrem()) {
+    target_addr = Runtime1::entry_for(Runtime1::graal_arithmetic_drem_id);
+    TRACE_graal_3("CiRuntimeCall::ArithmeticDrem()");
+  } else if (runtime_call == CiRuntimeCall::ArithmeticSin()) {
+    target_addr = CAST_FROM_FN_PTR(address, SharedRuntime::dsin);
+    TRACE_graal_3("CiRuntimeCall::ArithmeticSin()");
+  } else if (runtime_call == CiRuntimeCall::ArithmeticCos()) {
+    target_addr = CAST_FROM_FN_PTR(address, SharedRuntime::dcos);
+    TRACE_graal_3("CiRuntimeCall::ArithmeticCos()");
+  } else if (runtime_call == CiRuntimeCall::ArithmeticTan()) {
+    target_addr = CAST_FROM_FN_PTR(address, SharedRuntime::dtan);
+    TRACE_graal_3("CiRuntimeCall::ArithmeticTan()");
+  } else if (runtime_call == CiRuntimeCall::RegisterFinalizer()) {
+    target_addr = Runtime1::entry_for(Runtime1::register_finalizer_id);
+    TRACE_graal_3("CiRuntimeCall::RegisterFinalizer()");
+  } else if (runtime_call == CiRuntimeCall::Deoptimize()) {
+    target_addr = SharedRuntime::deopt_blob()->uncommon_trap();
+    TRACE_graal_3("CiRuntimeCall::Deoptimize()");
+  } else if (runtime_call == CiRuntimeCall::GenericCallback()) {
+    target_addr = Runtime1::entry_for(Runtime1::graal_generic_callback_id);
+    TRACE_graal_3("CiRuntimeCall::GenericCallback()");
+  } else {
+    runtime_call->print();
+    fatal("runtime_call not implemented");
+  }
+  return target_addr;
+}
+
+void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, oop site) {
+  oop target = CiTargetMethod_Call::target(site);
+  instanceKlass* target_klass = instanceKlass::cast(target->klass());
+
+  oop runtime_call = NULL; // CiRuntimeCall
+  oop hotspot_method = NULL; // RiMethod
+  oop global_stub = NULL;
+
+  if (target_klass->is_subclass_of(SystemDictionary::Long_klass())) {
+    global_stub = target;
+  } else if (target_klass->name() == vmSymbols::com_oracle_max_cri_ci_CiRuntimeCall()) {
+    runtime_call = target;
+  } else {
+    hotspot_method = target;
+  }
+
+  oop debug_info = CiTargetMethod_Call::debugInfo(site);
+
+  assert((runtime_call ? 1 : 0) + (hotspot_method ? 1 : 0) + (global_stub ? 1 : 0) == 1, "Call site needs exactly one type");
+
+  NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset);
+  jint next_pc_offset = 0x0;
+  if (inst->is_call() || inst->is_jump()) {
+    assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size");
+    next_pc_offset = pc_offset + NativeCall::instruction_size;
+  } else if (inst->is_mov_literal64()) {
+    // mov+call instruction pair
+    next_pc_offset = pc_offset + NativeMovConstReg::instruction_size;
+    u_char* call = (u_char*) (_instructions->start() + next_pc_offset);
+    assert((call[0] == 0x40 || call[0] == 0x41) && call[1] == 0xFF, "expected call with rex/rexb prefix byte");
+    next_pc_offset += 3; /* prefix byte + opcode byte + modrm byte */
+  } else {
+    runtime_call->print();
+    fatal("unsupported type of instruction for call site");
+  }
+
+  if (target->is_a(SystemDictionary::HotSpotCompiledMethod_klass())) {
+    assert(inst->is_jump(), "jump expected");
+
+    nmethod* nm = (nmethod*) HotSpotCompiledMethod::nmethod(target);
+    nativeJump_at((address)inst)->set_jump_destination(nm->verified_entry_point());
+    _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
+
+    return;
+  }
+
+  if (debug_info != NULL) {
+    _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_total_frame_size, _parameter_count, debug_info));
+    oop code_pos = CiDebugInfo::codePos(debug_info);
+    record_scope(next_pc_offset, code_pos, new GrowableArray<ScopeValue*>());
+  }
+
+  if (runtime_call != NULL) {
+    if (runtime_call != CiRuntimeCall::Debug()) {
+      address target_addr = runtime_call_target_address(runtime_call);
+
+      if (inst->is_call()) {
+        // NOTE: for call without a mov, the offset must fit a 32-bit immediate
+        //       see also CompilerToVM.getMaxCallTargetOffset()
+        NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
+        call->set_destination(target_addr);
+        _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand);
+      } else if (inst->is_mov_literal64()) {
+        NativeMovConstReg* mov = nativeMovConstReg_at(_instructions->start() + pc_offset);
+        mov->set_data((intptr_t) target_addr);
+        _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand);
+      } else {
+        runtime_call->print();
+        fatal("unknown type of instruction for runtime call");
+      }
+    }
+  } else if (global_stub != NULL) {
+    assert(java_lang_boxing_object::is_instance(global_stub, T_LONG), "global_stub needs to be of type Long");
+
+    if (inst->is_call()) {
+      nativeCall_at((address)inst)->set_destination(VmIds::getStub(global_stub));
+    } else {
+      nativeJump_at((address)inst)->set_jump_destination(VmIds::getStub(global_stub));
+    }
+    _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
+    TRACE_graal_3("relocating (stub)  at %016x", inst);
+  } else { // method != NULL
+    NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
+    assert(hotspot_method != NULL, "unexpected RiMethod");
+    assert(debug_info != NULL, "debug info expected");
+
+    methodOop method = NULL;
+    // we need to check, this might also be an unresolved method
+    if (hotspot_method->is_a(HotSpotMethodResolved::klass())) {
+      method = getMethodFromHotSpotMethod(hotspot_method);
+    }
+
+    assert(debug_info != NULL, "debug info expected");
+
+    TRACE_graal_3("method call");
+    switch (_next_call_type) {
+      case MARK_INVOKEVIRTUAL:
+      case MARK_INVOKEINTERFACE: {
+        assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface");
+
+        call->set_destination(SharedRuntime::get_resolve_virtual_call_stub());
+        _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc), Assembler::call32_operand);
+        break;
+      }
+      case MARK_INVOKESTATIC: {
+        assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic");
+
+        call->set_destination(SharedRuntime::get_resolve_static_call_stub());
+        _instructions->relocate(call->instruction_address(), relocInfo::static_call_type, Assembler::call32_operand);
+        break;
+      }
+      case MARK_INVOKESPECIAL: {
+        assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial");
+
+        call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
+        _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type, Assembler::call32_operand);
+        break;
+      }
+      case MARK_INVOKE_INVALID:
+      default:
+        fatal("invalid _next_call_type value");
+        break;
+    }
+  }
+  _next_call_type = MARK_INVOKE_INVALID;
+  if (debug_info != NULL) {
+    _debug_recorder->end_safepoint(next_pc_offset);
+  }
+}
+
+void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) {
+  oop constant = CiTargetMethod_DataPatch::constant(site);
+  int alignment = CiTargetMethod_DataPatch::alignment(site);
+  oop kind = CiConstant::kind(constant);
+
+  address instruction = _instructions->start() + pc_offset;
+
+  char typeChar = CiKind::typeChar(kind);
+  switch (typeChar) {
+    case 'z':
+    case 'b':
+    case 's':
+    case 'c':
+    case 'i':
+      fatal("int-sized values not expected in DataPatch")
+      ;
+      break;
+    case 'f':
+    case 'j':
+    case 'd': {
+      address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand);
+      address next_instruction = Assembler::locate_next_instruction(instruction);
+      int size = _constants->size();
+      if (alignment > 0) {
+        guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin");
+        size = align_size_up(size, alignment);
+      }
+      // we don't care if this is a long/double/etc., the primitive field contains the right bits
+      address dest = _constants->start() + size;
+      _constants->set_end(dest + BytesPerLong);
+      *(jlong*) dest = CiConstant::primitive(constant);
+
+      long disp = dest - next_instruction;
+      assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
+      *((jint*) operand) = (jint) disp;
+
+      _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
+      TRACE_graal_3("relocating (%c) at %016x/%016x with destination at %016x (%d)", typeChar, instruction, operand, dest, size);
+      break;
+    }
+    case 'a': {
+      address operand = Assembler::locate_operand(instruction, Assembler::imm_operand);
+      Handle obj = CiConstant::object(constant);
+
+      if (obj->is_a(HotSpotTypeResolved::klass())) {
+        assert(!obj.is_null(), "");
+        *((jobject*) operand) = JNIHandles::make_local(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(obj)));
+        _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
+        TRACE_graal_3("relocating (HotSpotType) at %016x/%016x", instruction, operand);
+      } else {
+        jobject value = JNIHandles::make_local(obj());
+        if (obj() == HotSpotProxy::DUMMY_CONSTANT_OBJ()) {
+          value = (jobject) Universe::non_oop_word();
+        }
+        *((jobject*) operand) = value;
+        _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
+        TRACE_graal_3("relocating (oop constant) at %016x/%016x", instruction, operand);
+      }
+      break;
+    }
+    default:
+      fatal("unexpected CiKind in DataPatch");
+      break;
+  }
+}
+
+void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) {
+  oop id_obj = CiTargetMethod_Mark::id(site);
+  arrayOop references = (arrayOop) CiTargetMethod_Mark::references(site);
+
+  if (id_obj != NULL) {
+    assert(java_lang_boxing_object::is_instance(id_obj, T_INT), "Integer id expected");
+    jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT));
+
+    address instruction = _instructions->start() + pc_offset;
+
+    switch (id) {
+      case MARK_UNVERIFIED_ENTRY:
+        _offsets.set_value(CodeOffsets::Entry, pc_offset);
+        break;
+      case MARK_VERIFIED_ENTRY:
+        _offsets.set_value(CodeOffsets::Verified_Entry, pc_offset);
+        break;
+      case MARK_OSR_ENTRY:
+        _offsets.set_value(CodeOffsets::OSR_Entry, pc_offset);
+        break;
+      case MARK_UNWIND_ENTRY:
+        _offsets.set_value(CodeOffsets::UnwindHandler, pc_offset);
+        break;
+      case MARK_EXCEPTION_HANDLER_ENTRY:
+        _offsets.set_value(CodeOffsets::Exceptions, pc_offset);
+        break;
+      case MARK_DEOPT_HANDLER_ENTRY:
+        _offsets.set_value(CodeOffsets::Deopt, pc_offset);
+        break;
+      case MARK_STATIC_CALL_STUB: {
+        assert(references->length() == 1, "static call stub needs one reference");
+        oop ref = ((oop*) references->base(T_OBJECT))[0];
+        address call_pc = _instructions->start() + CiTargetMethod_Site::pcOffset(ref);
+        _instructions->relocate(instruction, static_stub_Relocation::spec(call_pc));
+        _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
+        break;
+      }
+      case MARK_INVOKE_INVALID:
+      case MARK_INVOKEINTERFACE:
+      case MARK_INVOKESTATIC:
+      case MARK_INVOKESPECIAL:
+      case MARK_INVOKEVIRTUAL:
+        _next_call_type = (MarkId) id;
+        _invoke_mark_pc = instruction;
+        break;
+      case MARK_IMPLICIT_NULL:
+        _implicit_exception_table.append(pc_offset, pc_offset);
+        break;
+      case MARK_POLL_NEAR: {
+        NativeInstruction* ni = nativeInstruction_at(instruction);
+        int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand);
+        intptr_t new_disp = (intptr_t) (os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())) - (intptr_t) ni;
+        *disp = (int32_t)new_disp;
+      }
+      case MARK_POLL_FAR:
+        _instructions->relocate(instruction, relocInfo::poll_type);
+        break;
+      case MARK_POLL_RETURN_NEAR: {
+        NativeInstruction* ni = nativeInstruction_at(instruction);
+        int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand);
+        intptr_t new_disp = (intptr_t) (os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())) - (intptr_t) ni;
+        *disp = (int32_t)new_disp;
+      }
+      case MARK_POLL_RETURN_FAR:
+        _instructions->relocate(instruction, relocInfo::poll_return_type);
+        break;
+      case MARK_KLASS_PATCHING:
+      case MARK_ACCESS_FIELD_PATCHING: {
+        unsigned char* byte_count = (unsigned char*) (instruction - 1);
+        unsigned char* byte_skip = (unsigned char*) (instruction - 2);
+        unsigned char* being_initialized_entry_offset = (unsigned char*) (instruction - 3);
+
+        assert(*byte_skip == 5, "unexpected byte_skip");
+
+        assert(references->length() == 2, "MARK_KLASS_PATCHING/MARK_ACCESS_FIELD_PATCHING needs 2 references");
+        oop ref1 = ((oop*) references->base(T_OBJECT))[0];
+        oop ref2 = ((oop*) references->base(T_OBJECT))[1];
+        int i_byte_count = CiTargetMethod_Site::pcOffset(ref2) - CiTargetMethod_Site::pcOffset(ref1);
+        assert(i_byte_count == (unsigned char)i_byte_count, "invalid offset");
+        *byte_count = i_byte_count;
+        *being_initialized_entry_offset = *byte_count + *byte_skip;
+
+        // we need to correct the offset of a field access - it's created with MAX_INT to ensure the correct size, and hotspot expects 0
+        if (id == MARK_ACCESS_FIELD_PATCHING) {
+          NativeMovRegMem* inst = nativeMovRegMem_at(_instructions->start() + CiTargetMethod_Site::pcOffset(ref1));
+          assert(inst->offset() == max_jint, "unexpected offset value");
+          inst->set_offset(0);
+        }
+        break;
+      }
+      case MARK_DUMMY_OOP_RELOCATION: {
+        _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
+
+        RelocIterator iter(_instructions, (address) instruction, (address) (instruction + 1));
+        relocInfo::change_reloc_info_for_address(&iter, (address) instruction, relocInfo::oop_type, relocInfo::none);
+        break;
+      }
+      default:
+        ShouldNotReachHere();
+        break;
+    }
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/graal/graalCodeInstaller.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+/*
+ * This class handles the conversion from a CiTargetMethod to a CodeBlob or an nmethod.
+ */
+class CodeInstaller {
+private:
+  // these need to correspond to HotSpotXirGenerator.java
+  enum MarkId {
+    MARK_VERIFIED_ENTRY             = 0x0001,
+    MARK_UNVERIFIED_ENTRY           = 0x0002,
+    MARK_OSR_ENTRY                  = 0x0003,
+    MARK_UNWIND_ENTRY               = 0x0004,
+    MARK_EXCEPTION_HANDLER_ENTRY    = 0x0005,
+    MARK_DEOPT_HANDLER_ENTRY        = 0x0006,
+    MARK_STATIC_CALL_STUB           = 0x1000,
+    MARK_INVOKE_INVALID             = 0x2000,
+    MARK_INVOKEINTERFACE            = 0x2001,
+    MARK_INVOKESTATIC               = 0x2002,
+    MARK_INVOKESPECIAL              = 0x2003,
+    MARK_INVOKEVIRTUAL              = 0x2004,
+    MARK_IMPLICIT_NULL              = 0x3000,
+    MARK_POLL_NEAR                  = 0x3001,
+    MARK_POLL_RETURN_NEAR           = 0x3002,
+    MARK_POLL_FAR                   = 0x3003,
+    MARK_POLL_RETURN_FAR            = 0x3004,
+    MARK_KLASS_PATCHING             = 0x4000,
+    MARK_DUMMY_OOP_RELOCATION       = 0x4001,
+    MARK_ACCESS_FIELD_PATCHING      = 0x4002
+  };
+
+  ciEnv*        _env;
+
+  oop           _citarget_method;
+  oop           _hotspot_method;
+  oop           _name;
+  arrayOop      _sites;
+  arrayOop      _exception_handlers;
+  CodeOffsets   _offsets;
+
+  arrayOop      _code;
+  jint          _code_size;
+  jint          _total_frame_size;
+  jint          _custom_stack_area_offset;
+  jint          _parameter_count;
+  jint          _constants_size;
+  jint          _total_size;
+
+  MarkId        _next_call_type;
+  address       _invoke_mark_pc;
+
+  CodeSection*  _instructions;
+  CodeSection*  _constants;
+
+  OopRecorder*              _oop_recorder;
+  DebugInformationRecorder* _debug_recorder;
+  Dependencies*             _dependencies;
+  ExceptionHandlerTable     _exception_handler_table;
+  ImplicitExceptionTable    _implicit_exception_table;
+
+public:
+
+  // constructor used to create a method
+  CodeInstaller(Handle& target_method, nmethod*& nm, bool install_code);
+
+  // constructor used to create a stub
+  CodeInstaller(Handle& target_method, jlong& id);
+
+  static address runtime_call_target_address(oop runtime_call);
+
+private:
+  // extract the fields of the CiTargetMethod
+  void initialize_fields(oop target_method);
+  void initialize_assumptions(oop target_method);
+
+  // perform data and call relocation on the CodeBuffer
+  void initialize_buffer(CodeBuffer& buffer);
+
+  void assumption_MethodContents(Handle assumption);
+  void assumption_ConcreteSubtype(Handle assumption);
+  void assumption_ConcreteMethod(Handle assumption);
+
+  void site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site);
+  void site_Call(CodeBuffer& buffer, jint pc_offset, oop site);
+  void site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site);
+  void site_Mark(CodeBuffer& buffer, jint pc_offset, oop site);
+
+  void record_scope(jint pc_offset, oop code_pos, GrowableArray<ScopeValue*>* objects);
+
+  void process_exception_handlers();
+
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/graal/graalCompiler.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,319 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "graal/graalCompiler.hpp"
+#include "graal/graalJavaAccess.hpp"
+#include "graal/graalVMToCompiler.hpp"
+#include "graal/graalCompilerToVM.hpp"
+#include "graal/graalVmIds.hpp"
+#include "graal/graalEnv.hpp"
+#include "c1/c1_Runtime1.hpp"
+#include "compiler/compilerOracle.hpp"
+#include "runtime/arguments.hpp"
+
+GraalCompiler* GraalCompiler::_instance = NULL;
+
+GraalCompiler::GraalCompiler() {
+  _initialized = false;
+  assert(_instance == NULL, "only one instance allowed");
+  _instance = this;
+}
+
+// Initialization
+void GraalCompiler::initialize() {
+  
+  ThreadToNativeFromVM trans(JavaThread::current());
+  JavaThread* THREAD = JavaThread::current();
+  TRACE_graal_1("GraalCompiler::initialize");
+
+  initialize_buffer_blob();
+  Runtime1::initialize(THREAD->get_buffer_blob());
+
+  JNIEnv *env = ((JavaThread *) Thread::current())->jni_environment();
+  jclass klass = env->FindClass("com/oracle/max/graal/hotspot/bridge/CompilerToVMImpl");
+  if (klass == NULL) {
+    tty->print_cr("graal CompilerToVMImpl class not found");
+    vm_abort(false);
+  }
+  env->RegisterNatives(klass, CompilerToVM_methods, CompilerToVM_methods_count());
+
+  ResourceMark rm;
+  HandleMark hm;
+  {
+    VM_ENTRY_MARK;
+    check_pending_exception("Could not register natives");
+  }
+
+  graal_compute_offsets();
+
+  {
+    VM_ENTRY_MARK;
+    HandleMark hm;
+    VMToCompiler::initializeCompiler();
+    VMToCompiler::setDefaultOptions();
+    for (int i = 0; i < Arguments::num_graal_args(); ++i) {
+      const char* arg = Arguments::graal_args_array()[i];
+      Handle option = java_lang_String::create_from_str(arg, THREAD);
+      jboolean result = VMToCompiler::setOption(option);
+      if (!result) {
+        tty->print_cr("Invalid option for graal!");
+        vm_abort(false);
+      }
+    }
+    if (UseCompiler) {
+      VMToCompiler::startCompiler();
+      _initialized = true;
+      if (BootstrapGraal) {
+        VMToCompiler::bootstrap();
+      }
+    }
+  }
+}
+
+void GraalCompiler::initialize_buffer_blob() {
+
+  JavaThread* THREAD = JavaThread::current();
+  if (THREAD->get_buffer_blob() == NULL) {
+    // setup CodeBuffer.  Preallocate a BufferBlob of size
+    // NMethodSizeLimit plus some extra space for constants.
+    int code_buffer_size = Compilation::desired_max_code_buffer_size() +
+      Compilation::desired_max_constant_size();
+    BufferBlob* blob = BufferBlob::create("graal temporary CodeBuffer",
+                                          code_buffer_size);
+    guarantee(blob != NULL, "must create code buffer");
+    THREAD->set_buffer_blob(blob);
+  }
+}
+
+void GraalCompiler::compile_method(methodHandle method, int entry_bci, jboolean blocking) {
+  EXCEPTION_CONTEXT
+  if (!_initialized) {
+    method->clear_queued_for_compilation();
+    method->invocation_counter()->reset();
+    method->backedge_counter()->reset();
+    return;
+  }
+  assert(_initialized, "must already be initialized");
+  ResourceMark rm;
+  ciEnv* current_env = JavaThread::current()->env();
+  JavaThread::current()->set_env(NULL);
+  JavaThread::current()->set_compiling(true);
+  Handle hotspot_method = GraalCompiler::createHotSpotMethodResolved(method, CHECK);
+  VMToCompiler::compileMethod(hotspot_method, entry_bci, blocking);
+  JavaThread::current()->set_compiling(false);
+  JavaThread::current()->set_env(current_env);
+}
+
+// Compilation entry point for methods
+void GraalCompiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci) {
+  ShouldNotReachHere();
+}
+
+void GraalCompiler::exit() {
+  if (_initialized) {
+    VMToCompiler::shutdownCompiler();
+  }
+}
+
+// Print compilation timers and statistics
+void GraalCompiler::print_timers() {
+  TRACE_graal_1("GraalCompiler::print_timers");
+}
+
+Handle GraalCompiler::get_RiType(Symbol* klass_name, TRAPS) {
+   return VMToCompiler::createRiTypeUnresolved(VmIds::toString<Handle>(klass_name, THREAD), THREAD);
+}
+
+Handle GraalCompiler::get_RiTypeFromSignature(constantPoolHandle cp, int index, KlassHandle loading_klass, TRAPS) {
+  
+  Symbol* signature = cp->symbol_at(index);
+  BasicType field_type = FieldType::basic_type(signature);
+  // If the field is a pointer type, get the klass of the
+  // field.
+  if (field_type == T_OBJECT || field_type == T_ARRAY) {
+    KlassHandle handle = GraalEnv::get_klass_by_name(loading_klass, signature, false);
+    if (handle.is_null()) {
+      return get_RiType(signature, CHECK_NULL);
+    } else {
+      return get_RiType(handle, CHECK_NULL);
+    }
+  } else {
+    return VMToCompiler::createRiTypePrimitive(field_type, CHECK_NULL);
+  }
+}
+
+Handle GraalCompiler::get_RiType(constantPoolHandle cp, int index, KlassHandle loading_klass, TRAPS) {
+  bool is_accessible = false;
+
+  KlassHandle klass = GraalEnv::get_klass_by_index(cp, index, is_accessible, loading_klass);
+  oop catch_class = NULL;
+  if (klass.is_null()) {
+    // We have to lock the cpool to keep the oop from being resolved
+    // while we are accessing it.
+    ObjectLocker ol(cp, THREAD);
+
+    Symbol* klass_name = NULL;
+    constantTag tag = cp->tag_at(index);
+    if (tag.is_klass()) {
+      // The klass has been inserted into the constant pool
+      // very recently.
+      return GraalCompiler::get_RiType(cp->resolved_klass_at(index), CHECK_NULL);
+    } else if (tag.is_symbol()) {
+      klass_name = cp->symbol_at(index);
+    } else {
+      assert(cp->tag_at(index).is_unresolved_klass(), "wrong tag");
+      klass_name = cp->unresolved_klass_at(index);
+    }
+    return GraalCompiler::get_RiType(klass_name, CHECK_NULL);
+  } else {
+    return GraalCompiler::get_RiType(klass, CHECK_NULL);
+  }
+}
+
+Handle GraalCompiler::get_RiType(KlassHandle klass, TRAPS) {
+  Handle name = VmIds::toString<Handle>(klass->name(), THREAD);
+  return createHotSpotTypeResolved(klass, name, CHECK_NULL);
+}
+
+Handle GraalCompiler::get_RiField(int offset, int flags, Symbol* field_name, Handle field_holder, Handle field_type, Bytecodes::Code byteCode, TRAPS) {
+  Handle name = VmIds::toString<Handle>(field_name, CHECK_NULL);
+  return VMToCompiler::createRiField(field_holder, name, field_type, offset, flags, CHECK_NULL);
+}
+
+Handle GraalCompiler::createHotSpotTypeResolved(KlassHandle klass, Handle name, TRAPS) {
+  ObjectLocker ol(klass, THREAD);
+
+  if (klass->graal_mirror() != NULL) {
+    return klass->graal_mirror();
+  }
+
+  instanceKlass::cast(HotSpotTypeResolved::klass())->initialize(CHECK_NULL);
+  Handle obj = instanceKlass::cast(HotSpotTypeResolved::klass())->allocate_instance(CHECK_NULL);
+  assert(obj() != NULL, "must succeed in allocating instance");
+
+  HotSpotTypeResolved::set_compiler(obj, VMToCompiler::compilerInstance()());
+
+  if (klass->oop_is_instance()) {
+    ResourceMark rm;
+    instanceKlass* ik = (instanceKlass*)klass()->klass_part();
+    Handle full_name = java_lang_String::create_from_str(ik->signature_name(), CHECK_NULL);
+    HotSpotType::set_name(obj, full_name());
+  } else {
+    HotSpotType::set_name(obj, name());
+  }
+
+  HotSpotTypeResolved::set_javaMirror(obj, klass->java_mirror());
+  HotSpotTypeResolved::set_simpleName(obj, name());
+  HotSpotTypeResolved::set_accessFlags(obj, klass->access_flags().as_int());
+  HotSpotTypeResolved::set_isInterface(obj, klass->is_interface());
+  HotSpotTypeResolved::set_isInstanceClass(obj, klass->oop_is_instance());
+
+  if (klass->oop_is_javaArray()) {
+    HotSpotTypeResolved::set_isArrayClass(obj, true);
+  } else {
+    HotSpotTypeResolved::set_isArrayClass(obj, false);
+    HotSpotTypeResolved::set_instanceSize(obj, instanceKlass::cast(klass())->size_helper() * HeapWordSize);
+    HotSpotTypeResolved::set_hasFinalizer(obj, klass->has_finalizer());
+  }
+
+  // TODO replace these with correct values
+  HotSpotTypeResolved::set_hasSubclass(obj, false);
+  HotSpotTypeResolved::set_hasFinalizableSubclass(obj, false);
+
+  klass->set_graal_mirror(obj());
+
+  return obj;
+}
+
+Handle GraalCompiler::createHotSpotMethodResolved(methodHandle method, TRAPS) {
+  if (method->graal_mirror() != NULL) {
+    assert(method->graal_mirror()->is_a(HotSpotMethodResolved::klass()), "unexpected class...");
+    return method->graal_mirror();
+  }
+
+  Handle name = VmIds::toString<Handle>(method->name(), CHECK_NULL);
+
+  instanceKlass::cast(HotSpotMethodResolved::klass())->initialize(CHECK_NULL);
+  Handle obj = instanceKlass::cast(HotSpotMethodResolved::klass())->allocate_instance(CHECK_NULL);
+  assert(obj() != NULL, "must succeed in allocating instance");
+  
+  HotSpotMethodResolved::set_compiler(obj, VMToCompiler::compilerInstance()());
+  // (tw) Cannot use reflection here, because the compiler thread could dead lock with the running application.
+  // oop reflected = getReflectedMethod(method(), CHECK_NULL);
+  HotSpotMethodResolved::set_javaMirror(obj, method());
+  HotSpotMethodResolved::set_name(obj, name());
+  
+  KlassHandle klass = method->method_holder();
+  Handle holder_name = VmIds::toString<Handle>(klass->name(), CHECK_NULL);
+  Handle holder = GraalCompiler::createHotSpotTypeResolved(klass, holder_name, CHECK_NULL);
+  HotSpotMethodResolved::set_holder(obj, holder());
+  
+  HotSpotMethodResolved::set_codeSize(obj, method->code_size());
+  HotSpotMethodResolved::set_accessFlags(obj, method->access_flags().as_int());
+  HotSpotMethodResolved::set_maxLocals(obj, method->max_locals());
+  HotSpotMethodResolved::set_maxStackSize(obj, method->max_stack());
+  HotSpotMethodResolved::set_canBeInlined(obj, !CompilerOracle::should_not_inline(method));
+  
+  method->set_graal_mirror(obj());
+  return obj;
+}
+
+Handle GraalCompiler::createHotSpotMethodData(methodDataHandle method_data, TRAPS) {
+  if(method_data->graal_mirror() != NULL) {
+    assert(method_data->graal_mirror()->is_a(HotSpotMethodData::klass()), "unexpected class");
+    return method_data->graal_mirror();
+  }
+
+  instanceKlass::cast(HotSpotMethodData::klass())->initialize(CHECK_NULL);
+  Handle obj = instanceKlass::cast(HotSpotMethodData::klass())->allocate_instance(CHECK_NULL);
+  assert(obj.not_null(), "must succeed in allocating instance");
+  
+  HotSpotMethodData::set_compiler(obj, VMToCompiler::compilerInstance()());
+  HotSpotMethodData::set_hotspotMirror(obj, method_data());
+  HotSpotMethodData::set_normalDataSize(obj, method_data()->data_size());
+  HotSpotMethodData::set_extraDataSize(obj, method_data()->extra_data_size());
+
+  method_data->set_graal_mirror(obj());
+  return obj;
+}
+
+BasicType GraalCompiler::kindToBasicType(jchar ch) {
+  switch(ch) {
+    case 'z': return T_BOOLEAN;
+    case 'b': return T_BYTE;
+    case 's': return T_SHORT;
+    case 'c': return T_CHAR;
+    case 'i': return T_INT;
+    case 'f': return T_FLOAT;
+    case 'j': return T_LONG;
+    case 'd': return T_DOUBLE;
+    case 'a': return T_OBJECT;
+    case 'r': return T_ADDRESS;
+    case '-': return T_ILLEGAL;
+    default:
+      fatal(err_msg("unexpected CiKind: %c", ch));
+      break;
+  }
+  return T_ILLEGAL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/graal/graalCompiler.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+#include "compiler/abstractCompiler.hpp"
+
+class GraalCompiler : public AbstractCompiler {
+
+private:
+
+  bool                  _initialized;
+
+  static GraalCompiler*   _instance;
+
+public:
+
+  GraalCompiler();
+
+  static GraalCompiler* instance() { return _instance; }
+
+
+  virtual const char* name() { return "G"; }
+
+  // Native / OSR not supported
+  virtual bool supports_native()                 { return false; }
+  virtual bool supports_osr   ()                 { return false; }
+
+  // Pretend to be C1
+  bool is_c1   ()                                { return true; }
+  bool is_c2   ()                                { return false; }
+
+  // Initialization
+  virtual void initialize();
+
+  // Compilation entry point for methods
+  virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci);
+
+  void compile_method(methodHandle target, int entry_bci, jboolean blocking);
+
+  // Print compilation timers and statistics
+  virtual void print_timers();
+  
+  static Handle get_RiTypeFromSignature(constantPoolHandle cp, int index, KlassHandle accessor, TRAPS);
+  static Handle get_RiType(constantPoolHandle cp, int index, KlassHandle accessor, TRAPS);
+  static Handle get_RiType(Symbol* klass_name, TRAPS);
+  static Handle get_RiType(KlassHandle klass, TRAPS);
+  static Handle get_RiField(int offset, int flags, Symbol* field_name, Handle field_holder, Handle field_type, Bytecodes::Code byteCode, TRAPS);
+
+  static Handle createHotSpotTypeResolved(KlassHandle klass, Handle name, TRAPS);
+  static Handle createHotSpotMethodResolved(methodHandle method, TRAPS);
+  static Handle createHotSpotMethodData(methodDataHandle method_data, TRAPS);
+
+  void exit();
+
+  static BasicType kindToBasicType(jchar ch);
+
+  static int to_cp_index_u2(int index) {
+    // Tag.
+    return to_index_u2(index) + constantPoolOopDesc::CPCACHE_INDEX_TAG;
+  }
+
+  static int to_index_u2(int index) {
+    // Swap.
+    return ((index & 0xFF) << 8) | (index >> 8);
+  }
+
+  static void initialize_buffer_blob();
+};
+
+// Tracing macros
+
+#define IF_TRACE_graal_1 if (!(TraceGraal >= 1)) ; else
+#define IF_TRACE_graal_2 if (!(TraceGraal >= 2)) ; else
+#define IF_TRACE_graal_3 if (!(TraceGraal >= 3)) ; else
+#define IF_TRACE_graal_4 if (!(TraceGraal >= 4)) ; else
+#define IF_TRACE_graal_5 if (!(TraceGraal >= 5)) ; else
+
+// using commas and else to keep one-instruction semantics
+
+#define TRACE_graal_1 if (!(TraceGraal >= 1 && (tty->print("TraceGraal-1: "), true))) ; else tty->print_cr
+#define TRACE_graal_2 if (!(TraceGraal >= 2 && (tty->print("   TraceGraal-2: "), true))) ; else tty->print_cr
+#define TRACE_graal_3 if (!(TraceGraal >= 3 && (tty->print("      TraceGraal-3: "), true))) ; else tty->print_cr
+#define TRACE_graal_4 if (!(TraceGraal >= 4 && (tty->print("         TraceGraal-4: "), true))) ; else tty->print_cr
+#define TRACE_graal_5 if (!(TraceGraal >= 5 && (tty->print("            TraceGraal-5: "), true))) ; else tty->print_cr
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,992 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "runtime/fieldDescriptor.hpp"
+#include "c1/c1_Runtime1.hpp"
+#include "ci/ciMethodData.hpp"
+#include "compiler/compileBroker.hpp"
+#include "graal/graalCompilerToVM.hpp"
+#include "graal/graalCompiler.hpp"
+#include "graal/graalEnv.hpp"
+#include "graal/graalJavaAccess.hpp"
+#include "graal/graalCodeInstaller.hpp"
+#include "graal/graalVMToCompiler.hpp"
+#include "graal/graalVmIds.hpp"
+#include "memory/oopFactory.hpp"
+#include "oops/generateOopMap.hpp"
+
+methodOop getMethodFromHotSpotMethod(jobject hotspot_method) {
+  return getMethodFromHotSpotMethod(JNIHandles::resolve(hotspot_method));
+}
+
+methodOop getMethodFromHotSpotMethod(oop hotspot_method) {
+  return (methodOop)HotSpotMethodResolved::javaMirror(hotspot_method);
+}
+
+methodDataOop getMethodDataFromHotSpotMethodData(jobject hotspot_method_data) {
+  return (methodDataOop)HotSpotMethodData::hotspotMirror(JNIHandles::resolve(hotspot_method_data));
+}
+
+// public byte[] RiMethod_code(HotSpotResolvedMethod method);
+JNIEXPORT jbyteArray JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1code(JNIEnv *env, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::RiMethod_code");
+  methodHandle method = getMethodFromHotSpotMethod(hotspot_method);
+  int code_size = method->code_size();
+  jbyteArray result = env->NewByteArray(code_size);
+  env->SetByteArrayRegion(result, 0, code_size, (const jbyte *) method->code_base());
+  return result;
+}
+
+// public String RiMethod_signature(HotSpotResolvedMethod method);
+JNIEXPORT jstring JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1signature(JNIEnv *env, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::RiMethod_signature");
+  VM_ENTRY_MARK
+  methodOop method = getMethodFromHotSpotMethod(hotspot_method);
+  assert(method != NULL && method->signature() != NULL, "signature required");
+  return VmIds::toString<jstring>(method->signature(), THREAD);
+}
+
+// public RiExceptionHandler[] RiMethod_exceptionHandlers(long vmId);
+JNIEXPORT jobjectArray JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1exceptionHandlers(JNIEnv *, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::RiMethod_exceptionHandlers");
+  VM_ENTRY_MARK
+  ResourceMark rm;
+  methodHandle method = getMethodFromHotSpotMethod(hotspot_method);
+  typeArrayHandle handlers = method->exception_table();
+  int handler_count = handlers.is_null() ? 0 : handlers->length() / 4;
+
+  instanceKlass::cast(HotSpotExceptionHandler::klass())->initialize(CHECK_NULL);
+  objArrayHandle array = oopFactory::new_objArray(SystemDictionary::RiExceptionHandler_klass(), handler_count, CHECK_NULL);
+
+  for (int i = 0; i < handler_count; i++) {
+    // exception handlers are stored as four integers: start bci, end bci, handler bci, catch class constant pool index
+    int base = i * 4;
+    Handle entry = instanceKlass::cast(HotSpotExceptionHandler::klass())->allocate_instance(CHECK_NULL);
+    HotSpotExceptionHandler::set_startBci(entry, handlers->int_at(base + 0));
+    HotSpotExceptionHandler::set_endBci(entry, handlers->int_at(base + 1));
+    HotSpotExceptionHandler::set_handlerBci(entry, handlers->int_at(base + 2));
+    int catch_class_index = handlers->int_at(base + 3);
+    HotSpotExceptionHandler::set_catchClassIndex(entry, catch_class_index);
+
+    if (catch_class_index == 0) {
+      HotSpotExceptionHandler::set_catchClass(entry, NULL);
+    } else {
+      constantPoolOop cp = instanceKlass::cast(method->method_holder())->constants();
+      KlassHandle loading_klass = method->method_holder();
+      Handle catch_class = GraalCompiler::get_RiType(cp, catch_class_index, loading_klass, CHECK_NULL);
+      if (catch_class->klass() == HotSpotTypeResolved::klass() && java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(catch_class)) == SystemDictionary::Throwable_klass()) {
+        HotSpotExceptionHandler::set_catchClass(entry, NULL);
+        HotSpotExceptionHandler::set_catchClassIndex(entry, 0);
+      } else {
+        HotSpotExceptionHandler::set_catchClass(entry, catch_class());
+      }
+    }
+    array->obj_at_put(i, entry());
+  }
+
+  return (jobjectArray) JNIHandles::make_local(array());
+}
+
+// public boolean RiMethod_hasBalancedMonitors(long vmId);
+JNIEXPORT jint JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1hasBalancedMonitors(JNIEnv *, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::RiMethod_hasBalancedMonitors");
+
+  VM_ENTRY_MARK;
+
+  // Analyze the method to see if monitors are used properly.
+  methodHandle method(THREAD, getMethodFromHotSpotMethod(hotspot_method));
+  assert(method->has_monitor_bytecodes(), "should have checked this");
+
+  // Check to see if a previous compilation computed the monitor-matching analysis.
+  if (method->guaranteed_monitor_matching()) {
+    return true;
+  }
+
+  {
+    EXCEPTION_MARK;
+    ResourceMark rm(THREAD);
+    GeneratePairingInfo gpi(method);
+    gpi.compute_map(CATCH);
+    if (!gpi.monitor_safe()) {
+      return false;
+    }
+    method->set_guaranteed_monitor_matching();
+  }
+  return true;
+}
+
+// public RiMethod getRiMethod(java.lang.reflect.Method reflectionMethod);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_getRiMethod(JNIEnv *, jobject, jobject reflection_method_handle) {
+  TRACE_graal_3("CompilerToVM::getRiMethod");
+  VM_ENTRY_MARK;
+  oop reflection_method = JNIHandles::resolve(reflection_method_handle);
+  oop reflection_holder = java_lang_reflect_Method::clazz(reflection_method);
+  int slot = java_lang_reflect_Method::slot(reflection_method);
+  klassOop holder = java_lang_Class::as_klassOop(reflection_holder);
+  methodOop method = instanceKlass::cast(holder)->method_with_idnum(slot);
+  Handle ret = GraalCompiler::createHotSpotMethodResolved(method, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, ret());
+}
+
+// public boolean RiMethod_uniqueConcreteMethod(long vmId);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1uniqueConcreteMethod(JNIEnv *, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::RiMethod_uniqueConcreteMethod");
+
+  VM_ENTRY_MARK;
+  methodHandle method = getMethodFromHotSpotMethod(hotspot_method);
+  KlassHandle holder = method->method_holder();
+  if (holder->is_interface()) {
+    // Cannot trust interfaces. Because of:
+    // interface I { void foo(); }
+    // class A { public void foo() {} }
+    // class B extends A implements I { }
+    // class C extends B { public void foo() { } }
+    // class D extends B { }
+    // Would lead to identify C.foo() as the unique concrete method for I.foo() without seeing A.foo().
+    return false;
+  }
+  methodHandle unique_concrete;
+  {
+    ResourceMark rm;
+    MutexLocker locker(Compile_lock);
+    unique_concrete = Dependencies::find_unique_concrete_method(holder(), method());
+  }
+  if (unique_concrete.is_null()) {
+    return NULL;
+  } else {
+    Handle method_resolved = GraalCompiler::createHotSpotMethodResolved(unique_concrete, CHECK_NULL);
+    return JNIHandles::make_local(THREAD, method_resolved());
+  }
+}
+
+// public native int RiMethod_invocationCount(long vmId);
+JNIEXPORT jint JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1invocationCount(JNIEnv *, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::RiMethod_invocationCount");
+  return getMethodFromHotSpotMethod(hotspot_method)->invocation_count();
+}
+
+// public native HotSpotMethodData RiMethod_methodData(HotSpotMethodResolved method);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1methodData(JNIEnv *, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::RiMethod_methodData");
+  VM_ENTRY_MARK;
+
+  methodDataHandle method_data = getMethodFromHotSpotMethod(hotspot_method)->method_data();
+  if(method_data.is_null()) {
+    return NULL;
+  } else {
+    Handle graalMethodData = GraalCompiler::createHotSpotMethodData(method_data, CHECK_NULL);
+    return JNIHandles::make_local(THREAD, graalMethodData());
+  }
+}
+
+// ------------------------------------------------------------------
+// Adjust a CounterData count to be commensurate with
+// interpreter_invocation_count.  If the MDO exists for
+// only 25% of the time the method exists, then the
+// counts in the MDO should be scaled by 4X, so that
+// they can be usefully and stably compared against the
+// invocation counts in methods.
+int scale_count(methodDataOop method_data, int count) {
+  if (count > 0) {
+    int counter_life;
+    int method_life = method_data->method()->interpreter_invocation_count();
+    int current_mileage = methodDataOopDesc::mileage_of(method_data->method());
+    int creation_mileage = method_data->creation_mileage();
+    counter_life = current_mileage - creation_mileage;
+
+    // counter_life due to backedge_counter could be > method_life
+    if (counter_life > method_life)
+      counter_life = method_life;
+    if (0 < counter_life && counter_life <= method_life) {
+      count = (int)((double)count * method_life / counter_life + 0.5);
+      count = (count > 0) ? count : 1;
+    }
+  }
+  return count;
+}
+
+// public native boolean RiMethod_hasCompiledCode(HotSpotMethodResolved method);
+JNIEXPORT jboolean JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1hasCompiledCode(JNIEnv *, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::RiMethod_hasCompiledCode");
+  return getMethodFromHotSpotMethod(hotspot_method)->has_compiled_code();
+}
+
+// public native int RiMethod_getCompiledCodeSize(HotSpotMethodResolved method);
+JNIEXPORT jint JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1getCompiledCodeSize(JNIEnv *env, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::RiMethod_getCompiledCodeSize");
+  nmethod* code = getMethodFromHotSpotMethod(hotspot_method)->code();
+  return code == NULL ? 0 : code->insts_size();
+}
+
+// public RiType RiSignature_lookupType(String returnType, HotSpotTypeResolved accessingClass);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiSignature_1lookupType(JNIEnv *env, jobject, jstring jname, jobject accessingClass, jboolean eagerResolve) {
+  TRACE_graal_3("CompilerToVM::RiSignature_lookupType");
+  VM_ENTRY_MARK;
+  ResourceMark rm;
+
+  Symbol* nameSymbol = VmIds::toSymbol(jname);
+  Handle name = JNIHandles::resolve(jname);
+
+  oop result;
+  if (nameSymbol == vmSymbols::int_signature()) {
+    result = VMToCompiler::createRiTypePrimitive((int) T_INT, THREAD);
+  } else if (nameSymbol == vmSymbols::long_signature()) {
+    result = VMToCompiler::createRiTypePrimitive((int) T_LONG, THREAD);
+  } else if (nameSymbol == vmSymbols::bool_signature()) {
+    result = VMToCompiler::createRiTypePrimitive((int) T_BOOLEAN, THREAD);
+  } else if (nameSymbol == vmSymbols::char_signature()) {
+    result = VMToCompiler::createRiTypePrimitive((int) T_CHAR, THREAD);
+  } else if (nameSymbol == vmSymbols::short_signature()) {
+    result = VMToCompiler::createRiTypePrimitive((int) T_SHORT, THREAD);
+  } else if (nameSymbol == vmSymbols::byte_signature()) {
+    result = VMToCompiler::createRiTypePrimitive((int) T_BYTE, THREAD);
+  } else if (nameSymbol == vmSymbols::double_signature()) {
+    result = VMToCompiler::createRiTypePrimitive((int) T_DOUBLE, THREAD);
+  } else if (nameSymbol == vmSymbols::float_signature()) {
+    result = VMToCompiler::createRiTypePrimitive((int) T_FLOAT, THREAD);
+  } else {
+    klassOop resolved_type = NULL;
+    // if the name isn't in the symbol table then the class isn't loaded anyway...
+    if (nameSymbol != NULL) {
+      Handle classloader;
+      Handle protectionDomain;
+      if (JNIHandles::resolve(accessingClass) != NULL) {
+        classloader = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(accessingClass))->klass_part()->class_loader();
+        protectionDomain = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(accessingClass))->klass_part()->protection_domain();
+      }
+      if (eagerResolve) {
+        resolved_type = SystemDictionary::resolve_or_null(nameSymbol, classloader, protectionDomain, THREAD);
+      } else {
+        if (FieldType::is_obj(nameSymbol)) {
+          ResourceMark rm(THREAD);
+          // Ignore wrapping L and ;.
+          TempNewSymbol tmp_name = SymbolTable::new_symbol(nameSymbol->as_C_string() + 1,
+                                         nameSymbol->utf8_length() - 2, CHECK_NULL);
+          resolved_type = SystemDictionary::find_instance_or_array_klass(tmp_name, classloader, protectionDomain, THREAD);
+        } else {
+          resolved_type = SystemDictionary::find_instance_or_array_klass(nameSymbol, classloader, protectionDomain, THREAD);
+        }
+      }
+      if (HAS_PENDING_EXCEPTION) {
+        CLEAR_PENDING_EXCEPTION;
+        resolved_type = NULL;
+      }
+    }
+    if (resolved_type != NULL) {
+      Handle type = GraalCompiler::createHotSpotTypeResolved(resolved_type, name, CHECK_NULL);
+      result = type();
+    } else {
+      Handle type = VMToCompiler::createRiTypeUnresolved(name, THREAD);
+      result = type();
+    }
+  }
+
+  return JNIHandles::make_local(THREAD, result);
+}
+
+// public Object RiConstantPool_lookupConstant(HotSpotTypeResolved type, int cpi);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiConstantPool_1lookupConstant(JNIEnv *env, jobject, jobject type, jint index) {
+  TRACE_graal_3("CompilerToVM::RiConstantPool_lookupConstant");
+  VM_ENTRY_MARK;
+
+  constantPoolOop cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type)))->constants();
+
+  oop result = NULL;
+  constantTag tag = cp->tag_at(index);
+  if (tag.is_int()) {
+    result = VMToCompiler::createCiConstant(CiKind::Int(), cp->int_at(index), CHECK_0);
+  } else if (tag.is_long()) {
+    result = VMToCompiler::createCiConstant(CiKind::Long(), cp->long_at(index), CHECK_0);
+  } else if (tag.is_float()) {
+    result = VMToCompiler::createCiConstantFloat(cp->float_at(index), CHECK_0);
+  } else if (tag.is_double()) {
+    result = VMToCompiler::createCiConstantDouble(cp->double_at(index), CHECK_0);
+  } else if (tag.is_string() || tag.is_unresolved_string()) {
+    oop string = NULL;
+    if (cp->is_pseudo_string_at(index)) {
+      string = cp->pseudo_string_at(index);
+    } else {
+      string = cp->string_at(index, THREAD);
+      if (HAS_PENDING_EXCEPTION) {
+        CLEAR_PENDING_EXCEPTION;
+        // TODO: Gracefully exit compilation.
+        fatal("out of memory during compilation!");
+        return NULL;
+      }
+    }
+    result = VMToCompiler::createCiConstantObject(string, CHECK_0);
+  } else if (tag.is_klass() || tag.is_unresolved_klass()) {
+    Handle type = GraalCompiler::get_RiType(cp, index, cp->pool_holder(), CHECK_NULL);
+    result = type();
+  } else if (tag.is_object()) {
+    oop obj = cp->object_at(index);
+    assert(obj->is_instance(), "must be an instance");
+    result = VMToCompiler::createCiConstantObject(obj, CHECK_NULL);
+  } else {
+    ShouldNotReachHere();
+  }
+
+  return JNIHandles::make_local(THREAD, result);
+}
+
+// public RiMethod RiConstantPool_lookupMethod(long vmId, int cpi, byte byteCode);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiConstantPool_1lookupMethod(JNIEnv *env, jobject, jobject type, jint index, jbyte byteCode) {
+  TRACE_graal_3("CompilerToVM::RiConstantPool_lookupMethod");
+  VM_ENTRY_MARK;
+  index = GraalCompiler::to_cp_index_u2(index);
+  constantPoolHandle cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type)))->constants();
+  instanceKlassHandle pool_holder(cp->pool_holder());
+
+  Bytecodes::Code bc = (Bytecodes::Code) (((int) byteCode) & 0xFF);
+  methodHandle method = GraalEnv::get_method_by_index(cp, index, bc, pool_holder);
+  if (!method.is_null()) {
+    Handle ret = GraalCompiler::createHotSpotMethodResolved(method, CHECK_NULL);
+    return JNIHandles::make_local(THREAD, ret());
+  } else {
+    // Get the method's name and signature.
+    Handle name = VmIds::toString<Handle>(cp->name_ref_at(index), CHECK_NULL);
+    Handle signature  = VmIds::toString<Handle>(cp->signature_ref_at(index), CHECK_NULL);
+    int holder_index = cp->klass_ref_index_at(index);
+    Handle type = GraalCompiler::get_RiType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
+    return JNIHandles::make_local(THREAD, VMToCompiler::createRiMethodUnresolved(name, signature, type, THREAD));
+  }
+}
+
+// public RiType RiConstantPool_lookupType(long vmId, int cpi);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiConstantPool_1lookupType(JNIEnv *env, jobject, jobject type, jint index) {
+  TRACE_graal_3("CompilerToVM::RiConstantPool_lookupType");
+  VM_ENTRY_MARK;
+
+  constantPoolOop cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type)))->constants();
+  Handle result = GraalCompiler::get_RiType(cp, index, cp->pool_holder(), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result());
+}
+
+// public void RiConstantPool_loadReferencedType(long vmId, int cpi);
+JNIEXPORT void JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiConstantPool_1loadReferencedType(JNIEnv *env, jobject, jobject type, jint index, jbyte op) {
+  TRACE_graal_3("CompilerToVM::RiConstantPool_loadReferencedType");
+  VM_ENTRY_MARK;
+  
+  constantPoolOop cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type)))->constants();
+  int byteCode = (op & 0xFF);
+  if (byteCode != Bytecodes::_checkcast && byteCode != Bytecodes::_instanceof && byteCode != Bytecodes::_new && byteCode != Bytecodes::_anewarray
+      && byteCode != Bytecodes::_multianewarray && byteCode != Bytecodes::_ldc && byteCode != Bytecodes::_ldc_w && byteCode != Bytecodes::_ldc2_w)
+  {
+    index = cp->remap_instruction_operand_from_cache(GraalCompiler::to_cp_index_u2(index));
+  }
+  constantTag tag = cp->tag_at(index);
+  if (tag.is_field_or_method()) {
+    index = cp->uncached_klass_ref_index_at(index);
+    tag = cp->tag_at(index);
+  }
+
+  if (tag.is_unresolved_klass() || tag.is_klass()) {
+    klassOop klass = cp->klass_at(index, CHECK);
+    if (klass->klass_part()->oop_is_instance()) {
+      instanceKlass::cast(klass)->initialize(CHECK);
+    }
+  }
+}
+
+// public RiField RiConstantPool_lookupField(long vmId, int cpi);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiConstantPool_1lookupField(JNIEnv *env, jobject, jobject constantPoolHolder, jint index, jbyte byteCode) {
+  TRACE_graal_3("CompilerToVM::RiConstantPool_lookupField");
+  VM_ENTRY_MARK;
+  ResourceMark rm;
+
+  index = GraalCompiler::to_cp_index_u2(index);
+  constantPoolHandle cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(constantPoolHolder)))->constants();
+
+  int nt_index = cp->name_and_type_ref_index_at(index);
+  int sig_index = cp->signature_ref_index_at(nt_index);
+  Symbol* signature = cp->symbol_at(sig_index);
+  int name_index = cp->name_ref_index_at(nt_index);
+  Symbol* name = cp->symbol_at(name_index);
+  int holder_index = cp->klass_ref_index_at(index);
+  Handle holder = GraalCompiler::get_RiType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
+  instanceKlassHandle holder_klass;
+  
+  Bytecodes::Code code = (Bytecodes::Code)(((int) byteCode) & 0xFF);
+  int offset = -1;
+  AccessFlags flags;
+  BasicType basic_type;
+  if (holder->klass() == SystemDictionary::HotSpotTypeResolved_klass()) {
+    FieldAccessInfo result;
+    LinkResolver::resolve_field(result, cp, index,
+                                Bytecodes::java_code(code),
+                                true, false, Thread::current());
+    if (HAS_PENDING_EXCEPTION) {
+      CLEAR_PENDING_EXCEPTION;
+    } else {
+      offset = result.field_offset();
+      flags = result.access_flags();
+      holder_klass = result.klass()->as_klassOop();
+      basic_type = result.field_type();
+      holder = GraalCompiler::get_RiType(holder_klass, CHECK_NULL);
+    }
+  }
+  
+  Handle type = GraalCompiler::get_RiTypeFromSignature(cp, sig_index, cp->pool_holder(), CHECK_NULL);
+  Handle field_handle = GraalCompiler::get_RiField(offset, flags.as_int(), name, holder, type, code, THREAD);
+
+  oop constant_object = NULL;
+    // Check to see if the field is constant.
+  if (!holder_klass.is_null() && holder_klass->is_initialized() && flags.is_final() && flags.is_static()) {
+    // This field just may be constant.  The only cases where it will
+    // not be constant are:
+    //
+    // 1. The field holds a non-perm-space oop.  The field is, strictly
+    //    speaking, constant but we cannot embed non-perm-space oops into
+    //    generated code.  For the time being we need to consider the
+    //    field to be not constant.
+    // 2. The field is a *special* static&final field whose value
+    //    may change.  The three examples are java.lang.System.in,
+    //    java.lang.System.out, and java.lang.System.err.
+
+    bool ok = true;
+    assert( SystemDictionary::System_klass() != NULL, "Check once per vm");
+    if( holder_klass->as_klassOop() == SystemDictionary::System_klass() ) {
+      // Check offsets for case 2: System.in, System.out, or System.err
+      if( offset == java_lang_System::in_offset_in_bytes()  ||
+          offset == java_lang_System::out_offset_in_bytes() ||
+          offset == java_lang_System::err_offset_in_bytes() ) {
+        ok = false;
+      }
+    }
+
+    if (ok) {
+      Handle mirror = holder_klass->java_mirror();
+      switch(basic_type) {
+        case T_OBJECT:
+        case T_ARRAY:
+          constant_object = VMToCompiler::createCiConstantObject(mirror->obj_field(offset), CHECK_0);
+          break;
+        case T_DOUBLE:
+          constant_object = VMToCompiler::createCiConstantDouble(mirror->double_field(offset), CHECK_0);
+          break;
+        case T_FLOAT:
+          constant_object = VMToCompiler::createCiConstantFloat(mirror->float_field(offset), CHECK_0);
+          break;
+        case T_LONG:
+          constant_object = VMToCompiler::createCiConstant(CiKind::Long(), mirror->long_field(offset), CHECK_0);
+          break;
+        case T_INT:
+          constant_object = VMToCompiler::createCiConstant(CiKind::Int(), mirror->int_field(offset), CHECK_0);
+          break;
+        case T_SHORT:
+          constant_object = VMToCompiler::createCiConstant(CiKind::Short(), mirror->short_field(offset), CHECK_0);
+          break;
+        case T_CHAR:
+          constant_object = VMToCompiler::createCiConstant(CiKind::Char(), mirror->char_field(offset), CHECK_0);
+          break;
+        case T_BYTE:
+          constant_object = VMToCompiler::createCiConstant(CiKind::Byte(), mirror->byte_field(offset), CHECK_0);
+          break;
+        case T_BOOLEAN:
+          constant_object = VMToCompiler::createCiConstant(CiKind::Boolean(), mirror->bool_field(offset), CHECK_0);
+          break;
+        default:
+          fatal("Unhandled constant");
+          break;
+      }
+    }
+  }
+  if (constant_object != NULL) {
+    HotSpotField::set_constant(field_handle, constant_object);
+  }
+  return JNIHandles::make_local(THREAD, field_handle());
+}
+
+// public RiMethod RiType_resolveMethodImpl(HotSpotTypeResolved klass, String name, String signature);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiType_3resolveMethodImpl(JNIEnv *, jobject, jobject resolved_type, jstring name, jstring signature) {
+  TRACE_graal_3("CompilerToVM::RiType_resolveMethodImpl");
+  VM_ENTRY_MARK;
+
+  assert(JNIHandles::resolve(resolved_type) != NULL, "");
+  klassOop klass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(resolved_type));
+  Symbol* name_symbol = VmIds::toSymbol(name);
+  Symbol* signature_symbol = VmIds::toSymbol(signature);
+  methodHandle method = klass->klass_part()->lookup_method(name_symbol, signature_symbol);
+  if (method == NULL) {
+    if (TraceGraal >= 3) {
+      ResourceMark rm;
+      tty->print_cr("Could not resolve method %s %s on klass %s", name_symbol->as_C_string(), signature_symbol->as_C_string(), klass->klass_part()->name()->as_C_string());
+    }
+    return NULL;
+  }
+  Handle ret = GraalCompiler::createHotSpotMethodResolved(method, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, ret());
+}
+
+// public boolean RiType_isSubtypeOf(HotSpotTypeResolved klass, RiType other);
+JNIEXPORT jboolean JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiType_2isSubtypeOf(JNIEnv *, jobject, jobject klass, jobject jother) {
+  TRACE_graal_3("CompilerToVM::RiType_isSubtypeOf");
+  VM_ENTRY_MARK;
+  
+  oop other = JNIHandles::resolve(jother);
+  assert(other->is_a(HotSpotTypeResolved::klass()), "resolved hotspot type expected");
+  assert(JNIHandles::resolve(klass) != NULL, "");
+  klassOop thisKlass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass));
+  klassOop otherKlass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(other));
+  if (thisKlass->klass_part()->oop_is_instance_slow()) {
+    return instanceKlass::cast(thisKlass)->is_subtype_of(otherKlass);
+  } else if (thisKlass->klass_part()->oop_is_array()) {
+    return arrayKlass::cast(thisKlass)->is_subtype_of(otherKlass);
+  } else {
+    fatal("unexpected class type");
+    return false;
+  }
+}
+
+// public RiType RiType_leastCommonAncestor(HotSpotTypeResolved thisType, HotSpotTypeResolved otherType);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiType_2leastCommonAncestor(JNIEnv *, jobject, jobject this_type, jobject other_type) {
+  TRACE_graal_3("CompilerToVM::RiType_leastCommonAncestor");
+  VM_ENTRY_MARK;
+
+  Klass* this_klass  = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(this_type))->klass_part();
+  Klass* other_klass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(other_type))->klass_part();
+  Klass* lca         = this_klass->LCA(other_klass);
+
+  return JNIHandles::make_local(GraalCompiler::get_RiType(lca, THREAD)());
+}
+
+// public RiType RiType_componentType(HotSpotResolvedType klass);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiType_1componentType(JNIEnv *, jobject, jobject klass) {
+  TRACE_graal_3("CompilerToVM::RiType_componentType");
+  VM_ENTRY_MARK;
+  KlassHandle array_klass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass));
+  if(array_klass->oop_is_typeArray()) {
+    BasicType t = typeArrayKlass::cast(array_klass())->element_type();
+    oop primitive_type = VMToCompiler::createRiTypePrimitive((int) t, CHECK_NULL);
+    return JNIHandles::make_local(primitive_type);
+  }
+  assert(array_klass->oop_is_objArray(), "just checking");
+  klassOop element_type = objArrayKlass::cast(array_klass())->element_klass();
+  assert(JNIHandles::resolve(klass) != NULL, "");
+  return JNIHandles::make_local(GraalCompiler::get_RiType(element_type, THREAD)());
+}
+
+// public RiType RiType_superType(HotSpotResolvedType klass);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiType_1superType(JNIEnv *, jobject, jobject klass) {
+  TRACE_graal_3("CompilerToVM::RiType_superType");
+  VM_ENTRY_MARK;
+  KlassHandle klass_handle(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass)));
+  klassOop k;
+
+  if (klass_handle->oop_is_array()) {
+    k = SystemDictionary::Object_klass();
+  } else {
+    guarantee(klass_handle->oop_is_instance(), "must be instance klass");  
+    k = klass_handle->super();
+  }
+
+  if (k != NULL) {
+    return JNIHandles::make_local(GraalCompiler::get_RiType(k, THREAD)());
+  } else {
+    return NULL;
+  }
+}
+
+// public RiType RiType_uniqueConcreteSubtype(HotSpotResolvedType klass);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiType_1uniqueConcreteSubtype(JNIEnv *, jobject, jobject klass) {
+  TRACE_graal_3("CompilerToVM::RiType_uniqueConcreteSubtype");
+  VM_ENTRY_MARK;
+  KlassHandle klass_handle(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass)));
+  Klass *up_cast = klass_handle->up_cast_abstract();
+  if (up_cast->is_leaf_class()) {
+    return JNIHandles::make_local(GraalCompiler::get_RiType(up_cast, THREAD)());
+  }
+  return NULL;
+}
+
+// public bool RiType_isInitialized(HotSpotResolvedType klass);
+JNIEXPORT jboolean JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiType_1isInitialized(JNIEnv *, jobject, jobject hotspot_klass) {
+  TRACE_graal_3("CompilerToVM::RiType_isInitialized");
+  klassOop klass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(hotspot_klass));
+  assert(klass != NULL, "method must not be called for primitive types");
+  return instanceKlass::cast(klass)->is_initialized();
+}
+
+// public RiType RiType_arrayOf(HotSpotTypeResolved klass);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiType_1arrayOf(JNIEnv *, jobject, jobject klass) {
+  TRACE_graal_3("CompilerToVM::RiType_arrayOf");
+  VM_ENTRY_MARK;
+
+  KlassHandle klass_handle(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass)));
+  KlassHandle arr = klass_handle->array_klass(THREAD);
+  Handle name = VmIds::toString<Handle>(arr->name(), CHECK_NULL);
+  assert(arr->oop_is_array(), "");
+  return JNIHandles::make_local(THREAD, GraalCompiler::createHotSpotTypeResolved(arr, name, THREAD)());
+}
+
+// public RiResolvedField[] RiType_fields(HotSpotTypeResolved klass);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiType_1fields(JNIEnv *, jobject, jobject klass) {
+  TRACE_graal_3("CompilerToVM::RiType_fields");
+  VM_ENTRY_MARK;
+  ResourceMark rm;
+
+  instanceKlassHandle k = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass));
+  class MyFieldClosure : public FieldClosure {
+   public:
+    instanceKlassHandle _holder;
+    Handle _resolved_type_holder;
+    GrowableArray<Handle> _field_array;
+
+    MyFieldClosure(instanceKlassHandle& holder, Handle resolved_type_holder) : _holder(holder), _resolved_type_holder(resolved_type_holder) { }
+    
+    virtual void do_field(fieldDescriptor* fd) {
+      if (!Thread::current()->has_pending_exception()) {
+        if (fd->field_holder() == _holder()) {
+          Handle type = GraalCompiler::get_RiTypeFromSignature(fd->constants(), fd->signature_index(), fd->field_holder(), Thread::current());
+          Handle field = VMToCompiler::createRiField(_resolved_type_holder, VmIds::toString<Handle>(fd->name(), Thread::current()), type, fd->offset(), fd->access_flags().as_int(), Thread::current());
+          _field_array.append(field());
+        }
+      }
+    }
+  };
+  MyFieldClosure closure(k, JNIHandles::resolve(klass));
+  k->do_nonstatic_fields(&closure);
+  objArrayHandle field_array = oopFactory::new_objArray(SystemDictionary::RiResolvedField_klass(), closure._field_array.length(), CHECK_NULL);
+  for (int i=0; i<closure._field_array.length(); ++i) {
+    field_array->obj_at_put(i, closure._field_array.at(i)());
+  }
+  return JNIHandles::make_local(field_array());
+}
+
+// public RiType getPrimitiveArrayType(CiKind kind);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_getPrimitiveArrayType(JNIEnv *env, jobject, jobject kind) {
+  TRACE_graal_3("CompilerToVM::getPrimitiveArrayType");
+  VM_ENTRY_MARK;
+  BasicType type = GraalCompiler::kindToBasicType(CiKind::typeChar(kind));
+  assert(type != T_OBJECT, "primitive type expecteds");
+  Handle result = GraalCompiler::get_RiType(Universe::typeArrayKlassObj(type), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result());
+}
+
+// public long getMaxCallTargetOffset(CiRuntimeCall rtcall);
+JNIEXPORT jlong JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_getMaxCallTargetOffset(JNIEnv *env, jobject, jobject rtcall) {
+  TRACE_graal_3("CompilerToVM::getMaxCallTargetOffset");
+  VM_ENTRY_MARK;
+  oop call = JNIHandles::resolve(rtcall);
+  address target_addr = CodeInstaller::runtime_call_target_address(call);
+  if (target_addr != 0x0) {
+    int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int));
+    int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int));
+    return MAX2(ABS(off_low), ABS(off_high));
+  }
+  return -1;
+}
+
+// public RiType getType(Class<?> javaClass);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_getType(JNIEnv *env, jobject, jobject javaClass) {
+  TRACE_graal_3("CompilerToVM::getType");
+  VM_ENTRY_MARK;
+  oop javaClassOop = JNIHandles::resolve(javaClass);
+  if (javaClassOop == NULL) {
+    fatal("argument to CompilerToVM.getType must not be NULL");
+    return NULL;
+  } else if (java_lang_Class::is_primitive(javaClassOop)) {
+    BasicType basicType = java_lang_Class::primitive_type(javaClassOop);
+    return JNIHandles::make_local(THREAD, VMToCompiler::createRiTypePrimitive((int) basicType, THREAD));
+  } else {
+    KlassHandle klass = java_lang_Class::as_klassOop(javaClassOop);
+    Handle name = java_lang_String::create_from_symbol(klass->name(), CHECK_NULL);
+
+    Handle type = GraalCompiler::createHotSpotTypeResolved(klass, name, CHECK_NULL);
+    return JNIHandles::make_local(THREAD, type());
+  }
+}
+
+
+// helpers used to set fields in the HotSpotVMConfig object
+jfieldID getFieldID(JNIEnv* env, jobject obj, const char* name, const char* sig) {
+  jfieldID id = env->GetFieldID(env->GetObjectClass(obj), name, sig);
+  if (id == NULL) {
+    fatal(err_msg("field not found: %s (%s)", name, sig));
+  }
+  return id;
+}
+
+void set_boolean(JNIEnv* env, jobject obj, const char* name, bool value) { env->SetBooleanField(obj, getFieldID(env, obj, name, "Z"), value); }
+void set_int(JNIEnv* env, jobject obj, const char* name, int value) { env->SetIntField(obj, getFieldID(env, obj, name, "I"), value); }
+void set_long(JNIEnv* env, jobject obj, const char* name, jlong value) { env->SetLongField(obj, getFieldID(env, obj, name, "J"), value); }
+void set_object(JNIEnv* env, jobject obj, const char* name, jobject value) { env->SetObjectField(obj, getFieldID(env, obj, name, "Ljava/lang/Object;"), value); }
+void set_int_array(JNIEnv* env, jobject obj, const char* name, jarray value) { env->SetObjectField(obj, getFieldID(env, obj, name, "[I"), value); }
+
+jboolean get_boolean(JNIEnv* env, jobject obj, const char* name) { return env->GetBooleanField(obj, getFieldID(env, obj, name, "Z")); }
+jint get_int(JNIEnv* env, jobject obj, const char* name) { return env->GetIntField(obj, getFieldID(env, obj, name, "I")); }
+jlong get_long(JNIEnv* env, jobject obj, const char* name) { return env->GetLongField(obj, getFieldID(env, obj, name, "J")); }
+jobject get_object(JNIEnv* env, jobject obj, const char* name) { return env->GetObjectField(obj, getFieldID(env, obj, name, "Ljava/lang/Object;")); }
+jobject get_object(JNIEnv* env, jobject obj, const char* name, const char* sig) { return env->GetObjectField(obj, getFieldID(env, obj, name, sig)); }
+
+
+BasicType basicTypes[] = { T_BOOLEAN, T_BYTE, T_SHORT, T_CHAR, T_INT, T_FLOAT, T_LONG, T_DOUBLE, T_OBJECT };
+int basicTypeCount = sizeof(basicTypes) / sizeof(BasicType);
+
+// public HotSpotVMConfig getConfiguration();
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_getConfiguration(JNIEnv *env, jobject) {
+  jclass klass = env->FindClass("com/oracle/max/graal/hotspot/HotSpotVMConfig");
+  assert(klass != NULL, "HotSpot vm config class not found");
+  jobject config = env->AllocObject(klass);
+#ifdef _WIN64
+  set_boolean(env, config, "windowsOs", true);
+#else
+  set_boolean(env, config, "windowsOs", false);
+#endif
+  set_boolean(env, config, "verifyPointers", VerifyOops);
+  set_boolean(env, config, "useFastLocking", UseFastLocking);
+  set_boolean(env, config, "useFastNewObjectArray", UseFastNewObjectArray);
+  set_boolean(env, config, "useFastNewTypeArray", UseFastNewTypeArray);
+  set_int(env, config, "codeEntryAlignment", CodeEntryAlignment);
+  set_int(env, config, "vmPageSize", os::vm_page_size());
+  set_int(env, config, "stackShadowPages", StackShadowPages);
+  set_int(env, config, "hubOffset", oopDesc::klass_offset_in_bytes());
+  set_int(env, config, "arrayLengthOffset", arrayOopDesc::length_offset_in_bytes());
+  set_int(env, config, "klassStateOffset", instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc));
+  set_int(env, config, "klassStateFullyInitialized", (int)instanceKlass::fully_initialized);
+  set_int(env, config, "threadTlabTopOffset", in_bytes(JavaThread::tlab_top_offset()));
+  set_int(env, config, "threadTlabEndOffset", in_bytes(JavaThread::tlab_end_offset()));
+  set_int(env, config, "threadObjectOffset", in_bytes(JavaThread::threadObj_offset()));
+  set_int(env, config, "instanceHeaderPrototypeOffset", Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes());
+  set_int(env, config, "threadExceptionOopOffset", in_bytes(JavaThread::exception_oop_offset()));
+  set_int(env, config, "threadExceptionPcOffset", in_bytes(JavaThread::exception_pc_offset()));
+  set_int(env, config, "threadMultiNewArrayStorage", in_bytes(JavaThread::graal_multinewarray_storage_offset()));
+  set_int(env, config, "classMirrorOffset", klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes());
+  
+  set_int(env, config, "methodDataOopDataOffset", in_bytes(methodDataOopDesc::data_offset()));
+  set_int(env, config, "dataLayoutHeaderSize", DataLayout::header_size_in_bytes());
+  set_int(env, config, "dataLayoutTagOffset", in_bytes(DataLayout::tag_offset()));
+  set_int(env, config, "dataLayoutFlagsOffset", in_bytes(DataLayout::flags_offset()));
+  set_int(env, config, "dataLayoutBCIOffset", in_bytes(DataLayout::bci_offset()));
+  set_int(env, config, "dataLayoutCellsOffset", in_bytes(DataLayout::cell_offset(0)));
+  set_int(env, config, "dataLayoutCellSize", DataLayout::cell_size);
+  set_int(env, config, "bciProfileWidth", BciProfileWidth);
+  set_int(env, config, "typeProfileWidth", TypeProfileWidth);
+
+  set_long(env, config, "debugStub", VmIds::addStub((address)warning));
+  set_long(env, config, "instanceofStub", VmIds::addStub(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
+  set_long(env, config, "verifyPointerStub", VmIds::addStub(Runtime1::entry_for(Runtime1::graal_verify_pointer_id)));
+  set_long(env, config, "newInstanceStub", VmIds::addStub(Runtime1::entry_for(Runtime1::fast_new_instance_init_check_id)));
+  set_long(env, config, "unresolvedNewInstanceStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_instance_id)));
+  set_long(env, config, "newTypeArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_type_array_id)));
+  set_long(env, config, "newObjectArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_object_array_id)));
+  set_long(env, config, "newMultiArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_multi_array_id)));
+  set_long(env, config, "loadKlassStub", VmIds::addStub(Runtime1::entry_for(Runtime1::load_klass_patching_id)));
+  set_long(env, config, "accessFieldStub", VmIds::addStub(Runtime1::entry_for(Runtime1::access_field_patching_id)));
+  set_long(env, config, "resolveStaticCallStub", VmIds::addStub(SharedRuntime::get_resolve_static_call_stub()));
+  set_long(env, config, "inlineCacheMissStub", VmIds::addStub(SharedRuntime::get_ic_miss_stub()));
+  set_long(env, config, "unwindExceptionStub", VmIds::addStub(Runtime1::entry_for(Runtime1::graal_unwind_exception_call_id)));
+  set_long(env, config, "handleExceptionStub", VmIds::addStub(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id)));
+  set_long(env, config, "handleDeoptStub", VmIds::addStub(SharedRuntime::deopt_blob()->unpack()));
+  set_long(env, config, "monitorEnterStub", VmIds::addStub(Runtime1::entry_for(Runtime1::monitorenter_id)));
+  set_long(env, config, "monitorExitStub", VmIds::addStub(Runtime1::entry_for(Runtime1::monitorexit_id)));
+  set_long(env, config, "fastMonitorEnterStub", VmIds::addStub(Runtime1::entry_for(Runtime1::graal_monitorenter_id)));
+  set_long(env, config, "fastMonitorExitStub", VmIds::addStub(Runtime1::entry_for(Runtime1::graal_monitorexit_id)));
+  set_long(env, config, "safepointPollingAddress", (jlong)(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())));
+  set_int(env, config, "runtimeCallStackSize", (jint)frame::arg_reg_save_area_bytes);
+  set_int(env, config, "klassModifierFlagsOffset", Klass::modifier_flags_offset_in_bytes() + sizeof(oopDesc));
+  set_int(env, config, "graalMirrorKlassOffset", klassOopDesc::klass_part_offset_in_bytes() + Klass::graal_mirror_offset_in_bytes());
+  set_int(env, config, "klassOopOffset", java_lang_Class::klass_offset_in_bytes());
+
+  set_boolean(env, config, "isPollingPageFar", Assembler::is_polling_page_far());
+
+  set_int(env, config, "nmethodEntryOffset", nmethod::verified_entry_point_offset());
+
+  BarrierSet* bs = Universe::heap()->barrier_set();
+  switch (bs->kind()) {
+    case BarrierSet::CardTableModRef:
+    case BarrierSet::CardTableExtension: {
+      jlong base = (jlong)((CardTableModRefBS*)bs)->byte_map_base;
+      assert(base != 0, "unexpected byte_map_base");
+      set_long(env, config, "cardtableStartAddress", base);
+      set_int(env, config, "cardtableShift", CardTableModRefBS::card_shift);
+      break;
+    }
+    case BarrierSet::ModRef:
+    case BarrierSet::Other:
+      set_long(env, config, "cardtableStartAddress", 0);
+      set_int(env, config, "cardtableShift", 0);
+      // No post barriers
+      break;
+#ifndef SERIALGC
+    case BarrierSet::G1SATBCT:
+    case BarrierSet::G1SATBCTLogging:
+#endif // SERIALGC
+    default:
+      ShouldNotReachHere();
+      break;
+    }
+
+  jintArray arrayOffsets = env->NewIntArray(basicTypeCount);
+  for (int i=0; i<basicTypeCount; i++) {
+    jint offset = arrayOopDesc::base_offset_in_bytes(basicTypes[i]);
+    env->SetIntArrayRegion(arrayOffsets, i, 1, &offset);
+  }
+  set_int_array(env, config, "arrayOffsets", arrayOffsets);
+  set_int(env, config, "arrayClassElementOffset", objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc));
+  return config;
+}
+
+// public HotSpotCompiledMethod installMethod(HotSpotTargetMethod targetMethod, boolean installCode);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_installMethod(JNIEnv *jniEnv, jobject, jobject targetMethod, jboolean install_code) {
+  VM_ENTRY_MARK;
+  ResourceMark rm;
+  HandleMark hm;
+  Handle targetMethodHandle = JNIHandles::resolve(targetMethod);
+  nmethod* nm = NULL;
+  Arena arena;
+  ciEnv env(&arena);
+  CodeInstaller installer(targetMethodHandle, nm, install_code != 0);
+
+  // if install_code is true then we installed the code into the given method, no need to return an RiCompiledMethod
+  if (!install_code && nm != NULL) {
+    instanceKlass::cast(HotSpotCompiledMethod::klass())->initialize(CHECK_NULL);
+    Handle obj = instanceKlass::cast(HotSpotCompiledMethod::klass())->allocate_permanent_instance(CHECK_NULL);
+    assert(obj() != NULL, "must succeed in allocating instance");
+    HotSpotCompiledMethod::set_nmethod(obj, (jlong) nm);
+    HotSpotCompiledMethod::set_method(obj, HotSpotTargetMethod::method(targetMethod));
+    nm->set_graal_compiled_method(obj());
+    return JNIHandles::make_local(obj());
+  } else {
+    return NULL;
+  }
+}
+
+// public long installStub(HotSpotTargetMethod targetMethod, String name);
+JNIEXPORT jlong JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_installStub(JNIEnv *jniEnv, jobject, jobject targetMethod) {
+  VM_ENTRY_MARK;
+  ResourceMark rm;
+  HandleMark hm;
+  Handle targetMethodHandle = JNIHandles::resolve(targetMethod);
+  jlong id;
+  Arena arena;
+  ciEnv env(&arena);
+  CodeInstaller installer(targetMethodHandle, id);
+  return id;
+}
+
+// public String disassembleNative(byte[] code, long address);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_disassembleNative(JNIEnv *jniEnv, jobject, jbyteArray code, jlong start_address) {
+  TRACE_graal_3("CompilerToVM::disassembleNative");
+  VM_ENTRY_MARK;
+  ResourceMark rm;
+  HandleMark hm;
+
+  stringStream(st);
+  arrayOop code_oop = (arrayOop) JNIHandles::resolve(code);
+  int len = code_oop->length();
+  address begin = (address) code_oop->base(T_BYTE);
+  address end = begin + len;
+  Disassembler::decode(begin, end, &st);
+
+  Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL);
+  return JNIHandles::make_local(result());
+}
+
+// public String disassembleJava(HotSpotMethodResolved method);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_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());
+}
+
+
+#define CC (char*)  /*cast a literal from (const char*)*/
+#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_##f))
+
+#define PROXY           "J"
+#define TYPE            "Lcom/oracle/max/cri/ri/RiType;"
+#define RESOLVED_TYPE   "Lcom/oracle/max/graal/hotspot/ri/HotSpotTypeResolved;"
+#define METHOD          "Lcom/oracle/max/cri/ri/RiMethod;"
+#define RESOLVED_METHOD "Lcom/oracle/max/graal/hotspot/ri/HotSpotMethodResolved;"
+#define REFLECT_METHOD  "Ljava/lang/reflect/Method;"
+#define SIGNATURE       "Lcom/oracle/max/cri/ri/RiSignature;"
+#define FIELD           "Lcom/oracle/max/cri/ri/RiField;"
+#define RESOLVED_FIELD  "Lcom/oracle/max/cri/ri/RiResolvedField;"
+#define CONSTANT_POOL   "Lcom/oracle/max/cri/ri/RiConstantPool;"
+#define EXCEPTION_HANDLERS "[Lcom/oracle/max/cri/ri/RiExceptionHandler;"
+#define TARGET_METHOD   "Lcom/oracle/max/graal/hotspot/HotSpotTargetMethod;"
+#define CONFIG          "Lcom/oracle/max/graal/hotspot/HotSpotVMConfig;"
+#define HS_METHOD       "Lcom/oracle/max/graal/hotspot/ri/HotSpotMethod;"
+#define HS_COMP_METHOD  "Lcom/oracle/max/graal/hotspot/ri/HotSpotCompiledMethod;"
+#define METHOD_DATA     "Lcom/oracle/max/graal/hotspot/ri/HotSpotMethodData;"
+#define CI_CONSTANT     "Lcom/oracle/max/cri/ci/CiConstant;"
+#define CI_KIND         "Lcom/oracle/max/cri/ci/CiKind;"
+#define CI_RUNTIME_CALL "Lcom/oracle/max/cri/ci/CiRuntimeCall;"
+#define STRING          "Ljava/lang/String;"
+#define OBJECT          "Ljava/lang/Object;"
+#define CLASS           "Ljava/lang/Class;"
+
+JNINativeMethod CompilerToVM_methods[] = {
+  {CC"RiMethod_code",                     CC"("RESOLVED_METHOD")[B",                            FN_PTR(RiMethod_1code)},
+  {CC"RiMethod_signature",                CC"("RESOLVED_METHOD")"STRING,                        FN_PTR(RiMethod_1signature)},
+  {CC"RiMethod_exceptionHandlers",        CC"("RESOLVED_METHOD")"EXCEPTION_HANDLERS,            FN_PTR(RiMethod_1exceptionHandlers)},
+  {CC"RiMethod_hasBalancedMonitors",      CC"("RESOLVED_METHOD")Z",                             FN_PTR(RiMethod_1hasBalancedMonitors)},
+  {CC"RiMethod_uniqueConcreteMethod",     CC"("RESOLVED_METHOD")"METHOD,                        FN_PTR(RiMethod_1uniqueConcreteMethod)},
+  {CC"getRiMethod",                       CC"("REFLECT_METHOD")"METHOD,                         FN_PTR(getRiMethod)},
+  {CC"RiMethod_methodData",               CC"("RESOLVED_METHOD")"METHOD_DATA,                   FN_PTR(RiMethod_1methodData)},
+  {CC"RiMethod_invocationCount",          CC"("RESOLVED_METHOD")I",                             FN_PTR(RiMethod_1invocationCount)},
+  {CC"RiMethod_hasCompiledCode",          CC"("RESOLVED_METHOD")Z",                             FN_PTR(RiMethod_1hasCompiledCode)},
+  {CC"RiMethod_getCompiledCodeSize",      CC"("RESOLVED_METHOD")I",                             FN_PTR(RiMethod_1getCompiledCodeSize)},
+  {CC"RiSignature_lookupType",            CC"("STRING RESOLVED_TYPE"Z)"TYPE,                    FN_PTR(RiSignature_1lookupType)},
+  {CC"RiConstantPool_lookupConstant",     CC"("RESOLVED_TYPE"I)"OBJECT,                         FN_PTR(RiConstantPool_1lookupConstant)},
+  {CC"RiConstantPool_lookupMethod",       CC"("RESOLVED_TYPE"IB)"METHOD,                        FN_PTR(RiConstantPool_1lookupMethod)},
+  {CC"RiConstantPool_lookupType",         CC"("RESOLVED_TYPE"I)"TYPE,                           FN_PTR(RiConstantPool_1lookupType)},
+  {CC"RiConstantPool_loadReferencedType", CC"("RESOLVED_TYPE"IB)V",                             FN_PTR(RiConstantPool_1loadReferencedType)},
+  {CC"RiConstantPool_lookupField",        CC"("RESOLVED_TYPE"IB)"FIELD,                         FN_PTR(RiConstantPool_1lookupField)},
+  {CC"RiType_resolveMethodImpl",          CC"("RESOLVED_TYPE STRING STRING")"METHOD,            FN_PTR(RiType_3resolveMethodImpl)},
+  {CC"RiType_isSubtypeOf",                CC"("RESOLVED_TYPE TYPE")Z",                          FN_PTR(RiType_2isSubtypeOf)},
+  {CC"RiType_leastCommonAncestor",        CC"("RESOLVED_TYPE RESOLVED_TYPE")"TYPE,              FN_PTR(RiType_2leastCommonAncestor)},
+  {CC"RiType_componentType",              CC"("RESOLVED_TYPE")"TYPE,                            FN_PTR(RiType_1componentType)},
+  {CC"RiType_uniqueConcreteSubtype",      CC"("RESOLVED_TYPE")"TYPE,                            FN_PTR(RiType_1uniqueConcreteSubtype)},
+  {CC"RiType_superType",                  CC"("RESOLVED_TYPE")"TYPE,                            FN_PTR(RiType_1superType)},
+  {CC"RiType_arrayOf",                    CC"("RESOLVED_TYPE")"TYPE,                            FN_PTR(RiType_1arrayOf)},
+  {CC"RiType_fields",                     CC"("RESOLVED_TYPE")["RESOLVED_FIELD,                 FN_PTR(RiType_1fields)},
+  {CC"RiType_isInitialized",              CC"("RESOLVED_TYPE")Z",                               FN_PTR(RiType_1isInitialized)},
+  {CC"getPrimitiveArrayType",             CC"("CI_KIND")"TYPE,                                  FN_PTR(getPrimitiveArrayType)},
+  {CC"getMaxCallTargetOffset",            CC"("CI_RUNTIME_CALL")J",                             FN_PTR(getMaxCallTargetOffset)},
+  {CC"getType",                           CC"("CLASS")"TYPE,                                    FN_PTR(getType)},
+  {CC"getConfiguration",                  CC"()"CONFIG,                                         FN_PTR(getConfiguration)},
+  {CC"installMethod",                     CC"("TARGET_METHOD"Z)"HS_COMP_METHOD,                 FN_PTR(installMethod)},
+  {CC"installStub",                       CC"("TARGET_METHOD")"PROXY,                           FN_PTR(installStub)},
+  {CC"disassembleNative",                 CC"([BJ)"STRING,                                      FN_PTR(disassembleNative)},
+  {CC"disassembleJava",                   CC"("RESOLVED_METHOD")"STRING,                        FN_PTR(disassembleJava)},
+};
+
+int CompilerToVM_methods_count() {
+  return sizeof(CompilerToVM_methods) / sizeof(JNINativeMethod);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/graal/graalCompilerToVM.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+#include "prims/jni.h"
+
+extern JNINativeMethod CompilerToVM_methods[];
+int CompilerToVM_methods_count();
+
+methodOop getMethodFromHotSpotMethod(oop hotspotMethod);
+
+// nothing here - no need to define the jni method implementations in a header file
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/graal/graalEnv.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,567 @@
+/*
+ * Copyright (c) 1999, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "graal/graalEnv.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "classfile/vmSymbols.hpp"
+#include "code/scopeDesc.hpp"
+#include "runtime/sweeper.hpp"
+#include "compiler/compileBroker.hpp"
+#include "compiler/compileLog.hpp"
+#include "compiler/compilerOracle.hpp"
+#include "interpreter/linkResolver.hpp"
+#include "memory/allocation.inline.hpp"
+#include "memory/oopFactory.hpp"
+#include "memory/universe.inline.hpp"
+#include "oops/methodDataOop.hpp"
+#include "oops/objArrayKlass.hpp"
+#include "prims/jvmtiExport.hpp"
+#include "prims/methodHandleWalk.hpp"
+#include "runtime/init.hpp"
+#include "runtime/reflection.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "utilities/dtrace.hpp"
+#include "c1/c1_Runtime1.hpp"
+
+// ------------------------------------------------------------------
+// ciEnv::check_klass_accessiblity
+//
+// Note: the logic of this method should mirror the logic of
+// constantPoolOopDesc::verify_constant_pool_resolve.
+bool GraalEnv::check_klass_accessibility(KlassHandle accessing_klass, KlassHandle resolved_klass) {
+  if (accessing_klass->oop_is_objArray()) {
+    accessing_klass = objArrayKlass::cast(accessing_klass())->bottom_klass();
+  }
+  if (!accessing_klass->oop_is_instance()) {
+    return true;
+  }
+
+  if (resolved_klass->oop_is_objArray()) {
+    // Find the element klass, if this is an array.
+    resolved_klass = objArrayKlass::cast(resolved_klass())->bottom_klass();
+  }
+  if (resolved_klass->oop_is_instance()) {
+    return Reflection::verify_class_access(accessing_klass(), resolved_klass(), true);
+  }
+  return true;
+}
+
+// ------------------------------------------------------------------
+// ciEnv::get_klass_by_name_impl
+KlassHandle GraalEnv::get_klass_by_name_impl(KlassHandle& accessing_klass,
+                                          constantPoolHandle& cpool,
+                                          Symbol* sym,
+                                          bool require_local) {
+  EXCEPTION_CONTEXT;
+
+  // Now we need to check the SystemDictionary
+  if (sym->byte_at(0) == 'L' &&
+    sym->byte_at(sym->utf8_length()-1) == ';') {
+    // This is a name from a signature.  Strip off the trimmings.
+    // Call recursive to keep scope of strippedsym.
+    TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1,
+                    sym->utf8_length()-2,
+                    CHECK_(KlassHandle()));
+    return get_klass_by_name_impl(accessing_klass, cpool, strippedsym, require_local);
+  }
+
+  Handle loader(THREAD, (oop)NULL);
+  Handle domain(THREAD, (oop)NULL);
+  if (!accessing_klass.is_null()) {
+    loader = Handle(THREAD, accessing_klass->class_loader());
+    domain = Handle(THREAD, accessing_klass->protection_domain());
+  }
+
+  KlassHandle found_klass;
+  {
+    ttyUnlocker ttyul;  // release tty lock to avoid ordering problems
+    MutexLocker ml(Compile_lock);
+    klassOop kls;
+    if (!require_local) {
+      kls = SystemDictionary::find_constrained_instance_or_array_klass(sym, loader, CHECK_(KlassHandle()));
+    } else {
+      kls = SystemDictionary::find_instance_or_array_klass(sym, loader, domain, CHECK_(KlassHandle()));
+    }
+    found_klass = KlassHandle(THREAD, kls);
+  }
+
+  // If we fail to find an array klass, look again for its element type.
+  // The element type may be available either locally or via constraints.
+  // In either case, if we can find the element type in the system dictionary,
+  // we must build an array type around it.  The CI requires array klasses
+  // to be loaded if their element klasses are loaded, except when memory
+  // is exhausted.
+  if (sym->byte_at(0) == '[' &&
+      (sym->byte_at(1) == '[' || sym->byte_at(1) == 'L')) {
+    // We have an unloaded array.
+    // Build it on the fly if the element class exists.
+    TempNewSymbol elem_sym = SymbolTable::new_symbol(sym->as_utf8()+1,
+                                                 sym->utf8_length()-1,
+                                                 CHECK_(KlassHandle()));
+
+    // Get element ciKlass recursively.
+    KlassHandle elem_klass =
+      get_klass_by_name_impl(accessing_klass,
+                             cpool,
+                             elem_sym,
+                             require_local);
+    if (!elem_klass.is_null()) {
+      // Now make an array for it
+      return elem_klass->array_klass(CHECK_(KlassHandle()));
+    }
+  }
+
+  if (found_klass.is_null() && !cpool.is_null() && cpool->has_preresolution()) {
+    // Look inside the constant pool for pre-resolved class entries.
+    for (int i = cpool->length() - 1; i >= 1; i--) {
+      if (cpool->tag_at(i).is_klass()) {
+        klassOop kls = cpool->resolved_klass_at(i);
+        if (Klass::cast(kls)->name() == sym) {
+          return kls;
+        }
+      }
+    }
+  }
+
+  return found_klass();
+}
+
+// ------------------------------------------------------------------
+// ciEnv::get_klass_by_name
+KlassHandle GraalEnv::get_klass_by_name(KlassHandle& accessing_klass,
+                                  Symbol* klass_name,
+                                  bool require_local) {
+  ResourceMark rm;
+  constantPoolHandle cpool;
+  return get_klass_by_name_impl(accessing_klass,
+                                                 cpool,
+                                                 klass_name,
+                                                 require_local);
+}
+
+// ------------------------------------------------------------------
+// ciEnv::get_klass_by_index_impl
+//
+// Implementation of get_klass_by_index.
+KlassHandle GraalEnv::get_klass_by_index_impl(constantPoolHandle& cpool,
+                                        int index,
+                                        bool& is_accessible,
+                                        KlassHandle& accessor) {
+  EXCEPTION_CONTEXT;
+  KlassHandle klass (THREAD, constantPoolOopDesc::klass_at_if_loaded(cpool, index));
+  Symbol* klass_name = NULL;
+  if (klass.is_null()) {
+    // The klass has not been inserted into the constant pool.
+    // Try to look it up by name.
+    {
+      // We have to lock the cpool to keep the oop from being resolved
+      // while we are accessing it.
+      ObjectLocker ol(cpool, THREAD);
+
+      constantTag tag = cpool->tag_at(index);
+      if (tag.is_klass()) {
+        // The klass has been inserted into the constant pool
+        // very recently.
+        klass = KlassHandle(THREAD, cpool->resolved_klass_at(index));
+      } else if (tag.is_symbol()) {
+        klass_name = cpool->symbol_at(index);
+      } else {
+        assert(cpool->tag_at(index).is_unresolved_klass(), "wrong tag");
+        klass_name = cpool->unresolved_klass_at(index);
+      }
+    }
+  }
+
+  if (klass.is_null()) {
+    // Not found in constant pool.  Use the name to do the lookup.
+    KlassHandle k = get_klass_by_name_impl(accessor,
+                                        cpool,
+                                        klass_name,
+                                        false);
+    // Calculate accessibility the hard way.
+    if (k.is_null()) {
+      is_accessible = false;
+    } else if (k->class_loader() != accessor->class_loader() &&
+               get_klass_by_name_impl(accessor, cpool, k->name(), true).is_null()) {
+      // Loaded only remotely.  Not linked yet.
+      is_accessible = false;
+    } else {
+      // Linked locally, and we must also check public/private, etc.
+      is_accessible = check_klass_accessibility(accessor, k);
+    }
+    if (!is_accessible) {
+      return KlassHandle();
+    }
+    return k;
+  }
+
+  // It is known to be accessible, since it was found in the constant pool.
+  is_accessible = true;
+  return klass;
+}
+
+// ------------------------------------------------------------------
+// ciEnv::get_klass_by_index
+//
+// Get a klass from the constant pool.
+KlassHandle GraalEnv::get_klass_by_index(constantPoolHandle& cpool,
+                                   int index,
+                                   bool& is_accessible,
+                                   KlassHandle& accessor) {
+  ResourceMark rm;
+  KlassHandle result = get_klass_by_index_impl(cpool, index, is_accessible, accessor);
+  return result;
+}
+
+// ------------------------------------------------------------------
+// ciEnv::get_field_by_index_impl
+//
+// Implementation of get_field_by_index.
+//
+// Implementation note: the results of field lookups are cached
+// in the accessor klass.
+void GraalEnv::get_field_by_index_impl(instanceKlassHandle& klass, fieldDescriptor& field_desc,
+                                        int index) {
+  EXCEPTION_CONTEXT;
+
+  assert(klass->is_linked(), "must be linked before using its constant-pool");
+
+  constantPoolHandle cpool(thread, klass->constants());
+
+  // Get the field's name, signature, and type.
+  Symbol* name  = cpool->name_ref_at(index);
+
+  int nt_index = cpool->name_and_type_ref_index_at(index);
+  int sig_index = cpool->signature_ref_index_at(nt_index);
+  Symbol* signature = cpool->symbol_at(sig_index);
+
+  // Get the field's declared holder.
+  //
+  // Note: we actually create a ciInstanceKlass for this klass,
+  // even though we may not need to.
+  int holder_index = cpool->klass_ref_index_at(index);
+  bool holder_is_accessible;
+  KlassHandle declared_holder = get_klass_by_index(cpool, holder_index,
+                                               holder_is_accessible,
+                                               klass);
+
+  // The declared holder of this field may not have been loaded.
+  // Bail out with partial field information.
+  if (!holder_is_accessible) {
+    return;
+  }
+
+
+  // Perform the field lookup.
+  klassOop canonical_holder =
+    instanceKlass::cast(declared_holder())->find_field(name, signature, &field_desc);
+  if (canonical_holder == NULL) {
+    return;
+  }
+
+  assert(canonical_holder == field_desc.field_holder(), "just checking");
+}
+
+// ------------------------------------------------------------------
+// ciEnv::get_field_by_index
+//
+// Get a field by index from a klass's constant pool.
+void GraalEnv::get_field_by_index(instanceKlassHandle& accessor, fieldDescriptor& fd,
+                                   int index) {
+  ResourceMark rm;
+  return get_field_by_index_impl(accessor, fd, index);
+}
+
+// ------------------------------------------------------------------
+// ciEnv::lookup_method
+//
+// Perform an appropriate method lookup based on accessor, holder,
+// name, signature, and bytecode.
+methodHandle GraalEnv::lookup_method(instanceKlassHandle& h_accessor,
+                               instanceKlassHandle& h_holder,
+                               Symbol*       name,
+                               Symbol*       sig,
+                               Bytecodes::Code bc) {
+  EXCEPTION_CONTEXT;
+  LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL));
+  methodHandle dest_method;
+  switch (bc) {
+  case Bytecodes::_invokestatic:
+    dest_method =
+      LinkResolver::resolve_static_call_or_null(h_holder, name, sig, h_accessor);
+    break;
+  case Bytecodes::_invokespecial:
+    dest_method =
+      LinkResolver::resolve_special_call_or_null(h_holder, name, sig, h_accessor);
+    break;
+  case Bytecodes::_invokeinterface:
+    dest_method =
+      LinkResolver::linktime_resolve_interface_method_or_null(h_holder, name, sig,
+                                                              h_accessor, true);
+    break;
+  case Bytecodes::_invokevirtual:
+    dest_method =
+      LinkResolver::linktime_resolve_virtual_method_or_null(h_holder, name, sig,
+                                                            h_accessor, true);
+    break;
+  default: ShouldNotReachHere();
+  }
+
+  return dest_method;
+}
+
+
+// ------------------------------------------------------------------
+// ciEnv::get_method_by_index_impl
+methodHandle GraalEnv::get_method_by_index_impl(constantPoolHandle& cpool,
+                                          int index, Bytecodes::Code bc,
+                                          instanceKlassHandle& accessor) {
+  int holder_index = cpool->klass_ref_index_at(index);
+  bool holder_is_accessible;
+  KlassHandle holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor);
+
+  // Get the method's name and signature.
+  Symbol* name_sym = cpool->name_ref_at(index);
+  Symbol* sig_sym  = cpool->signature_ref_at(index);
+
+  if (holder_is_accessible) { // Our declared holder is loaded.
+    instanceKlassHandle lookup = get_instance_klass_for_declared_method_holder(holder);
+    methodHandle m = lookup_method(accessor, lookup, name_sym, sig_sym, bc);
+    if (!m.is_null() &&
+        (bc == Bytecodes::_invokestatic
+         ?  instanceKlass::cast(m->method_holder())->is_not_initialized()
+         : !instanceKlass::cast(m->method_holder())->is_loaded())) {
+      m = NULL;
+    }
+    if (!m.is_null()) {
+      // We found the method.
+      return m;
+    }
+  }
+
+  // Either the declared holder was not loaded, or the method could
+  // not be found.  Create a dummy ciMethod to represent the failed
+  // lookup.
+
+  return NULL;
+}
+
+// ------------------------------------------------------------------
+// ciEnv::get_instance_klass_for_declared_method_holder
+instanceKlassHandle GraalEnv::get_instance_klass_for_declared_method_holder(KlassHandle& method_holder) {
+  // For the case of <array>.clone(), the method holder can be a ciArrayKlass
+  // instead of a ciInstanceKlass.  For that case simply pretend that the
+  // declared holder is Object.clone since that's where the call will bottom out.
+  // A more correct fix would trickle out through many interfaces in CI,
+  // requiring ciInstanceKlass* to become ciKlass* and many more places would
+  // require checks to make sure the expected type was found.  Given that this
+  // only occurs for clone() the more extensive fix seems like overkill so
+  // instead we simply smear the array type into Object.
+  if (method_holder->oop_is_instance()) {
+    return instanceKlassHandle(method_holder());
+  } else if (method_holder->oop_is_array()) {
+    return instanceKlassHandle(SystemDictionary::Object_klass());
+  } else {
+    ShouldNotReachHere();
+  }
+  return NULL;
+}
+
+
+// ------------------------------------------------------------------
+// ciEnv::get_method_by_index
+methodHandle GraalEnv::get_method_by_index(constantPoolHandle& cpool,
+                                     int index, Bytecodes::Code bc,
+                                     instanceKlassHandle& accessor) {
+  ResourceMark rm;
+  assert(bc != Bytecodes::_invokedynamic, "invokedynamic not yet supported");
+  return get_method_by_index_impl(cpool, index, bc, accessor);
+}
+
+// ------------------------------------------------------------------
+// ciEnv::check_for_system_dictionary_modification
+// Check for changes to the system dictionary during compilation
+// class loads, evolution, breakpoints
+bool GraalEnv::check_for_system_dictionary_modification(Dependencies* dependencies) {
+  // Dependencies must be checked when the system dictionary changes.
+  // If logging is enabled all violated dependences will be recorded in
+  // the log.  In debug mode check dependencies even if the system
+  // dictionary hasn't changed to verify that no invalid dependencies
+  // were inserted.  Any violated dependences in this case are dumped to
+  // the tty.
+
+  // TODO (tw): Always check dependency for now.
+  //bool counter_changed = system_dictionary_modification_counter_changed();
+  //bool test_deps = counter_changed;
+  //DEBUG_ONLY(test_deps = true);
+  //if (!test_deps)  return;
+
+  for (Dependencies::DepStream deps(dependencies); deps.next(); ) {
+    klassOop witness = deps.check_dependency();
+    if (witness != NULL) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+// ------------------------------------------------------------------
+// ciEnv::register_method
+nmethod* GraalEnv::register_method(methodHandle& method,
+                                int entry_bci,
+                                CodeOffsets* offsets,
+                                int orig_pc_offset,
+                                CodeBuffer* code_buffer,
+                                int frame_words,
+                                OopMapSet* oop_map_set,
+                                ExceptionHandlerTable* handler_table,
+                                ImplicitExceptionTable* inc_table,
+                                AbstractCompiler* compiler,
+                                DebugInformationRecorder* debug_info,
+                                Dependencies* dependencies,
+                                CompileTask* task,
+                                int compile_id,
+                                bool has_debug_info,
+                                bool has_unsafe_access,
+                                bool install_code) {
+  EXCEPTION_CONTEXT;
+  NMethodSweeper::possibly_sweep();
+  nmethod* nm = NULL;
+  int comp_level = CompLevel_simple;
+  {
+    // To prevent compile queue updates.
+    MutexLocker locker(MethodCompileQueue_lock, THREAD);
+
+    // Prevent SystemDictionary::add_to_hierarchy from running
+    // and invalidating our dependencies until we install this method.
+    MutexLocker ml(Compile_lock);
+
+    // Encode the dependencies now, so we can check them right away.
+    dependencies->encode_content_bytes();
+
+    // Check for {class loads, evolution, breakpoints} during compilation
+    if (!check_for_system_dictionary_modification(dependencies)) {
+      // While not a true deoptimization, it is a preemptive decompile.
+      methodDataOop mdo = method()->method_data();
+      if (mdo != NULL) {
+        mdo->inc_decompile_count();
+      }
+
+      // All buffers in the CodeBuffer are allocated in the CodeCache.
+      // If the code buffer is created on each compile attempt
+      // as in C2, then it must be freed.
+      //code_buffer->free_blob();
+      return NULL;
+    }
+
+    assert(offsets->value(CodeOffsets::Deopt) != -1, "must have deopt entry");
+    assert(offsets->value(CodeOffsets::Exceptions) != -1, "must have exception entry");
+
+    nm =  nmethod::new_nmethod(method,
+                               compile_id,
+                               entry_bci,
+                               offsets,
+                               orig_pc_offset,
+                               debug_info, dependencies, code_buffer,
+                               frame_words, oop_map_set,
+                               handler_table, inc_table,
+                               compiler, comp_level);
+
+    // Free codeBlobs
+    //code_buffer->free_blob();
+
+    // stress test 6243940 by immediately making the method
+    // non-entrant behind the system's back. This has serious
+    // side effects on the code cache and is not meant for
+    // general stress testing
+    if (nm != NULL && StressNonEntrant) {
+      MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag);
+      NativeJump::patch_verified_entry(nm->entry_point(), nm->verified_entry_point(),
+                  SharedRuntime::get_handle_wrong_method_stub());
+    }
+
+    if (nm == NULL) {
+      // The CodeCache is full.  Print out warning and disable compilation.
+      {
+        MutexUnlocker ml(Compile_lock);
+        MutexUnlocker locker(MethodCompileQueue_lock);
+        CompileBroker::handle_full_code_cache();
+      }
+    } else {
+      nm->set_has_unsafe_access(has_unsafe_access);
+
+      // Record successful registration.
+      // (Put nm into the task handle *before* publishing to the Java heap.)
+      if (task != NULL)  task->set_code(nm);
+
+      if (install_code) {
+        if (entry_bci == InvocationEntryBci) {
+          if (TieredCompilation) {
+            // If there is an old version we're done with it
+            nmethod* old = method->code();
+            if (TraceMethodReplacement && old != NULL) {
+              ResourceMark rm;
+              char *method_name = method->name_and_sig_as_C_string();
+              tty->print_cr("Replacing method %s", method_name);
+            }
+            if (old != NULL ) {
+              old->make_not_entrant();
+            }
+          }
+          if (TraceNMethodInstalls ) {
+            ResourceMark rm;
+            char *method_name = method->name_and_sig_as_C_string();
+            ttyLocker ttyl;
+            tty->print_cr("Installing method (%d) %s ",
+                          comp_level,
+                          method_name);
+          }
+          // Allow the code to be executed
+          method->set_code(method, nm);
+        } else {
+          if (TraceNMethodInstalls ) {
+            ResourceMark rm;
+            char *method_name = method->name_and_sig_as_C_string();
+            ttyLocker ttyl;
+            tty->print_cr("Installing osr method (%d) %s @ %d",
+                          comp_level,
+                          method_name,
+                          entry_bci);
+          }
+          instanceKlass::cast(method->method_holder())->add_osr_nmethod(nm);
+
+        }
+      }
+    }
+  }
+  // JVMTI -- compiled method notification (must be done outside lock)
+  if (nm != NULL) {
+    nm->post_compiled_method_load_event();
+  }
+
+  return nm;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/graal/graalEnv.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 1999, 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.
+ *
+ */
+
+#ifndef SHARE_VM_GRAAL_GRAALENV_HPP
+#define SHARE_VM_GRAAL_GRAALENV_HPP
+
+#include "classfile/systemDictionary.hpp"
+#include "code/debugInfoRec.hpp"
+#include "code/dependencies.hpp"
+#include "code/exceptionHandlerTable.hpp"
+#include "compiler/oopMap.hpp"
+#include "runtime/thread.hpp"
+
+class CompileTask;
+
+// ciEnv
+//
+// This class is the top level broker for requests from the compiler
+// to the VM.
+class GraalEnv : AllStatic {
+  CI_PACKAGE_ACCESS_TO
+
+  friend class CompileBroker;
+  friend class Dependencies;  // for get_object, during logging
+
+public:
+
+  // Look up a klass by name from a particular class loader (the accessor's).
+  // If require_local, result must be defined in that class loader, or NULL.
+  // If !require_local, a result from remote class loader may be reported,
+  // if sufficient class loader constraints exist such that initiating
+  // a class loading request from the given loader is bound to return
+  // the class defined in the remote loader (or throw an error).
+  //
+  // Return an unloaded klass if !require_local and no class at all is found.
+  //
+  // The CI treats a klass as loaded if it is consistently defined in
+  // another loader, even if it hasn't yet been loaded in all loaders
+  // that could potentially see it via delegation.
+  static KlassHandle get_klass_by_name(KlassHandle& accessing_klass,
+                             Symbol* klass_name,
+                             bool require_local);
+
+  // Constant pool access.
+  static KlassHandle   get_klass_by_index(constantPoolHandle& cpool,
+                                int klass_index,
+                                bool& is_accessible,
+                                KlassHandle& loading_klass);
+  static void   get_field_by_index(instanceKlassHandle& loading_klass, fieldDescriptor& fd,
+                                int field_index);
+  static methodHandle  get_method_by_index(constantPoolHandle& cpool,
+                                 int method_index, Bytecodes::Code bc,
+                                 instanceKlassHandle& loading_klass);
+
+private:
+
+  // Implementation methods for loading and constant pool access.
+  static KlassHandle get_klass_by_name_impl(KlassHandle& accessing_klass,
+                                  constantPoolHandle& cpool,
+                                  Symbol* klass_name,
+                                  bool require_local);
+  static KlassHandle   get_klass_by_index_impl(constantPoolHandle& cpool,
+                                     int klass_index,
+                                     bool& is_accessible,
+                                     KlassHandle& loading_klass);
+  static void   get_field_by_index_impl(instanceKlassHandle& loading_klass, fieldDescriptor& fd,
+                                     int field_index);
+  static methodHandle  get_method_by_index_impl(constantPoolHandle& cpool,
+                                      int method_index, Bytecodes::Code bc,
+                                      instanceKlassHandle& loading_klass);
+
+  // Helper methods
+  static bool       check_klass_accessibility(KlassHandle accessing_klass, KlassHandle resolved_klassOop);
+  static methodHandle  lookup_method(instanceKlassHandle&  accessor,
+                           instanceKlassHandle&  holder,
+                           Symbol*         name,
+                           Symbol*         sig,
+                           Bytecodes::Code bc);
+
+  private:
+
+  // Is this thread currently in the VM state?
+  static bool is_in_vm();
+
+  // Helper routine for determining the validity of a compilation
+  // with respect to concurrent class loading.
+  static bool check_for_system_dictionary_modification(Dependencies* target);
+
+public:
+  // Register the result of a compilation.
+  static nmethod* register_method(methodHandle&             target,
+                       int                       entry_bci,
+                       CodeOffsets*              offsets,
+                       int                       orig_pc_offset,
+                       CodeBuffer*               code_buffer,
+                       int                       frame_words,
+                       OopMapSet*                oop_map_set,
+                       ExceptionHandlerTable*    handler_table,
+                       ImplicitExceptionTable*   inc_table,
+                       AbstractCompiler*         compiler,
+                       DebugInformationRecorder* debug_info,
+                       Dependencies*             dependencies,
+                       CompileTask*              task,
+                       int                       compile_id,
+                       bool                      has_debug_info = true,
+                       bool                      has_unsafe_access = false,
+                       bool                      install_code = true);
+
+  static ciKlass*  find_system_klass(ciSymbol* klass_name);
+  // Note:  To find a class from its name string, use ciSymbol::make,
+  // but consider adding to vmSymbols.hpp instead.
+
+  // converts the ciKlass* representing the holder of a method into a
+  // ciInstanceKlass*.  This is needed since the holder of a method in
+  // the bytecodes could be an array type.  Basically this converts
+  // array types into java/lang/Object and other types stay as they are.
+  static instanceKlassHandle get_instance_klass_for_declared_method_holder(KlassHandle& klass);
+};
+
+#endif // SHARE_VM_GRAAL_GRAALENV_HPP
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/graal/graalJavaAccess.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+#include "precompiled.hpp"
+#include "graal/graalJavaAccess.hpp"
+#include "runtime/jniHandles.hpp"
+#include "classfile/symbolTable.hpp"
+// This function is similar to javaClasses.cpp, it computes the field offset of a (static or instance) field.
+// It looks up the name and signature symbols without creating new ones, all the symbols of these classes need to be already loaded.
+
+void compute_offset(int &dest_offset, klassOop klass_oop, const char* name, const char* signature, bool static_field) {
+  Symbol* name_symbol = SymbolTable::probe(name, (int)strlen(name));
+  Symbol* signature_symbol = SymbolTable::probe(signature, (int)strlen(signature));
+#ifndef PRODUCT
+  if (name_symbol == NULL) {
+    tty->print_cr("symbol with name %s was not found in symbol table (klass=%s)", name, klass_oop->klass_part()->name()->as_C_string());
+  }
+#endif
+  guarantee(name_symbol != NULL, "symbol not found - class layout changed?");
+  guarantee(signature_symbol != NULL, "symbol not found - class layout changed?");
+
+  instanceKlass* ik = instanceKlass::cast(klass_oop);
+  fieldDescriptor fd;
+  if (!ik->find_field(name_symbol, signature_symbol, &fd)) {
+    ResourceMark rm;
+    tty->print_cr("Invalid layout of %s at %s", name_symbol->as_C_string(), ik->external_name());
+    fatal("Invalid layout of preloaded class");
+  }
+  guarantee(fd.is_static() == static_field, "static/instance mismatch");
+  dest_offset = fd.offset();
+}
+
+// This piece of macro magic creates the contents of the graal_compute_offsets method that initializes the field indices of all the access classes.
+
+#define START_CLASS(name) { klassOop k = SystemDictionary::name##_klass(); assert(k != NULL, "Could not find class " #name "");
+
+#define END_CLASS }
+
+#define FIELD(klass, name, signature, static_field) compute_offset(klass::_##name##_offset, k, #name, signature, static_field);
+#define CHAR_FIELD(klass, name) FIELD(klass, name, "C", false)
+#define INT_FIELD(klass, name) FIELD(klass, name, "I", false)
+#define BOOLEAN_FIELD(klass, name) FIELD(klass, name, "Z", false)
+#define LONG_FIELD(klass, name) FIELD(klass, name, "J", false)
+#define FLOAT_FIELD(klass, name) FIELD(klass, name, "F", false)
+#define OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, false)
+#define STATIC_OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, true)
+
+
+void graal_compute_offsets() {
+  COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, STATIC_OOP_FIELD)
+}
+
+#define EMPTY0
+#define EMPTY1(x)
+#define EMPTY2(x,y)
+#define FIELD2(klass, name) int klass::_##name##_offset = 0;
+#define FIELD3(klass, name, sig) FIELD2(klass, name)
+
+COMPILER_CLASSES_DO(EMPTY1, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3)
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,291 @@
+/*
+ * 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.
+ */
+
+void graal_compute_offsets();
+
+#include "classfile/systemDictionary.hpp"
+#include "oops/instanceMirrorKlass.hpp"
+
+/* This macro defines the structure of the CiTargetMethod - classes.
+ * It will generate classes with accessors similar to javaClasses.hpp, but with specializations for oops, Handles and jni handles.
+ *
+ * The public interface of these classes will look like this:
+
+ * class CiStackSlot : AllStatic {
+ * public:
+ *   static klassOop klass();
+ *   static jint  index(oop obj);
+ *   static jint  index(Handle obj);
+ *   static jint  index(jobject obj);
+ *   static void set_index(oop obj, jint x);
+ *   static void set_index(Handle obj, jint x);
+ *   static void set_index(jobject obj, jint x);
+ * };
+ *
+ */
+
+#define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, float_field, oop_field, static_oop_field)   \
+  start_class(HotSpotTypeResolved)                                                      \
+    oop_field(HotSpotTypeResolved, compiler, "Lcom/oracle/max/graal/hotspot/Compiler;") \
+    oop_field(HotSpotTypeResolved, javaMirror, "Ljava/lang/Class;")                     \
+    oop_field(HotSpotTypeResolved, simpleName, "Ljava/lang/String;")                    \
+    int_field(HotSpotTypeResolved, accessFlags)                                         \
+    boolean_field(HotSpotTypeResolved, hasFinalizer)                                    \
+    boolean_field(HotSpotTypeResolved, hasSubclass)                                     \
+    boolean_field(HotSpotTypeResolved, hasFinalizableSubclass)                          \
+    boolean_field(HotSpotTypeResolved, isArrayClass)                                    \
+    boolean_field(HotSpotTypeResolved, isInstanceClass)                                 \
+    boolean_field(HotSpotTypeResolved, isInterface)                                     \
+    int_field(HotSpotTypeResolved, instanceSize)                                        \
+  end_class                                                                             \
+  start_class(HotSpotMethodResolved)                                                    \
+    oop_field(HotSpotMethodResolved, compiler, "Lcom/oracle/max/graal/hotspot/Compiler;") \
+    oop_field(HotSpotMethodResolved, name, "Ljava/lang/String;")                        \
+    oop_field(HotSpotMethodResolved, holder, "Lcom/oracle/max/cri/ri/RiResolvedType;")  \
+    oop_field(HotSpotMethodResolved, javaMirror, "Ljava/lang/Object;")                  \
+    int_field(HotSpotMethodResolved, codeSize)                                          \
+    int_field(HotSpotMethodResolved, accessFlags)                                       \
+    int_field(HotSpotMethodResolved, maxLocals)                                         \
+    int_field(HotSpotMethodResolved, maxStackSize)                                      \
+    boolean_field(HotSpotMethodResolved, canBeInlined)                                  \
+    oop_field(HotSpotMethodResolved, callback, "Lcom/oracle/max/cri/ci/CiGenericCallback;") \
+  end_class                                                                             \
+  start_class(HotSpotMethodData)                                                        \
+    oop_field(HotSpotMethodData, compiler, "Lcom/oracle/max/graal/hotspot/Compiler;")   \
+    oop_field(HotSpotMethodData, hotspotMirror, "Ljava/lang/Object;")                   \
+    int_field(HotSpotMethodData, normalDataSize)                                        \
+    int_field(HotSpotMethodData, extraDataSize)                                         \
+  end_class                                                                             \
+  start_class(HotSpotType)                                                              \
+    oop_field(HotSpotType, name, "Ljava/lang/String;")                                  \
+  end_class                                                                             \
+  start_class(HotSpotField)                                                             \
+    oop_field(HotSpotField, constant, "Lcom/oracle/max/cri/ci/CiConstant;")             \
+    int_field(HotSpotField, offset)                                                     \
+    int_field(HotSpotField, accessFlags)                                                \
+  end_class                                                                             \
+  start_class(HotSpotCompiledMethod)                                                    \
+    long_field(HotSpotCompiledMethod, nmethod)                                          \
+    oop_field(HotSpotCompiledMethod, method, "Lcom/oracle/max/cri/ri/RiResolvedMethod;") \
+  end_class                                                                             \
+  start_class(HotSpotProxy)                                                             \
+    static_oop_field(HotSpotProxy, DUMMY_CONSTANT_OBJ, "Ljava/lang/Long;")              \
+  end_class                                                                             \
+  start_class(HotSpotTargetMethod)                                                      \
+    oop_field(HotSpotTargetMethod, targetMethod, "Lcom/oracle/max/cri/ci/CiTargetMethod;") \
+    oop_field(HotSpotTargetMethod, method, "Lcom/oracle/max/graal/hotspot/ri/HotSpotMethodResolved;") \
+    oop_field(HotSpotTargetMethod, name, "Ljava/lang/String;")                          \
+    oop_field(HotSpotTargetMethod, sites, "[Lcom/oracle/max/cri/ci/CiTargetMethod$Site;") \
+    oop_field(HotSpotTargetMethod, exceptionHandlers, "[Lcom/oracle/max/cri/ci/CiTargetMethod$ExceptionHandler;") \
+  end_class                                                                             \
+  start_class(HotSpotExceptionHandler)                                                  \
+    int_field(HotSpotExceptionHandler, startBci)                                        \
+    int_field(HotSpotExceptionHandler, endBci)                                          \
+    int_field(HotSpotExceptionHandler, handlerBci)                                      \
+    int_field(HotSpotExceptionHandler, catchClassIndex)                                 \
+    oop_field(HotSpotExceptionHandler, catchClass, "Lcom/oracle/max/cri/ri/RiType;")    \
+  end_class                                                                             \
+  start_class(CiTargetMethod)                                                           \
+    int_field(CiTargetMethod, frameSize)                                                \
+    int_field(CiTargetMethod, customStackAreaOffset)                                    \
+    oop_field(CiTargetMethod, targetCode, "[B")                                         \
+    oop_field(CiTargetMethod, assumptions, "Lcom/oracle/max/cri/ci/CiAssumptions;")     \
+    int_field(CiTargetMethod, targetCodeSize)                                           \
+  end_class                                                                             \
+  start_class(CiAssumptions)                                                            \
+    oop_field(CiAssumptions, list, "[Lcom/oracle/max/cri/ci/CiAssumptions$Assumption;") \
+  end_class                                                                             \
+  start_class(CiAssumptions_MethodContents)                                             \
+    oop_field(CiAssumptions_MethodContents, method, "Lcom/oracle/max/cri/ri/RiResolvedMethod;") \
+  end_class                                                                             \
+  start_class(CiAssumptions_ConcreteSubtype)                                            \
+    oop_field(CiAssumptions_ConcreteSubtype, context, "Lcom/oracle/max/cri/ri/RiResolvedType;") \
+    oop_field(CiAssumptions_ConcreteSubtype, subtype, "Lcom/oracle/max/cri/ri/RiResolvedType;") \
+  end_class                                                                             \
+  start_class(CiAssumptions_ConcreteMethod)                                             \
+    oop_field(CiAssumptions_ConcreteMethod, method, "Lcom/oracle/max/cri/ri/RiResolvedMethod;") \
+    oop_field(CiAssumptions_ConcreteMethod, context, "Lcom/oracle/max/cri/ri/RiResolvedType;") \
+    oop_field(CiAssumptions_ConcreteMethod, impl, "Lcom/oracle/max/cri/ri/RiResolvedMethod;") \
+  end_class                                                                             \
+  start_class(CiTargetMethod_Site)                                                      \
+    int_field(CiTargetMethod_Site, pcOffset)                                            \
+  end_class                                                                             \
+  start_class(CiTargetMethod_Call)                                                      \
+    oop_field(CiTargetMethod_Call, target, "Ljava/lang/Object;")                        \
+    oop_field(CiTargetMethod_Call, debugInfo, "Lcom/oracle/max/cri/ci/CiDebugInfo;")    \
+  end_class                                                                             \
+  start_class(CiTargetMethod_DataPatch)                                                 \
+    oop_field(CiTargetMethod_DataPatch, constant, "Lcom/oracle/max/cri/ci/CiConstant;") \
+    int_field(CiTargetMethod_DataPatch, alignment)                                      \
+  end_class                                                                             \
+  start_class(CiTargetMethod_Safepoint)                                                 \
+    oop_field(CiTargetMethod_Safepoint, debugInfo, "Lcom/oracle/max/cri/ci/CiDebugInfo;") \
+  end_class                                                                             \
+  start_class(CiTargetMethod_ExceptionHandler)                                          \
+    int_field(CiTargetMethod_ExceptionHandler, handlerPos)                              \
+  end_class                                                                             \
+  start_class(CiTargetMethod_Mark)                                                      \
+    oop_field(CiTargetMethod_Mark, id, "Ljava/lang/Object;")                            \
+    oop_field(CiTargetMethod_Mark, references, "[Lcom/oracle/max/cri/ci/CiTargetMethod$Mark;") \
+  end_class                                                                             \
+  start_class(CiDebugInfo)                                                              \
+    oop_field(CiDebugInfo, codePos, "Lcom/oracle/max/cri/ci/CiCodePos;")                \
+    oop_field(CiDebugInfo, registerRefMap, "Lcom/oracle/max/cri/ci/CiBitMap;")          \
+    oop_field(CiDebugInfo, frameRefMap, "Lcom/oracle/max/cri/ci/CiBitMap;")             \
+  end_class                                                                             \
+  start_class(GraalBitMap)                                                              \
+    int_field(GraalBitMap, size)                                                        \
+    long_field(GraalBitMap, low)                                                        \
+    oop_field(GraalBitMap, extra, "[J")                                                 \
+  end_class                                                                             \
+  start_class(CiFrame)                                                                  \
+    oop_field(CiFrame, values, "[Lcom/oracle/max/cri/ci/CiValue;")                      \
+    int_field(CiFrame, numLocals)                                                       \
+    int_field(CiFrame, numStack)                                                        \
+    int_field(CiFrame, numLocks)                                                        \
+    boolean_field(CiFrame, rethrowException)                                            \
+    boolean_field(CiFrame, duringCall)                                                  \
+  end_class                                                                             \
+  start_class(CiCodePos)                                                                \
+    oop_field(CiCodePos, caller, "Lcom/oracle/max/cri/ci/CiCodePos;")                   \
+    oop_field(CiCodePos, method, "Lcom/oracle/max/cri/ri/RiResolvedMethod;")            \
+    int_field(CiCodePos, bci)                                                           \
+  end_class                                                                             \
+  start_class(CiConstant)                                                               \
+    oop_field(CiConstant, kind, "Lcom/oracle/max/cri/ci/CiKind;")                       \
+    oop_field(CiConstant, object, "Ljava/lang/Object;")                                 \
+    long_field(CiConstant, primitive)                                                   \
+  end_class                                                                             \
+  start_class(CiKind)                                                                   \
+    char_field(CiKind, typeChar)                                                        \
+    static_oop_field(CiKind, Boolean, "Lcom/oracle/max/cri/ci/CiKind;");                \
+    static_oop_field(CiKind, Byte, "Lcom/oracle/max/cri/ci/CiKind;");                   \
+    static_oop_field(CiKind, Char, "Lcom/oracle/max/cri/ci/CiKind;");                   \
+    static_oop_field(CiKind, Short, "Lcom/oracle/max/cri/ci/CiKind;");                  \
+    static_oop_field(CiKind, Int, "Lcom/oracle/max/cri/ci/CiKind;");                    \
+    static_oop_field(CiKind, Long, "Lcom/oracle/max/cri/ci/CiKind;");                   \
+  end_class                                                                             \
+  start_class(CiRuntimeCall)                                                            \
+    static_oop_field(CiRuntimeCall, UnwindException, "Lcom/oracle/max/cri/ci/CiRuntimeCall;"); \
+    static_oop_field(CiRuntimeCall, RegisterFinalizer, "Lcom/oracle/max/cri/ci/CiRuntimeCall;"); \
+    static_oop_field(CiRuntimeCall, SetDeoptInfo, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");    \
+    static_oop_field(CiRuntimeCall, CreateNullPointerException, "Lcom/oracle/max/cri/ci/CiRuntimeCall;"); \
+    static_oop_field(CiRuntimeCall, CreateOutOfBoundsException, "Lcom/oracle/max/cri/ci/CiRuntimeCall;"); \
+    static_oop_field(CiRuntimeCall, JavaTimeMillis, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");  \
+    static_oop_field(CiRuntimeCall, JavaTimeNanos, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");   \
+    static_oop_field(CiRuntimeCall, Debug, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");           \
+    static_oop_field(CiRuntimeCall, ArithmeticFrem, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");  \
+    static_oop_field(CiRuntimeCall, ArithmeticDrem, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");  \
+    static_oop_field(CiRuntimeCall, ArithmeticCos, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");   \
+    static_oop_field(CiRuntimeCall, ArithmeticTan, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");   \
+    static_oop_field(CiRuntimeCall, ArithmeticSin, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");   \
+    static_oop_field(CiRuntimeCall, Deoptimize, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");      \
+    static_oop_field(CiRuntimeCall, GenericCallback, "Lcom/oracle/max/cri/ci/CiRuntimeCall;"); \
+  end_class                                                                             \
+  start_class(RiMethod)                                                                 \
+  end_class                                                                             \
+  start_class(CiValue)                                                                  \
+    oop_field(CiValue, kind, "Lcom/oracle/max/cri/ci/CiKind;")                          \
+    static_oop_field(CiValue, IllegalValue, "Lcom/oracle/max/cri/ci/CiValue;");         \
+  end_class                                                                             \
+  start_class(CiRegisterValue)                                                          \
+    oop_field(CiRegisterValue, reg, "Lcom/oracle/max/cri/ci/CiRegister;")               \
+  end_class                                                                             \
+  start_class(CiRegister)                                                               \
+    int_field(CiRegister, number)                                                       \
+  end_class                                                                             \
+  start_class(CiStackSlot)                                                              \
+    int_field(CiStackSlot, offset)                                                      \
+    boolean_field(CiStackSlot, addFrameSize)                                            \
+  end_class                                                                             \
+  start_class(CiVirtualObject)                                                          \
+    int_field(CiVirtualObject, id)                                                      \
+    oop_field(CiVirtualObject, type, "Lcom/oracle/max/cri/ri/RiType;")                  \
+    oop_field(CiVirtualObject, values, "[Lcom/oracle/max/cri/ci/CiValue;")              \
+  end_class                                                                             \
+  start_class(CiMonitorValue)                                                           \
+    oop_field(CiMonitorValue, owner, "Lcom/oracle/max/cri/ci/CiValue;")                 \
+    oop_field(CiMonitorValue, lockData, "Lcom/oracle/max/cri/ci/CiValue;")              \
+    boolean_field(CiMonitorValue, eliminated)                                           \
+  end_class                                                                             \
+  /* end*/
+
+#define START_CLASS(name)                       \
+class name : AllStatic {                      \
+  private:                                      \
+    friend class GraalCompiler;                   \
+    static void check(oop obj) { assert(obj != NULL, "NULL field access of class " #name); assert(obj->is_a(SystemDictionary::name##_klass()), "wrong class, " #name " expected"); } \
+    static void compute_offsets();              \
+  public:                                       \
+    static klassOop klass() { return SystemDictionary::name##_klass(); }
+
+#define END_CLASS };
+
+#define FIELD(name, type, accessor)             \
+    static int _##name##_offset;                \
+    static type name(oop obj)                   { check(obj); return obj->accessor(_##name##_offset); } \
+    static type name(Handle& obj)                { check(obj()); return obj->accessor(_##name##_offset); } \
+    static type name(jobject obj)               { check(JNIHandles::resolve(obj)); return JNIHandles::resolve(obj)->accessor(_##name##_offset); } \
+    static void set_##name(oop obj, type x)     { check(obj); obj->accessor##_put(_##name##_offset, x); } \
+    static void set_##name(Handle& obj, type x)  { check(obj()); obj->accessor##_put(_##name##_offset, x); } \
+    static void set_##name(jobject obj, type x) { check(JNIHandles::resolve(obj)); JNIHandles::resolve(obj)->accessor##_put(_##name##_offset, x); }
+
+#define CHAR_FIELD(klass, name) FIELD(name, jchar, char_field)
+#define INT_FIELD(klass, name) FIELD(name, jint, int_field)
+#define BOOLEAN_FIELD(klass, name) FIELD(name, jboolean, bool_field)
+#define LONG_FIELD(klass, name) FIELD(name, jlong, long_field)
+#define FLOAT_FIELD(klass, name) FIELD(name, jfloat, float_field)
+#define OOP_FIELD(klass, name, signature) FIELD(name, oop, obj_field)
+#define STATIC_OOP_FIELD(klassName, name, signature)                \
+    static int _##name##_offset;                                    \
+    static oop name() {                                             \
+      instanceKlass* ik = instanceKlass::cast(klassName::klass());  \
+      address addr = ik->static_field_addr(_##name##_offset - instanceMirrorKlass::offset_of_static_fields());       \
+      if (UseCompressedOops) {                                      \
+        return oopDesc::load_decode_heap_oop((narrowOop *)addr);    \
+      } else {                                                      \
+        return oopDesc::load_decode_heap_oop((oop*)addr);           \
+      }                                                             \
+    }                                                               \
+    static void set_##name(oop x) {                                 \
+      instanceKlass* ik = instanceKlass::cast(klassName::klass());  \
+      address addr = ik->static_field_addr(_##name##_offset - instanceMirrorKlass::offset_of_static_fields());       \
+      if (UseCompressedOops) {                                      \
+        oop_store((narrowOop *)addr, x);       \
+      } else {                                                      \
+        oop_store((oop*)addr, x);              \
+      }                                                             \
+    }
+COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, STATIC_OOP_FIELD)
+#undef START_CLASS
+#undef END_CLASS
+#undef FIELD
+#undef CHAR_FIELD
+#undef INT_FIELD
+#undef BOOLEAN_FIELD
+#undef LONG_FIELD
+#undef FLOAT_FIELD
+#undef OOP_FIELD
+#undef STATIC_OOP_FIELD
+
+void compute_offset(int &dest_offset, klassOop klass_oop, const char* name, const char* signature, bool static_field);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/graal/graalVMToCompiler.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,279 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "graal/graalVMToCompiler.hpp"
+
+// this is a *global* handle
+jobject VMToCompiler::_compilerPermObject = NULL;
+jobject VMToCompiler::_vmExitsPermObject = NULL;
+jobject VMToCompiler::_vmExitsPermKlass = NULL;
+
+KlassHandle VMToCompiler::vmExitsKlass() {
+  if (JNIHandles::resolve(_vmExitsPermKlass) == NULL) {
+    klassOop result = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_max_graal_hotspot_bridge_VMToCompiler(), SystemDictionary::java_system_loader(), NULL, Thread::current());
+    check_not_null(result, "Couldn't find class com.oracle.max.graal.hotspot.bridge.VMToCompiler");
+    _vmExitsPermKlass = JNIHandles::make_global(result);
+  }
+  return KlassHandle((klassOop)JNIHandles::resolve_non_null(_vmExitsPermKlass));
+}
+
+Handle VMToCompiler::compilerInstance() {
+  if (JNIHandles::resolve(_compilerPermObject) == NULL) {
+    KlassHandle compilerImplKlass = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_max_graal_hotspot_CompilerImpl(), SystemDictionary::java_system_loader(), NULL, Thread::current());
+    check_not_null(compilerImplKlass(), "Couldn't find class com.sun.hotspot.graal.CompilerImpl");
+
+    JavaValue result(T_OBJECT);
+    JavaCalls::call_static(&result, compilerImplKlass, vmSymbols::getInstance_name(), vmSymbols::getInstance_signature(), Thread::current());
+    check_pending_exception("Couldn't get Compiler");
+    _compilerPermObject = JNIHandles::make_global((oop) result.get_jobject());
+  }
+  return Handle(JNIHandles::resolve_non_null(_compilerPermObject));
+}
+
+Handle VMToCompiler::instance() {
+  if (JNIHandles::resolve(_vmExitsPermObject) == NULL) {
+    KlassHandle compilerKlass = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_max_graal_hotspot_Compiler(), SystemDictionary::java_system_loader(), NULL, Thread::current());
+    check_not_null(compilerKlass(), "Couldn't find class com.sun.hotspot.graal.Compiler");
+
+    JavaValue result(T_OBJECT);
+    JavaCallArguments args;
+    args.set_receiver(compilerInstance());
+    JavaCalls::call_interface(&result, compilerKlass, vmSymbols::getVMExits_name(), vmSymbols::getVMExits_signature(), &args, Thread::current());
+    check_pending_exception("Couldn't get VMExits");
+    _vmExitsPermObject = JNIHandles::make_global((oop) result.get_jobject());
+  }
+  return Handle(JNIHandles::resolve_non_null(_vmExitsPermObject));
+}
+
+void VMToCompiler::initializeCompiler() {
+  KlassHandle compilerImplKlass = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_max_graal_hotspot_CompilerImpl(), SystemDictionary::java_system_loader(), NULL, Thread::current());
+  check_not_null(compilerImplKlass(), "Couldn't find class com.sun.hotspot.graal.CompilerImpl");
+
+  JavaValue result(T_VOID);
+  JavaCalls::call_static(&result, compilerImplKlass, vmSymbols::initialize_name(), vmSymbols::void_method_signature(), Thread::current());
+  check_pending_exception("Couldn't initialize compiler");
+}
+
+jboolean VMToCompiler::setOption(Handle option) {
+  assert(!option.is_null(), "");
+  KlassHandle compilerKlass = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_max_graal_hotspot_HotSpotOptions(), SystemDictionary::java_system_loader(), NULL, Thread::current());
+  check_not_null(compilerKlass(), "Couldn't find class com.sun.hotspot.graal.HotSpotOptions");
+
+  Thread* THREAD = Thread::current();
+  JavaValue result(T_BOOLEAN);
+  JavaCalls::call_static(&result, compilerKlass, vmSymbols::setOption_name(), vmSymbols::setOption_signature(), option, THREAD);
+  check_pending_exception("Error while calling setOption");
+  return result.get_jboolean();
+}
+
+void VMToCompiler::setDefaultOptions() {
+  KlassHandle compilerKlass = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_max_graal_hotspot_HotSpotOptions(), SystemDictionary::java_system_loader(), NULL, Thread::current());
+  check_not_null(compilerKlass(), "Couldn't find class com.sun.hotspot.graal.HotSpotOptions");
+
+  Thread* THREAD = Thread::current();
+  JavaValue result(T_VOID);
+  JavaCalls::call_static(&result, compilerKlass, vmSymbols::setDefaultOptions_name(), vmSymbols::void_method_signature(), THREAD);
+  check_pending_exception("Error while calling setDefaultOptions");
+}
+
+void VMToCompiler::compileMethod(Handle hotspot_method, int entry_bci, jboolean blocking) {
+  assert(!hotspot_method.is_null(), "just checking");
+  Thread* THREAD = Thread::current();
+  JavaValue result(T_VOID);
+  JavaCallArguments args;
+  args.push_oop(instance());
+  args.push_oop(hotspot_method);
+  args.push_int(entry_bci);
+  args.push_int(blocking);
+  JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::compileMethod_name(), vmSymbols::compileMethod_signature(), &args, THREAD);
+  check_pending_exception("Error while calling compileMethod");
+}
+
+void VMToCompiler::shutdownCompiler() {
+  if (_compilerPermObject != NULL) {
+    HandleMark hm;
+    JavaThread* THREAD = JavaThread::current();
+    JavaValue result(T_VOID);
+    JavaCallArguments args;
+    args.push_oop(instance());
+    JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::shutdownCompiler_name(), vmSymbols::void_method_signature(), &args, THREAD);
+    check_pending_exception("Error while calling shutdownCompiler");
+
+    JNIHandles::destroy_global(_compilerPermObject);
+    JNIHandles::destroy_global(_vmExitsPermObject);
+    JNIHandles::destroy_global(_vmExitsPermKlass);
+
+    _compilerPermObject = NULL;
+    _vmExitsPermObject = NULL;
+    _vmExitsPermKlass = NULL;
+  }
+}
+
+void VMToCompiler::startCompiler() {
+  JavaThread* THREAD = JavaThread::current();
+  JavaValue result(T_VOID);
+  JavaCallArguments args;
+  args.push_oop(instance());
+  JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::startCompiler_name(), vmSymbols::void_method_signature(), &args, THREAD);
+  check_pending_exception("Error while calling startCompiler");
+}
+
+void VMToCompiler::bootstrap() {
+  JavaThread* THREAD = JavaThread::current();
+  JavaValue result(T_VOID);
+  JavaCallArguments args;
+  args.push_oop(instance());
+  JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::bootstrap_name(), vmSymbols::void_method_signature(), &args, THREAD);
+  check_pending_exception("Error while calling boostrap");
+}
+
+oop VMToCompiler::createRiMethodResolved(jlong vmId, Handle name, TRAPS) {
+  assert(!name.is_null(), "just checking");
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args;
+  args.push_oop(instance());
+  args.push_long(vmId);
+  args.push_oop(name);
+  JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createRiMethodResolved_name(), vmSymbols::createRiMethodResolved_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createRiMethodResolved");
+  return (oop) result.get_jobject();
+}
+
+oop VMToCompiler::createRiMethodUnresolved(Handle name, Handle signature, Handle holder, TRAPS) {
+  assert(!name.is_null(), "just checking");
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args;
+  args.push_oop(instance());
+  args.push_oop(name);
+  args.push_oop(signature);
+  args.push_oop(holder);
+  JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createRiMethodUnresolved_name(), vmSymbols::createRiMethodUnresolved_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createRiMethodUnresolved");
+  return (oop) result.get_jobject();
+}
+
+oop VMToCompiler::createRiField(Handle holder, Handle name, Handle type, int index, int flags, TRAPS) {
+  assert(!holder.is_null(), "just checking");
+  assert(!name.is_null(), "just checking");
+  assert(!type.is_null(), "just checking");
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args;
+  args.push_oop(instance());
+  args.push_oop(holder);
+  args.push_oop(name);
+  args.push_oop(type);
+  args.push_int(index);
+  args.push_int(flags);
+  JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createRiField_name(), vmSymbols::createRiField_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createRiField");
+  assert(result.get_type() == T_OBJECT, "just checking");
+  return (oop) result.get_jobject();
+}
+
+oop VMToCompiler::createRiType(jlong vmId, Handle name, TRAPS) {
+  assert(!name.is_null(), "just checking");
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args;
+  args.push_oop(instance());
+  args.push_long(vmId);
+  args.push_oop(name);
+  JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createRiType_name(), vmSymbols::createRiType_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createRiType");
+  return (oop) result.get_jobject();
+}
+
+oop VMToCompiler::createRiTypePrimitive(int basic_type, TRAPS) {
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args;
+  args.push_oop(instance());
+  args.push_int(basic_type);
+  JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createRiTypePrimitive_name(), vmSymbols::createRiTypePrimitive_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createRiTypePrimitive");
+  return (oop) result.get_jobject();
+}
+
+oop VMToCompiler::createRiTypeUnresolved(Handle name, TRAPS) {
+  assert(!name.is_null(), "just checking");
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args;
+  args.push_oop(instance());
+  args.push_oop(name);
+  JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createRiTypeUnresolved_name(), vmSymbols::createRiTypeUnresolved_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createRiTypeUnresolved");
+  return (oop) result.get_jobject();
+}
+
+oop VMToCompiler::createRiSignature(Handle name, TRAPS) {
+  assert(!name.is_null(), "just checking");
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args;
+  args.push_oop(instance());
+  args.push_oop(name);
+  JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createRiSignature_name(), vmSymbols::createRiSignature_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createRiSignature");
+  return (oop) result.get_jobject();
+}
+
+oop VMToCompiler::createCiConstant(Handle kind, jlong value, TRAPS) {
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args;
+  args.push_oop(instance());
+  args.push_oop(kind());
+  args.push_long(value);
+  JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createCiConstant_name(), vmSymbols::createCiConstant_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createCiConstantFloat");
+  return (oop) result.get_jobject();
+
+}
+
+oop VMToCompiler::createCiConstantFloat(jfloat value, TRAPS) {
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args;
+  args.push_oop(instance());
+  args.push_float(value);
+  JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createCiConstantFloat_name(), vmSymbols::createCiConstantFloat_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createCiConstantFloat");
+  return (oop) result.get_jobject();
+
+}
+
+oop VMToCompiler::createCiConstantDouble(jdouble value, TRAPS) {
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args;
+  args.push_oop(instance());
+  args.push_double(value);
+  JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createCiConstantDouble_name(), vmSymbols::createCiConstantDouble_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createCiConstantDouble");
+  return (oop) result.get_jobject();
+}
+
+oop VMToCompiler::createCiConstantObject(Handle object, TRAPS) {
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args;
+  KlassHandle klass = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_max_cri_ci_CiConstant(), SystemDictionary::java_system_loader(), NULL, Thread::current());
+  JavaCalls::call_static(&result, klass(), vmSymbols::forObject_name(), vmSymbols::createCiConstantObject_signature(), object, THREAD);
+  check_pending_exception("Error while calling CiConstant.forObject");
+  return (oop) result.get_jobject();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/graal/graalVMToCompiler.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,125 @@
+/*
+ * 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.
+ */
+
+#include "memory/allocation.hpp"
+#include "oops/oop.hpp"
+#include "runtime/handles.hpp"
+#include "runtime/thread.hpp"
+#include "classfile/javaClasses.hpp"
+#include "runtime/jniHandles.hpp"
+#include "runtime/javaCalls.hpp"
+
+class VMToCompiler : public AllStatic {
+
+private:
+  static jobject _compilerPermObject;
+  static jobject _vmExitsPermObject;
+  static jobject _vmExitsPermKlass;
+
+  static KlassHandle vmExitsKlass();
+  static Handle instance();
+
+public:
+  static void initializeCompiler();
+
+  static Handle compilerInstance();
+
+  // public static boolean HotSpotOptions.setOption(String option);
+  static jboolean setOption(Handle option);
+
+  // public static void HotSpotOptions.setDefaultOptions();
+  static void setDefaultOptions();
+
+  // public abstract void compileMethod(long vmId, String name, int entry_bci, boolean blocking);
+  static void compileMethod(Handle hotspot_method, int entry_bci, jboolean blocking);
+
+  // public abstract void shutdownCompiler();
+  static void shutdownCompiler();
+  
+  // public abstract void startCompiler();
+  static void startCompiler();
+  
+  // public abstract void bootstrap();
+  static void bootstrap();
+
+  // public abstract RiMethod createRiMethodResolved(long vmId, String name);
+  static oop createRiMethodResolved(jlong vmId, Handle name, TRAPS);
+
+  // public abstract RiMethod createRiMethodUnresolved(String name, String signature, RiType holder);
+  static oop createRiMethodUnresolved(Handle name, Handle signature, Handle holder, TRAPS);
+
+  // public abstract RiField createRiField(RiType holder, String name, RiType type, int flags, int offset);
+  static oop createRiField(Handle holder, Handle name, Handle type, int index, int flags, TRAPS);
+
+  // public abstract RiType createRiType(long vmId, String name);
+  static oop createRiType(jlong vmId, Handle name, TRAPS);
+
+  // public abstract RiType createRiTypeUnresolved(String name);
+  static oop createRiTypeUnresolved(Handle name, TRAPS);
+
+  // public abstract RiType createRiTypePrimitive(int basicType);
+  static oop createRiTypePrimitive(int basicType, TRAPS);
+
+  // public abstract RiSignature createRiSignature(String signature);
+  static oop createRiSignature(Handle name, TRAPS);
+
+  // public abstract CiConstant createCiConstant(CiKind kind, long value);
+  static oop createCiConstant(Handle kind, jlong value, TRAPS);
+
+  // public abstract CiConstant createCiConstantFloat(float value);
+  static oop createCiConstantFloat(jfloat value, TRAPS);
+
+  // public abstract CiConstant createCiConstantDouble(double value);
+  static oop createCiConstantDouble(jdouble value, TRAPS);
+
+  // public abstract CiConstant createCiConstantObject(long vmId);
+  static oop createCiConstantObject(Handle object, TRAPS);
+};
+
+inline void check_pending_exception(const char* message, bool dump_core = false) {
+  Thread* THREAD = Thread::current();
+  if (THREAD->has_pending_exception()) {
+    Handle exception = PENDING_EXCEPTION;
+    CLEAR_PENDING_EXCEPTION;
+
+    assert(exception->is_a(SystemDictionary::Throwable_klass()), "Throwable instance expected");
+    JavaValue result(T_VOID);
+    JavaCalls::call_virtual(&result,
+                            exception,
+                            KlassHandle(THREAD,
+                            SystemDictionary::Throwable_klass()),
+                            vmSymbols::printStackTrace_name(),
+                            vmSymbols::void_method_signature(),
+                            THREAD);
+
+    vm_abort(dump_core);
+  }
+}
+
+inline void check_not_null(void* value, const char* message, bool dump_core = false) {
+  if (value == NULL) {
+    tty->print_cr("%s", message);
+    vm_abort(dump_core);
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/graal/graalVmIds.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "graal/graalVmIds.hpp"
+#include "ci/ciUtilities.hpp"
+
+// VmIds implementation
+
+jlong VmIds::addStub(address stub) {
+  return (jlong)stub;
+}
+
+address VmIds::getStub(jlong id) {
+  return (address)id;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/graal/graalVmIds.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+#include "memory/allocation.hpp"
+#include "utilities/growableArray.hpp"
+#include "oops/oop.hpp"
+#include "runtime/handles.hpp"
+#include "runtime/thread.hpp"
+#include "classfile/javaClasses.hpp"
+#include "runtime/jniHandles.hpp"
+
+class VmIds : public AllStatic {
+
+public:
+  // Adds a stub address, and returns the corresponding vmId (which is of type STUB)
+  static jlong addStub(address stub);
+
+  // Returns the stub address with the given vmId
+  static address getStub(jlong id);
+
+  // Returns the stub address with the given vmId taken from a java.lang.Long
+  static address getStub(oop id);
+
+  // Helper function to convert a symbol to a java.lang.String object
+  template <typename T> static T toString(Symbol* symbol, TRAPS);
+
+  // Helper function to convert a java.lang.String object to a symbol (this will return NULL if the symbol doesn't exist in the system)
+  static Symbol* toSymbol(jstring string);
+
+  // Helper function to get the contents of a java.lang.Long
+  static jlong getBoxedLong(oop obj);
+};
+
+inline address VmIds::getStub(oop obj) {
+  return getStub(getBoxedLong(obj));
+}
+
+template <> inline Handle VmIds::toString<Handle>(Symbol* symbol, TRAPS) {
+  return java_lang_String::create_from_symbol(symbol, THREAD);
+}
+
+template <> inline oop VmIds::toString<oop>(Symbol* symbol, TRAPS) {
+  return toString<Handle>(symbol, THREAD)();
+}
+
+template <> inline jstring VmIds::toString<jstring>(Symbol* symbol, TRAPS) {
+  return (jstring)JNIHandles::make_local(toString<oop>(symbol, THREAD));
+}
+
+template <> inline jobject VmIds::toString<jobject>(Symbol* symbol, TRAPS) {
+  return JNIHandles::make_local(toString<oop>(symbol, THREAD));
+}
+
+inline Symbol* VmIds::toSymbol(jstring string) {
+  return java_lang_String::as_symbol(JNIHandles::resolve(string), Thread::current());
+}
+
+inline jlong VmIds::getBoxedLong(oop obj) {
+  assert(obj->is_oop(true), "cannot unbox null or non-oop");
+  return obj->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG));
+}
+
--- a/src/share/vm/interpreter/interpreter.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/interpreter/interpreter.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -367,6 +367,26 @@
   return Interpreter::deopt_entry(vtos, 0);
 }
 
+#ifdef GRAAL
+
+
+// If deoptimization happens, the interpreter should reexecute these bytecodes.
+// This function mainly helps the compilers to set up the reexecute bit.
+bool AbstractInterpreter::bytecode_should_reexecute(Bytecodes::Code code) {
+    switch (code) {
+  case Bytecodes::_invokedynamic:
+  case Bytecodes::_invokevirtual:
+  case Bytecodes::_invokeinterface:
+  case Bytecodes::_invokespecial:
+  case Bytecodes::_invokestatic:
+    return false;
+  default: 
+    return true;
+    }
+  return true;
+}
+#else 
+
 // If deoptimization happens, the interpreter should reexecute these bytecodes.
 // This function mainly helps the compilers to set up the reexecute bit.
 bool AbstractInterpreter::bytecode_should_reexecute(Bytecodes::Code code) {
@@ -415,6 +435,7 @@
       return false;
   }
 }
+#endif
 
 void AbstractInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
   // Quick & dirty stack overflow checking: bang the stack & handle trap.
--- a/src/share/vm/interpreter/interpreterRuntime.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -445,6 +445,18 @@
     }
   } while (should_repeat == true);
 
+  if (h_method->method_data() != NULL) {
+    ResourceMark rm(thread);
+    ProfileData* pdata = h_method->method_data()->allocate_bci_to_data(current_bci);
+    if (pdata != NULL) {
+      int tstate0 = pdata->trap_state();
+      int tstate1 = Deoptimization::trap_state_set_recompiled(tstate0, true);
+      if (tstate1 != tstate0) {
+        pdata->set_trap_state(tstate1);
+      }
+    }
+  }
+
   // notify JVMTI of an exception throw; JVMTI will detect if this is a first
   // time throw or a stack unwinding throw and accordingly notify the debugger
   if (JvmtiExport::can_post_on_exceptions()) {
--- a/src/share/vm/interpreter/rewriter.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/interpreter/rewriter.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -118,7 +118,11 @@
   while (!bcs.is_last_bytecode()) {
     Bytecodes::Code opcode = bcs.raw_next();
     switch (opcode) {
-      case Bytecodes::_return: *bcs.bcp() = Bytecodes::_return_register_finalizer; break;
+      case Bytecodes::_return:
+#ifndef GRAAL
+          *bcs.bcp() = Bytecodes::_return_register_finalizer;
+#endif
+        break;
 
       case Bytecodes::_istore:
       case Bytecodes::_lstore:
@@ -273,12 +277,14 @@
       switch (c) {
         case Bytecodes::_lookupswitch   : {
 #ifndef CC_INTERP
-          Bytecode_lookupswitch bc(method, bcp);
-          (*bcp) = (
-            bc.number_of_pairs() < BinarySwitchThreshold
-            ? Bytecodes::_fast_linearswitch
-            : Bytecodes::_fast_binaryswitch
-          );
+#ifndef GRAAL
+            Bytecode_lookupswitch bc(method, bcp);
+            (*bcp) = (
+              bc.number_of_pairs() < BinarySwitchThreshold
+              ? Bytecodes::_fast_linearswitch
+              : Bytecodes::_fast_binaryswitch
+            );
+#endif
 #endif
           break;
         }
--- a/src/share/vm/interpreter/templateTable.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/interpreter/templateTable.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -429,7 +429,8 @@
   def(Bytecodes::_jsr                 , ubcp|disp|____|____, vtos, vtos, jsr                 ,  _           ); // result is not an oop, so do not transition to atos
   def(Bytecodes::_ret                 , ubcp|disp|____|____, vtos, vtos, ret                 ,  _           );
   def(Bytecodes::_tableswitch         , ubcp|disp|____|____, itos, vtos, tableswitch         ,  _           );
-  def(Bytecodes::_lookupswitch        , ubcp|disp|____|____, itos, itos, lookupswitch        ,  _           );
+//  def(Bytecodes::_lookupswitch        , ubcp|disp|____|____, itos, itos, lookupswitch        ,  _           );
+  def(Bytecodes::_lookupswitch        , ubcp|disp|____|____, itos, vtos, fast_linearswitch   ,  _           );
   def(Bytecodes::_ireturn             , ____|disp|clvm|____, itos, itos, _return             , itos         );
   def(Bytecodes::_lreturn             , ____|disp|clvm|____, ltos, ltos, _return             , ltos         );
   def(Bytecodes::_freturn             , ____|disp|clvm|____, ftos, ftos, _return             , ftos         );
--- a/src/share/vm/memory/heap.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/memory/heap.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -127,7 +127,7 @@
   assert(_number_of_reserved_segments >= _number_of_committed_segments, "just checking");
 
   // reserve space for _segmap
-  if (!_segmap.initialize(align_to_page_size(_number_of_reserved_segments), align_to_page_size(_number_of_committed_segments))) {
+  if (!_segmap.initialize(align_to_allocation_size(_number_of_reserved_segments), align_to_allocation_size(_number_of_committed_segments))) {
     return false;
   }
   assert(_segmap.committed_size() >= (size_t) _number_of_committed_segments, "could not commit  enough space for segment map");
--- a/src/share/vm/oops/constantPoolOop.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/oops/constantPoolOop.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -346,6 +346,7 @@
   int cpc_index = operand;
   DEBUG_ONLY(cpc_index -= CPCACHE_INDEX_TAG);
   assert((int)(u2)cpc_index == cpc_index, "clean u2");
+  assert(cache() != NULL, "cache not null, maybe class is resolved but not rewritten yet");
   int member_index = cache()->entry_at(cpc_index)->constant_pool_index();
   return member_index;
 }
--- a/src/share/vm/oops/constantPoolOop.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/oops/constantPoolOop.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -704,8 +704,10 @@
   int       impl_klass_ref_index_at(int which, bool uncached);
   int       impl_name_and_type_ref_index_at(int which, bool uncached);
 
+  public:
   int remap_instruction_operand_from_cache(int operand);  // operand must be biased by CPCACHE_INDEX_TAG
 
+  private:
   // Used while constructing constant pool (only by ClassFileParser)
   jint klass_index_at(int which) {
     assert(tag_at(which).is_klass_index(), "Corrupted constant pool");
--- a/src/share/vm/oops/instanceKlass.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/oops/instanceKlass.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -2288,7 +2288,7 @@
 }
 
 // -----------------------------------------------------------------------------------------------------
-#ifndef PRODUCT
+
 
 // Printing
 
@@ -2358,7 +2358,7 @@
   }
 }
 
-#endif //PRODUCT
+
 
 void instanceKlass::oop_print_value_on(oop obj, outputStream* st) {
   st->print("a ");
--- a/src/share/vm/oops/instanceKlass.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/oops/instanceKlass.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -99,7 +99,7 @@
   virtual void do_field(fieldDescriptor* fd) = 0;
 };
 
-#ifndef PRODUCT
+//#ifndef PRODUCT
 // Print fields.
 // If "obj" argument to constructor is NULL, prints static fields, otherwise prints non-static fields.
 class FieldPrinter: public FieldClosure {
@@ -109,7 +109,7 @@
    FieldPrinter(outputStream* st, oop obj = NULL) : _obj(obj), _st(st) {}
    void do_field(fieldDescriptor* fd);
 };
-#endif  // !PRODUCT
+//#endif  // !PRODUCT
 
 // ValueObjs embedded in klass. Describes where oops are located in instances of
 // this klass.
@@ -646,7 +646,7 @@
   void process_interfaces(Thread *thread);
 
   // virtual operations from Klass
-  bool is_leaf_class() const               { return _subklass == NULL; }
+  bool is_leaf_class() const               { return _subklass == NULL && _nof_implementors == 0; }
   objArrayOop compute_secondary_supers(int num_extra_slots, TRAPS);
   bool compute_is_subtype_of(klassOop k);
   bool can_be_primary_super_slow() const;
@@ -844,12 +844,11 @@
  public:
   // Printing
   void oop_print_value_on(oop obj, outputStream* st);
-#ifndef PRODUCT
+
   void oop_print_on      (oop obj, outputStream* st);
 
   void print_dependent_nmethods(bool verbose = false);
   bool is_dependent_nmethod(nmethod* nm);
-#endif
 
   // Verification
   const char* internal_name() const;
--- a/src/share/vm/oops/klass.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/oops/klass.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -148,6 +148,7 @@
   }
 
   kl->set_java_mirror(NULL);
+  kl->set_graal_mirror(NULL);
   kl->set_modifier_flags(0);
   kl->set_layout_helper(Klass::_lh_neutral_value);
   kl->set_name(NULL);
--- a/src/share/vm/oops/klass.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/oops/klass.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -239,6 +239,8 @@
   klassOop    _primary_supers[_primary_super_limit];
   // java/lang/Class instance mirroring this class
   oop       _java_mirror;
+  // com/oracle/max/graal/hotspot/HotSpotTypeResolved mirroring this class
+  oop       _graal_mirror;
   // Superclass
   klassOop  _super;
   // First subclass (NULL if none); _subklass->next_sibling() is next one
@@ -337,6 +339,10 @@
   oop java_mirror() const              { return _java_mirror; }
   void set_java_mirror(oop m)          { oop_store((oop*) &_java_mirror, m); }
 
+  // graal mirror
+  oop graal_mirror() const               { return _graal_mirror; }
+  void set_graal_mirror(oop m)           { oop_store((oop*) &_graal_mirror, m); }
+
   // modifier flags
   jint modifier_flags() const          { return _modifier_flags; }
   void set_modifier_flags(jint flags)  { _modifier_flags = flags; }
@@ -365,6 +371,7 @@
   oop* adr_secondary_super_cache() const { return (oop*)&_secondary_super_cache; }
   oop* adr_secondary_supers()const { return (oop*)&_secondary_supers;  }
   oop* adr_java_mirror()     const { return (oop*)&_java_mirror;       }
+  oop* adr_graal_mirror()    const { return (oop*)&_graal_mirror;      }
   oop* adr_subklass()        const { return (oop*)&_subklass;          }
   oop* adr_next_sibling()    const { return (oop*)&_next_sibling;      }
 
@@ -385,6 +392,7 @@
   static ByteSize modifier_flags_offset()        { return in_ByteSize(sizeof(klassOopDesc) + offset_of(Klass, _modifier_flags)); }
   static ByteSize layout_helper_offset()         { return in_ByteSize(sizeof(klassOopDesc) + offset_of(Klass, _layout_helper)); }
   static ByteSize access_flags_offset()          { return in_ByteSize(sizeof(klassOopDesc) + offset_of(Klass, _access_flags)); }
+  static ByteSize graal_mirror_offset()          { return in_ByteSize(sizeof(klassOopDesc) + offset_of(Klass, _graal_mirror)); }
 
   // Unpacking layout_helper:
   enum {
--- a/src/share/vm/oops/klassKlass.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/oops/klassKlass.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -73,6 +73,7 @@
   MarkSweep::mark_and_push(k->adr_secondary_super_cache());
   MarkSweep::mark_and_push(k->adr_secondary_supers());
   MarkSweep::mark_and_push(k->adr_java_mirror());
+  MarkSweep::mark_and_push(k->adr_graal_mirror());
   // We follow the subklass and sibling links at the end of the
   // marking phase, since otherwise following them will prevent
   // class unloading (all classes are transitively linked from
@@ -92,6 +93,7 @@
   PSParallelCompact::mark_and_push(cm, k->adr_secondary_super_cache());
   PSParallelCompact::mark_and_push(cm, k->adr_secondary_supers());
   PSParallelCompact::mark_and_push(cm, k->adr_java_mirror());
+  PSParallelCompact::mark_and_push(cm, k->adr_graal_mirror());
   // We follow the subklass and sibling links at the end of the
   // marking phase, since otherwise following them will prevent
   // class unloading (all classes are transitively linked from
@@ -111,6 +113,7 @@
   blk->do_oop(k->adr_secondary_super_cache());
   blk->do_oop(k->adr_secondary_supers());
   blk->do_oop(k->adr_java_mirror());
+  blk->do_oop(k->adr_graal_mirror());
   // The following are in the perm gen and are treated
   // specially in a later phase of a perm gen collection; ...
   assert(oop(k)->is_perm(), "should be in perm");
@@ -144,6 +147,8 @@
   if (mr.contains(adr)) blk->do_oop(adr);
   adr = k->adr_java_mirror();
   if (mr.contains(adr)) blk->do_oop(adr);
+  adr = k->adr_graal_mirror();
+  if (mr.contains(adr)) blk->do_oop(adr);
   // The following are "weak links" in the perm gen and are
   // treated specially in a later phase of a perm gen collection.
   assert(oop(k)->is_perm(), "should be in perm");
@@ -172,6 +177,7 @@
   MarkSweep::adjust_pointer(k->adr_secondary_super_cache());
   MarkSweep::adjust_pointer(k->adr_secondary_supers());
   MarkSweep::adjust_pointer(k->adr_java_mirror());
+  MarkSweep::adjust_pointer(k->adr_graal_mirror());
   MarkSweep::adjust_pointer(k->adr_subklass());
   MarkSweep::adjust_pointer(k->adr_next_sibling());
   return size;
--- a/src/share/vm/oops/methodDataKlass.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/oops/methodDataKlass.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -35,6 +35,7 @@
 #include "oops/oop.inline2.hpp"
 #include "runtime/handles.inline.hpp"
 #ifndef SERIALGC
+#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
 #include "oops/oop.pcgc.inline.hpp"
 #endif
@@ -84,6 +85,7 @@
 
   obj->follow_header();
   MarkSweep::mark_and_push(m->adr_method());
+  MarkSweep::mark_and_push(m->adr_graal_mirror());
   ResourceMark rm;
   for (ProfileData* data = m->first_data();
        m->is_valid(data);
@@ -100,6 +102,7 @@
 
   obj->follow_header(cm);
   PSParallelCompact::mark_and_push(cm, m->adr_method());
+  PSParallelCompact::mark_and_push(cm, m->adr_graal_mirror());
   ResourceMark rm;
   for (ProfileData* data = m->first_data();
        m->is_valid(data);
@@ -119,6 +122,7 @@
 
   obj->oop_iterate_header(blk);
   blk->do_oop(m->adr_method());
+  blk->do_oop(m->adr_graal_mirror());
   ResourceMark rm;
   for (ProfileData* data = m->first_data();
        m->is_valid(data);
@@ -140,6 +144,11 @@
   if (mr.contains(adr)) {
     blk->do_oop(m->adr_method());
   }
+  adr = m->adr_graal_mirror();
+  if(mr.contains(adr)) {
+    blk->do_oop(m->adr_graal_mirror());
+  }
+
   ResourceMark rm;
   for (ProfileData* data = m->first_data();
        m->is_valid(data);
@@ -158,6 +167,7 @@
 
   obj->adjust_header();
   MarkSweep::adjust_pointer(m->adr_method());
+  MarkSweep::adjust_pointer(m->adr_graal_mirror());
   ResourceMark rm;
   ProfileData* data;
   for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) {
@@ -173,6 +183,11 @@
   methodDataOop m = methodDataOop(obj);
   // This should never point into the young gen.
   assert(!PSScavenge::should_scavenge(m->adr_method()), "Sanity");
+ 
+  oop* adr = m->adr_graal_mirror();
+  if(PSScavenge::should_scavenge(adr)) {
+    pm->claim_or_forward_depth(adr);
+  }
 }
 
 int methodDataKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
@@ -180,6 +195,7 @@
   methodDataOop m = methodDataOop(obj);
 
   PSParallelCompact::adjust_pointer(m->adr_method());
+  PSParallelCompact::adjust_pointer(m->adr_graal_mirror());
 
   ResourceMark rm;
   ProfileData* data;
--- a/src/share/vm/oops/methodDataOop.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/oops/methodDataOop.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -555,6 +555,14 @@
   return DataLayout::compute_size_in_bytes(cell_count);
 }
 
+#ifdef GRAAL
+int methodDataOopDesc::compute_extra_data_count(int data_size, int empty_bc_count) {
+  if (!ProfileTraps) return 0;
+
+  // Assume that up to 30% of the possibly trapping BCIs with no MDP will need to allocate one.
+  return MIN2(empty_bc_count, MAX2(4, (empty_bc_count * 30) / 100));
+}
+#else
 int methodDataOopDesc::compute_extra_data_count(int data_size, int empty_bc_count) {
   if (ProfileTraps) {
     // Assume that up to 3% of BCIs with no MDP will need to allocate one.
@@ -571,6 +579,7 @@
     return 0;
   }
 }
+#endif
 
 // Compute the size of the methodDataOop necessary to store
 // profiling information about a given method.  Size is in bytes.
@@ -582,7 +591,8 @@
   while ((c = stream.next()) >= 0) {
     int size_in_bytes = compute_data_size(&stream);
     data_size += size_in_bytes;
-    if (size_in_bytes == 0)  empty_bc_count += 1;
+
+    if (is_empty_data(size_in_bytes, c)) empty_bc_count++;
   }
   int object_size = in_bytes(data_offset()) + data_size;
 
@@ -590,9 +600,11 @@
   int extra_data_count = compute_extra_data_count(data_size, empty_bc_count);
   object_size += extra_data_count * DataLayout::compute_size_in_bytes(0);
 
+#ifndef GRAAL
   // Add a cell to record information about modified arguments.
   int arg_size = method->size_of_parameters();
   object_size += DataLayout::compute_size_in_bytes(arg_size+1);
+#endif
   return object_size;
 }
 
@@ -749,6 +761,7 @@
   ResourceMark rm;
   // Set the method back-pointer.
   _method = method();
+  _graal_mirror = NULL;
 
   if (TieredCompilation) {
     _invocation_counter.init();
@@ -780,7 +793,8 @@
   while ((c = stream.next()) >= 0) {
     int size_in_bytes = initialize_data(&stream, data_size);
     data_size += size_in_bytes;
-    if (size_in_bytes == 0)  empty_bc_count += 1;
+
+    if (is_empty_data(size_in_bytes, c)) empty_bc_count++;
   }
   _data_size = data_size;
   int object_size = in_bytes(data_offset()) + data_size;
@@ -788,7 +802,9 @@
   // Add some extra DataLayout cells (at least one) to track stray traps.
   int extra_data_count = compute_extra_data_count(data_size, empty_bc_count);
   int extra_size = extra_data_count * DataLayout::compute_size_in_bytes(0);
+  object_size += extra_size;
 
+#ifndef GRAAL
   // Add a cell to record information about modified arguments.
   // Set up _args_modified array after traps cells so that
   // the code for traps cells works.
@@ -797,7 +813,8 @@
   int arg_size = method->size_of_parameters();
   dp->initialize(DataLayout::arg_info_data_tag, 0, arg_size+1);
 
-  object_size += extra_size + DataLayout::compute_size_in_bytes(arg_size+1);
+  object_size += DataLayout::compute_size_in_bytes(arg_size+1);
+#endif
 
   // Set an initial hint. Don't use set_hint_di() because
   // first_di() may be out of bounds if data_size is 0.
@@ -810,6 +827,14 @@
   set_object_is_parsable(object_size);
 }
 
+bool methodDataOopDesc::is_empty_data(int size_in_bytes, Bytecodes::Code code) {
+#ifdef GRAAL
+  return size_in_bytes == 0 && Bytecodes::can_trap(code);
+#else
+  return size_in_bytes == 0;
+#endif
+}
+
 // Get a measure of how much mileage the method has on it.
 int methodDataOopDesc::mileage_of(methodOop method) {
   int mileage = 0;
--- a/src/share/vm/oops/methodDataOop.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/oops/methodDataOop.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -1194,6 +1194,9 @@
   // Back pointer to the methodOop
   methodOop _method;
 
+  // com/oracle/max/graal/hotspot/HotSpotProfilingInfo mirroring this method
+  oop               _graal_mirror;
+
   // Size of this oop in bytes
   int _size;
 
@@ -1383,6 +1386,7 @@
 
   bool is_mature() const;  // consult mileage and ProfileMaturityPercentage
   static int mileage_of(methodOop m);
+  static bool is_empty_data(int size, Bytecodes::Code code);
 
   // Support for interprocedural escape analysis, from Thomas Kotzmann.
   enum EscapeFlag {
@@ -1423,6 +1427,10 @@
   // Accessors
   methodOop method() { return _method; }
 
+  // graal mirror
+  oop graal_mirror() const               { return _graal_mirror; }
+  void set_graal_mirror(oop m)           { oop_store((oop*) &_graal_mirror, m); }
+
   // Get the data at an arbitrary (sort of) data index.
   ProfileData* data_at(int data_index);
 
@@ -1520,6 +1528,7 @@
 
   // GC support
   oop* adr_method() const { return (oop*)&_method; }
+  oop* adr_graal_mirror() const { return (oop*)&_graal_mirror; }
   bool object_is_parsable() const { return _size != 0; }
   void set_object_is_parsable(int object_size_in_bytes) { _size = object_size_in_bytes; }
 
--- a/src/share/vm/oops/methodKlass.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/oops/methodKlass.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -103,6 +103,7 @@
   m->invocation_counter()->init();
   m->backedge_counter()->init();
   m->clear_number_of_breakpoints();
+  m->set_graal_mirror(NULL);
 
 #ifdef TIERED
   m->set_rate(0);
@@ -128,6 +129,7 @@
   // know that Universe::methodKlassObj never moves.
   MarkSweep::mark_and_push(m->adr_constMethod());
   MarkSweep::mark_and_push(m->adr_constants());
+  MarkSweep::mark_and_push(m->adr_graal_mirror());
   if (m->method_data() != NULL) {
     MarkSweep::mark_and_push(m->adr_method_data());
   }
@@ -142,11 +144,10 @@
   // know that Universe::methodKlassObj never moves.
   PSParallelCompact::mark_and_push(cm, m->adr_constMethod());
   PSParallelCompact::mark_and_push(cm, m->adr_constants());
-#ifdef COMPILER2
+  PSParallelCompact::mark_and_push(cm, m->adr_graal_mirror());
   if (m->method_data() != NULL) {
     PSParallelCompact::mark_and_push(cm, m->adr_method_data());
   }
-#endif // COMPILER2
 }
 #endif // SERIALGC
 
@@ -160,6 +161,7 @@
   // know that Universe::methodKlassObj never moves
   blk->do_oop(m->adr_constMethod());
   blk->do_oop(m->adr_constants());
+  blk->do_oop(m->adr_graal_mirror());
   if (m->method_data() != NULL) {
     blk->do_oop(m->adr_method_data());
   }
@@ -180,6 +182,8 @@
   if (mr.contains(adr)) blk->do_oop(adr);
   adr = m->adr_constants();
   if (mr.contains(adr)) blk->do_oop(adr);
+  adr = m->adr_graal_mirror();
+  if (mr.contains(adr)) blk->do_oop(adr);
   if (m->method_data() != NULL) {
     adr = m->adr_method_data();
     if (mr.contains(adr)) blk->do_oop(adr);
@@ -198,6 +202,7 @@
   // know that Universe::methodKlassObj never moves.
   MarkSweep::adjust_pointer(m->adr_constMethod());
   MarkSweep::adjust_pointer(m->adr_constants());
+  MarkSweep::adjust_pointer(m->adr_graal_mirror());
   if (m->method_data() != NULL) {
     MarkSweep::adjust_pointer(m->adr_method_data());
   }
@@ -214,11 +219,10 @@
   methodOop m = methodOop(obj);
   PSParallelCompact::adjust_pointer(m->adr_constMethod());
   PSParallelCompact::adjust_pointer(m->adr_constants());
-#ifdef COMPILER2
+  PSParallelCompact::adjust_pointer(m->adr_graal_mirror());
   if (m->method_data() != NULL) {
     PSParallelCompact::adjust_pointer(m->adr_method_data());
   }
-#endif // COMPILER2
   return m->object_size();
 }
 #endif // SERIALGC
--- a/src/share/vm/oops/methodOop.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/oops/methodOop.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -207,6 +207,12 @@
 }
 
 address methodOopDesc::bcp_from(int bci) const {
+#ifdef ASSERT
+  if (!((is_native() && bci == 0)  || (!is_native() && 0 <= bci && bci < code_size()))) {
+    char buf[1024];
+    tty->print_cr("bci: %i, size: %i, method: %s", bci, code_size(), const_cast<methodOop>(this)->name_and_sig_as_C_string(buf, 1024));
+  }
+#endif // ASSERT
   assert((is_native() && bci == 0)  || (!is_native() && 0 <= bci && bci < code_size()), "illegal bci");
   address bcp = code_base() + bci;
   assert(is_native() && bcp == code_base() || contains(bcp), "bcp doesn't belong to this method");
--- a/src/share/vm/oops/methodOop.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/oops/methodOop.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -131,6 +131,8 @@
   InvocationCounter _invocation_counter;         // Incremented before each activation of the method - used to trigger frequency-based optimizations
   InvocationCounter _backedge_counter;           // Incremented before each backedge taken - used to trigger frequencey-based optimizations
 
+  // com/oracle/max/graal/hotspot/HotSpotMethodResolved mirroring this method
+  oop               _graal_mirror;
 #ifdef TIERED
   jlong             _prev_time;                   // Previous time the rate was acquired
   float             _rate;                        // Events (invocation and backedge counter increments) per millisecond
@@ -331,6 +333,10 @@
   int invocation_count();
   int backedge_count();
 
+  // graal mirror
+  oop graal_mirror() const               { return _graal_mirror; }
+  void set_graal_mirror(oop m)           { oop_store((oop*) &_graal_mirror, m); }
+
   bool was_executed_more_than(int n);
   bool was_never_executed()                      { return !was_executed_more_than(0); }
 
@@ -724,6 +730,7 @@
   // Garbage collection support
   oop*  adr_constMethod() const                  { return (oop*)&_constMethod;     }
   oop*  adr_constants() const                    { return (oop*)&_constants;       }
+  oop*  adr_graal_mirror() const                 { return (oop*)&_graal_mirror;    }
   oop*  adr_method_data() const                  { return (oop*)&_method_data;     }
 };
 
--- a/src/share/vm/opto/output.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/opto/output.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -944,7 +944,9 @@
     assert(jvms->bci() >= InvocationEntryBci && jvms->bci() <= 0x10000, "must be a valid or entry BCI");
     assert(!jvms->should_reexecute() || depth == max_depth, "reexecute allowed only for the youngest");
     // Now we can describe the scope.
-    debug_info()->describe_scope(safepoint_pc_offset, scope_method, jvms->bci(), jvms->should_reexecute(), is_method_handle_invoke, return_oop, locvals, expvals, monvals);
+    methodHandle null_mh;
+    bool rethrow_exception = false;
+    debug_info()->describe_scope(safepoint_pc_offset, null_mh, scope_method, jvms->bci(), jvms->should_reexecute(), rethrow_exception, is_method_handle_invoke, return_oop, locvals, expvals, monvals);
   } // End jvms loop
 
   // Mark the end of the scope set.
@@ -1027,7 +1029,8 @@
     JVMState* jvms = youngest_jvms->of_depth(depth);
     ciMethod* method = jvms->has_method() ? jvms->method() : NULL;
     assert(!jvms->should_reexecute() || depth==max_depth, "reexecute allowed only for the youngest");
-    debug_info->describe_scope(pc_offset, method, jvms->bci(), jvms->should_reexecute());
+    methodHandle null_mh;
+    debug_info->describe_scope(pc_offset, null_mh, method, jvms->bci(), jvms->should_reexecute());
   }
 
   // Mark the end of the scope set.
--- a/src/share/vm/prims/jni.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/prims/jni.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -29,6 +29,9 @@
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "interpreter/linkResolver.hpp"
+#ifdef GRAAL
+#include "graal/graalCompiler.hpp"
+#endif
 #ifndef SERIALGC
 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
 #endif // SERIALGC
@@ -5135,6 +5138,12 @@
     *vm = (JavaVM *)(&main_vm);
     *(JNIEnv**)penv = thread->jni_environment();
 
+#ifdef GRAAL
+      GraalCompiler* compiler = GraalCompiler::instance();
+      ciObjectFactory::initialize(); 
+      compiler->initialize();
+#endif
+
     // Tracks the time application was running before GC
     RuntimeService::record_application_start();
 
--- a/src/share/vm/prims/jvmtiCodeBlobEvents.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/prims/jvmtiCodeBlobEvents.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -251,7 +251,7 @@
 
     address scopes_data = nm->scopes_data_begin();
     for( pcd = nm->scopes_pcs_begin(); pcd < nm->scopes_pcs_end(); ++pcd ) {
-      ScopeDesc sc0(nm, pcd->scope_decode_offset(), pcd->should_reexecute(), pcd->return_oop());
+      ScopeDesc sc0(nm, pcd->scope_decode_offset(), pcd->should_reexecute(), pcd->rethrow_exception(), pcd->return_oop());
       ScopeDesc *sd  = &sc0;
       while( !sd->is_top() ) { sd = sd->sender(); }
       int bci = sd->bci();
--- a/src/share/vm/runtime/arguments.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/arguments.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -61,6 +61,10 @@
 int     Arguments::_num_jvm_flags               = 0;
 char**  Arguments::_jvm_args_array              = NULL;
 int     Arguments::_num_jvm_args                = 0;
+#ifdef GRAAL
+char**  Arguments::_graal_args_array              = NULL;
+int     Arguments::_num_graal_args                = 0;
+#endif
 char*  Arguments::_java_command                 = NULL;
 SystemProperty* Arguments::_system_properties   = NULL;
 const char*  Arguments::_gc_log_filename        = NULL;
@@ -98,6 +102,9 @@
 SystemProperty *Arguments::_java_home = NULL;
 SystemProperty *Arguments::_java_class_path = NULL;
 SystemProperty *Arguments::_sun_boot_class_path = NULL;
+#ifdef GRAAL
+SystemProperty *Arguments::_compiler_class_path = NULL;
+#endif
 
 char* Arguments::_meta_index_path = NULL;
 char* Arguments::_meta_index_dir = NULL;
@@ -159,6 +166,9 @@
   _java_library_path = new SystemProperty("java.library.path", NULL,  true);
   _java_home =  new SystemProperty("java.home", NULL,  true);
   _sun_boot_class_path = new SystemProperty("sun.boot.class.path", NULL,  true);
+#ifdef GRAAL
+  _compiler_class_path = new SystemProperty("compiler.class.path", NULL,  true);
+#endif
 
   _java_class_path = new SystemProperty("java.class.path", "",  true);
 
@@ -170,6 +180,9 @@
   PropertyList_add(&_system_properties, _java_home);
   PropertyList_add(&_system_properties, _java_class_path);
   PropertyList_add(&_system_properties, _sun_boot_class_path);
+#ifdef GRAAL
+  PropertyList_add(&_system_properties, _compiler_class_path);
+#endif
 
   // Set OS specific system properties values
   os::init_system_properties_values();
@@ -749,6 +762,11 @@
 void Arguments::build_jvm_flags(const char* arg) {
   add_string(&_jvm_flags_array, &_num_jvm_flags, arg);
 }
+#ifdef GRAAL
+void Arguments::add_graal_arg(const char* arg) {
+  add_string(&_graal_args_array, &_num_graal_args, arg);
+}
+#endif
 
 // utility function to return a string that concatenates all
 // strings in a given char** array
@@ -1929,6 +1947,19 @@
 
   status = status && verify_object_alignment();
 
+#ifdef GRAAL
+  if (UseCompressedOops) {
+    jio_fprintf(defaultStream::error_stream(),
+                    "CompressedOops are not supported in Graal at the moment\n");
+        status = false;
+  }
+  if (UseG1GC) {
+    jio_fprintf(defaultStream::error_stream(),
+                        "G1 is not supported in Graal at the moment\n");
+            status = false;
+  }
+#endif
+
   return status;
 }
 
@@ -2008,6 +2039,53 @@
 }
 
 // Parse JavaVMInitArgs structure
+#ifdef GRAAL
+static void prepend_to_graal_classpath(SysClassPath &cp, const char* graal_dir, const char* project) {
+  const int BUFFER_SIZE = 1024;
+  char path[BUFFER_SIZE];
+
+  const char fileSep = *os::file_separator();
+  sprintf(path, "%s%c%s%cbin", graal_dir, fileSep, project, fileSep);
+  DIR* dir = os::opendir(path);
+  if (dir == NULL) {
+    jio_fprintf(defaultStream::output_stream(), "Error while starting Graal VM: The Graal class directory %s could not be opened.\n", path);
+    vm_exit(1);
+  }
+  os::closedir(dir);
+  cp.add_prefix(path);
+}
+
+// Walk up the directory hierarchy starting from JAVA_HOME looking
+// for a directory named "graal". If found, then the full path to
+// this directory is returned in graal_dir.
+static bool find_graal_dir(char* graal_dir) {
+  strcpy(graal_dir, Arguments::get_java_home());
+  char* end = graal_dir + strlen(graal_dir);
+  const char fileSep = *os::file_separator();
+  while (end != graal_dir) {
+    if (fileSep == '/') 
+      strcat(graal_dir, "/graal");
+    else {
+      assert(fileSep == '\\', "unexpected separator char");
+      strcat(graal_dir, "\\graal");
+    }
+    DIR* dir = os::opendir(graal_dir);
+    if (dir != NULL) {
+      os::closedir(dir);
+      return true;
+    }
+    *end = 0;
+    while (end != graal_dir) {
+      if (*end == fileSep) {
+        *end = 0;
+        break;
+      }
+      end--;
+    }
+  }
+  return false;
+}
+#endif
 
 jint Arguments::parse_vm_init_args(const JavaVMInitArgs* args) {
   // For components of the system classpath.
@@ -2035,6 +2113,40 @@
     return result;
   }
 
+#ifdef GRAAL
+    if (PrintVMOptions) {
+      tty->print_cr("Running Graal VM... ");
+    }
+    const int BUFFER_SIZE = 1024;
+    char graal_dir[BUFFER_SIZE];
+    if (!os::getenv("GRAAL", graal_dir, sizeof(graal_dir))) {
+      if (find_graal_dir(graal_dir) == false) {
+        jio_fprintf(defaultStream::output_stream(), "Error while starting Graal VM: The GRAAL environment variable needs to point to the directory containing the Graal projects.\n");
+        vm_exit(0);
+      }
+    }
+    if (PrintVMOptions) tty->print_cr("GRAAL=%s", graal_dir);
+    
+    SysClassPath scp_compiler(Arguments::get_sysclasspath());
+    struct dirent* dentry;
+    char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(graal_dir));
+    errno = 0;
+    DIR* graal_dir_handle = os::opendir(graal_dir);
+    while ((dentry = os::readdir(graal_dir_handle, (struct dirent *)tdbuf)) != NULL) {
+      if (strcmp(dentry->d_name, ".") != 0 && strcmp(dentry->d_name, "..") != 0 && strcmp(dentry->d_name, "com.oracle.max.graal.tests") != 0 && strcmp(dentry->d_name, "com.oracle.max.graal.jtt") != 0) {
+        prepend_to_graal_classpath(scp_compiler, graal_dir, dentry->d_name);
+        if (PrintVMOptions) {
+          tty->print_cr("Adding project directory %s to bootclasspath", dentry->d_name);
+        }
+      }
+    }
+    os::closedir(graal_dir_handle);
+    FREE_C_HEAP_ARRAY(char, tdbuf);
+    scp_compiler.expand_endorsed();
+
+    Arguments::set_compilerclasspath(scp_compiler.combined_path());
+#endif
+
   if (AggressiveOpts) {
     // Insert alt-rt.jar between user-specified bootclasspath
     // prefix and the default bootclasspath.  os::set_boot_path()
@@ -2695,8 +2807,19 @@
           return JNI_EINVAL;
         }
       }
+    }
+#ifdef GRAAL
+    else if (match_option(option, "-G:", &tail)) { // -G:XXX
+      // Option for the graal compiler.
+      if (PrintVMOptions) {
+        tty->print_cr("graal option %s", tail);
+      }
+      Arguments::add_graal_arg(tail);
+
     // Unknown option
-    } else if (is_bad_option(option, args->ignoreUnrecognized)) {
+    }
+#endif
+    else if (is_bad_option(option, args->ignoreUnrecognized)) {
       return JNI_ERR;
     }
   }
--- a/src/share/vm/runtime/arguments.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/arguments.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -228,6 +228,11 @@
   // an array containing all jvm arguments specified in the command line
   static char** _jvm_args_array;
   static int    _num_jvm_args;
+#ifdef GRAAL
+  // an array containing all graal arguments specified in the command line
+  static char** _graal_args_array;
+  static int    _num_graal_args;
+#endif
   // string containing all java command (class/jarfile name and app args)
   static char* _java_command;
 
@@ -242,6 +247,9 @@
   static SystemProperty *_java_home;
   static SystemProperty *_java_class_path;
   static SystemProperty *_sun_boot_class_path;
+#ifdef GRAAL
+  static SystemProperty *_compiler_class_path;
+#endif
 
   // Meta-index for knowing what packages are in the boot class path
   static char* _meta_index_path;
@@ -366,6 +374,9 @@
   // methods to build strings from individual args
   static void build_jvm_args(const char* arg);
   static void build_jvm_flags(const char* arg);
+#ifdef GRAAL
+  static void add_graal_arg(const char* arg);
+#endif
   static void add_string(char*** bldarray, int* count, const char* arg);
   static const char* build_resource_string(char** args, int count);
 
@@ -421,6 +432,10 @@
   // return a char* array containing all options
   static char** jvm_flags_array()          { return _jvm_flags_array; }
   static char** jvm_args_array()           { return _jvm_args_array; }
+#ifdef GRAAL
+  static char** graal_args_array()           { return _graal_args_array; }
+  static int num_graal_args()               { return _num_graal_args; }
+#endif
   static int num_jvm_flags()               { return _num_jvm_flags; }
   static int num_jvm_args()                { return _num_jvm_args; }
   // return the arguments passed to the Java application
@@ -519,6 +534,9 @@
   static void set_ext_dirs(char *value) { _java_ext_dirs->set_value(value); }
   static void set_endorsed_dirs(char *value) { _java_endorsed_dirs->set_value(value); }
   static void set_sysclasspath(char *value) { _sun_boot_class_path->set_value(value); }
+#ifdef GRAAL
+  static void set_compilerclasspath(char *value) { _compiler_class_path->set_value(value); }
+#endif
   static void append_sysclasspath(const char *value) { _sun_boot_class_path->append_value(value); }
   static void set_meta_index_path(char* meta_index_path, char* meta_index_dir) {
     _meta_index_path = meta_index_path;
@@ -529,6 +547,9 @@
   static char *get_dll_dir() { return _sun_boot_library_path->value(); }
   static char *get_endorsed_dir() { return _java_endorsed_dirs->value(); }
   static char *get_sysclasspath() { return _sun_boot_class_path->value(); }
+#ifdef GRAAL
+  static char *get_compilerclasspath() { return _compiler_class_path->value(); }
+#endif
   static char* get_meta_index_path() { return _meta_index_path; }
   static char* get_meta_index_dir()  { return _meta_index_dir;  }
 
--- a/src/share/vm/runtime/basicLock.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/basicLock.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -63,6 +63,7 @@
  public:
   // Manipulation
   oop      obj() const                                { return _obj;  }
+  oop*     obj_addr()                                 { return &_obj; }
   void set_obj(oop obj)                               { _obj = obj; }
   BasicLock* lock()                                   { return &_lock; }
 
--- a/src/share/vm/runtime/compilationPolicy.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/compilationPolicy.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -60,11 +60,11 @@
     break;
 
   case 1:
-#ifdef COMPILER2
+//#ifdef COMPILER2
     CompilationPolicy::set_policy(new StackWalkCompPolicy());
-#else
-    Unimplemented();
-#endif
+//#else
+//    Unimplemented();
+//#endif
     break;
   case 2:
 #ifdef TIERED
@@ -420,7 +420,7 @@
 }
 // StackWalkCompPolicy - walk up stack to find a suitable method to compile
 
-#ifdef COMPILER2
+//#ifdef COMPILER2
 const char* StackWalkCompPolicy::_msg = NULL;
 
 
@@ -646,4 +646,4 @@
 
 
 
-#endif // COMPILER2
+//#endif // COMPILER2
--- a/src/share/vm/runtime/compilationPolicy.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/compilationPolicy.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -118,7 +118,7 @@
 
 // StackWalkCompPolicy - existing C2 policy
 
-#ifdef COMPILER2
+//#ifdef COMPILER2
 class StackWalkCompPolicy : public NonTieredCompPolicy {
  public:
   virtual void method_invocation_event(methodHandle m, JavaThread* thread);
@@ -138,6 +138,6 @@
   // negative filter: should send NOT be inlined?  returns NULL (--> inline) or rejection msg
 
 };
-#endif
+//#endif
 
 #endif // SHARE_VM_RUNTIME_COMPILATIONPOLICY_HPP
--- a/src/share/vm/runtime/deoptimization.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/deoptimization.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -19,7 +19,6 @@
  * 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.
- *
  */
 
 #include "precompiled.hpp"
@@ -163,8 +162,10 @@
   // handler. Note this fact before we start generating temporary frames
   // that can confuse an asynchronous stack walker. This counter is
   // decremented at the end of unpack_frames().
+  if (TraceDeoptimization) {
+    tty->print("Deoptimization "); 
+  }
   thread->inc_in_deopt_handler();
-
   return fetch_unroll_info_helper(thread);
 JRT_END
 
@@ -208,11 +209,14 @@
   assert(vf->is_compiled_frame(), "Wrong frame type");
   chunk->push(compiledVFrame::cast(vf));
 
-#ifdef COMPILER2
+  // TODO(tw): Fix this hack after introducing GRAAL macro.
+#if defined(COMPILER2) || defined(GRAAL)
   // Reallocate the non-escaping objects and restore their fields. Then
   // relock objects if synchronization on them was eliminated.
+#ifdef COMPILER2
   if (DoEscapeAnalysis || EliminateNestedLocks) {
     if (EliminateAllocations) {
+#endif // COMPILER2
       assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames");
       GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects();
 
@@ -232,7 +236,7 @@
         assert(result == NULL || result->is_oop(), "must be oop");
         return_value = Handle(thread, result);
         assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
-        if (TraceDeoptimization) {
+        if (PrintDeoptimizationDetails) {
           tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, result, thread);
         }
       }
@@ -245,19 +249,21 @@
       if (reallocated) {
         reassign_fields(&deoptee, &map, objects);
 #ifndef PRODUCT
-        if (TraceDeoptimization) {
+        if (PrintDeoptimizationDetails) {
           ttyLocker ttyl;
           tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, thread);
           print_objects(objects);
         }
-#endif
+#endif // !PRODUCT
       }
       if (save_oop_result) {
         // Restore result.
         deoptee.set_saved_oop_result(&map, return_value());
       }
+#ifdef COMPILER2
     }
     if (EliminateLocks) {
+#endif // COMPILER2
 #ifndef PRODUCT
       bool first = true;
 #endif
@@ -268,7 +274,7 @@
         if (monitors->is_nonempty()) {
           relock_objects(monitors, thread);
 #ifndef PRODUCT
-          if (TraceDeoptimization) {
+          if (PrintDeoptimizationDetails) {
             ttyLocker ttyl;
             for (int j = 0; j < monitors->length(); j++) {
               MonitorInfo* mi = monitors->at(j);
@@ -281,12 +287,15 @@
               }
             }
           }
-#endif
+#endif // !PRODUCT
         }
       }
+#ifdef COMPILER2
     }
   }
 #endif // COMPILER2
+#endif // COMPILER2 || GRAAL
+
   // Ensure that no safepoint is taken after pointers have been stored
   // in fields of rematerialized objects.  If a safepoint occurs from here on
   // out the java state residing in the vframeArray will be missed.
@@ -492,7 +501,7 @@
   info->set_initial_info((intptr_t) array->sender().initial_deoptimization_info());
 
   if (array->frames() > 1) {
-    if (VerifyStack && TraceDeoptimization) {
+    if (PrintDeoptimizationDetails) {
       tty->print_cr("Deoptimizing method containing inlining");
     }
   }
@@ -572,7 +581,7 @@
   vframeArray* array = thread->vframe_array_head();
 
 #ifndef PRODUCT
-  if (TraceDeoptimization) {
+  if (PrintDeoptimizationDetails) {
     tty->print_cr("DEOPT UNPACKING thread " INTPTR_FORMAT " vframeArray " INTPTR_FORMAT " mode %d", thread, array, exec_mode);
   }
 #endif
@@ -737,7 +746,7 @@
 }
 
 
-#ifdef COMPILER2
+//#ifdef COMPILER2
 bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS) {
   Handle pending_exception(thread->pending_exception());
   const char* exception_file = thread->exception_file();
@@ -917,6 +926,9 @@
     KlassHandle k(((ConstantOopReadValue*) sv->klass())->value()());
     Handle obj = sv->value();
     assert(obj.not_null(), "reallocation was missed");
+    if (PrintDeoptimizationDetails) {
+      tty->print_cr("reassign fields for object of type %s!", k->name()->as_C_string());
+    }
 
     if (k->oop_is_instance()) {
       instanceKlass* ik = instanceKlass::cast(k());
@@ -979,13 +991,13 @@
   }
 }
 #endif
-#endif // COMPILER2
+//#endif // COMPILER2
 
 vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk) {
   Events::log(thread, "DEOPT PACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT, fr.pc(), fr.sp());
 
 #ifndef PRODUCT
-  if (TraceDeoptimization) {
+  if (PrintDeoptimizationDetails) {
     ttyLocker ttyl;
     tty->print("DEOPT PACKING thread " INTPTR_FORMAT " ", thread);
     fr.print_on(tty);
@@ -1030,7 +1042,7 @@
   assert(array->structural_compare(thread, chunk), "just checking");
 
 #ifndef PRODUCT
-  if (TraceDeoptimization) {
+  if (PrintDeoptimizationDetails) {
     ttyLocker ttyl;
     tty->print_cr("     Created vframeArray " INTPTR_FORMAT, array);
   }
@@ -1178,7 +1190,6 @@
 JRT_END
 
 
-#if defined(COMPILER2) || defined(SHARK)
 void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) {
   // in case of an unresolved klass entry, load the class.
   if (constant_pool->tag_at(index).is_unresolved_klass()) {
@@ -1258,10 +1269,38 @@
     nmethod* nm = cvf->code();
 
     ScopeDesc*      trap_scope  = cvf->scope();
+    
+    if (TraceDeoptimization) {
+      tty->print_cr("  bci=%d pc=%d, relative_pc=%d, method=%s", trap_scope->bci(), fr.pc(), fr.pc() - nm->code_begin(), trap_scope->method()->name()->as_C_string());
+      if (thread->graal_deopt_info() != NULL) {
+        oop deopt_info = thread->graal_deopt_info();
+        if (java_lang_String::is_instance(deopt_info)) {
+          char buf[1024];
+          java_lang_String::as_utf8_string(deopt_info, buf, 1024);
+          tty->print_cr("deopt info: %s", buf);
+        } else {
+          tty->print_cr("deopt info:");
+          deopt_info->print();
+        }
+        thread->set_graal_deopt_info(NULL);
+      }
+    }
+
     methodHandle    trap_method = trap_scope->method();
     int             trap_bci    = trap_scope->bci();
     Bytecodes::Code trap_bc     = trap_method->java_code_at(trap_bci);
 
+    if (trap_scope->rethrow_exception()) {
+      if (PrintDeoptimizationDetails) {
+        tty->print_cr("Exception to be rethrown in the interpreter for method %s::%s at bci %d", instanceKlass::cast(trap_method->method_holder())->name()->as_C_string(), trap_method->name()->as_C_string(), trap_bci);
+      }
+      GrowableArray<ScopeValue*>* expressions = trap_scope->expressions();
+      guarantee(expressions != NULL, "must have exception to throw");
+      ScopeValue* topOfStack = expressions->top();
+      Handle topOfStackObj = cvf->create_stack_value(topOfStack)->get_obj();
+      THREAD->set_pending_exception(topOfStackObj(), NULL, 0);
+    }
+    
     // Record this event in the histogram.
     gather_statistics(reason, action, trap_bc);
 
@@ -1666,7 +1705,9 @@
 }
 
 Deoptimization::UnrollBlock* Deoptimization::uncommon_trap(JavaThread* thread, jint trap_request) {
-
+  if (TraceDeoptimization) {
+    tty->print("Uncommon trap "); 
+  }
   // Still in Java no safepoints
   {
     // This enters VM and may safepoint
@@ -1923,40 +1964,3 @@
     if (xtty != NULL)  xtty->tail("statistics");
   }
 }
-#else // COMPILER2 || SHARK
-
-
-// Stubs for C1 only system.
-bool Deoptimization::trap_state_is_recompiled(int trap_state) {
-  return false;
-}
-
-const char* Deoptimization::trap_reason_name(int reason) {
-  return "unknown";
-}
-
-void Deoptimization::print_statistics() {
-  // no output
-}
-
-void
-Deoptimization::update_method_data_from_interpreter(methodDataHandle trap_mdo, int trap_bci, int reason) {
-  // no udpate
-}
-
-int Deoptimization::trap_state_has_reason(int trap_state, int reason) {
-  return 0;
-}
-
-void Deoptimization::gather_statistics(DeoptReason reason, DeoptAction action,
-                                       Bytecodes::Code bc) {
-  // no update
-}
-
-const char* Deoptimization::format_trap_state(char* buf, size_t buflen,
-                                              int trap_state) {
-  jio_snprintf(buf, buflen, "#%d", trap_state);
-  return buf;
-}
-
-#endif // COMPILER2 || SHARK
--- a/src/share/vm/runtime/deoptimization.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/deoptimization.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -112,7 +112,7 @@
   // executing in a particular CodeBlob if UseBiasedLocking is enabled
   static void revoke_biases_of_monitors(CodeBlob* cb);
 
-#ifdef COMPILER2
+//#ifdef COMPILER2
   // Support for restoring non-escaping objects
   static bool realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS);
   static void reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type);
@@ -120,7 +120,7 @@
   static void reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects);
   static void relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread);
   NOT_PRODUCT(static void print_objects(GrowableArray<ScopeValue*>* objects);)
-#endif // COMPILER2
+//#endif // COMPILER2
 
   public:
   static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk);
--- a/src/share/vm/runtime/fieldDescriptor.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/fieldDescriptor.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -61,6 +61,7 @@
   Symbol* signature() const {
     return field()->signature(_cp);
   }
+  int signature_index() const          { return field()->signature_index(); }
   klassOop field_holder() const        { return _cp->pool_holder(); }
   constantPoolOop constants() const    { return _cp(); }
   AccessFlags access_flags() const     { return _access_flags; }
--- a/src/share/vm/runtime/frame.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/frame.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -604,44 +604,65 @@
 void frame::interpreter_frame_print_on(outputStream* st) const {
 #ifndef PRODUCT
   assert(is_interpreted_frame(), "Not an interpreted frame");
+  assert(interpreter_frame_method() != NULL && interpreter_frame_method()->contains(interpreter_frame_bcp()), "must be");
   jint i;
-  for (i = 0; i < interpreter_frame_method()->max_locals(); i++ ) {
-    intptr_t x = *interpreter_frame_local_at(i);
-    st->print(" - local  [" INTPTR_FORMAT "]", x);
-    st->fill_to(23);
-    st->print_cr("; #%d", i);
-  }
+  st->print_cr(" - sp                                  = " INTPTR_FORMAT, sp());
+  // expressions
   for (i = interpreter_frame_expression_stack_size() - 1; i >= 0; --i ) {
-    intptr_t x = *interpreter_frame_expression_stack_at(i);
-    st->print(" - stack  [" INTPTR_FORMAT "]", x);
-    st->fill_to(23);
+    intptr_t* x = interpreter_frame_expression_stack_at(i);
+    st->print(" - stack         at " INTPTR_FORMAT " = " INTPTR_FORMAT, x, *x);
+    st->fill_to(70);
     st->print_cr("; #%d", i);
   }
   // locks for synchronization
+  st->print_cr(" - monitorend                          = " INTPTR_FORMAT, interpreter_frame_monitor_end());
   for (BasicObjectLock* current = interpreter_frame_monitor_end();
        current < interpreter_frame_monitor_begin();
        current = next_monitor_in_interpreter_frame(current)) {
-    st->print(" - obj    [");
+    st->print (" - lock          at " INTPTR_FORMAT " = ", current->lock());
+    current->lock()->print_on(st);
+    st->cr();
+    st->print (" - obj           at " INTPTR_FORMAT " = " INTPTR_FORMAT " ", current->obj_addr(), *current->obj_addr());
     current->obj()->print_value_on(st);
-    st->print_cr("]");
-    st->print(" - lock   [");
-    current->lock()->print_on(st);
-    st->print_cr("]");
+    st->cr();
   }
-  // monitor
-  st->print_cr(" - monitor[" INTPTR_FORMAT "]", interpreter_frame_monitor_begin());
-  // bcp
-  st->print(" - bcp    [" INTPTR_FORMAT "]", interpreter_frame_bcp());
-  st->fill_to(23);
-  st->print_cr("; @%d", interpreter_frame_bci());
+  st->print_cr(" - monitorbegin                        = " INTPTR_FORMAT, interpreter_frame_monitor_begin());
+  
+  // bcp/bcx
+  st->print   (" - bcp           at " INTPTR_FORMAT " = " INTPTR_FORMAT, interpreter_frame_bcx_addr(), interpreter_frame_bcp());
+  st->fill_to(70);
+  st->print_cr("; @%d - %s", interpreter_frame_bci(), Bytecodes::name(interpreter_frame_method()->code_at(interpreter_frame_bci())));
   // locals
-  st->print_cr(" - locals [" INTPTR_FORMAT "]", interpreter_frame_local_at(0));
+  st->print_cr(" - locals        at " INTPTR_FORMAT " = " INTPTR_FORMAT, interpreter_frame_locals_addr(), *interpreter_frame_locals_addr());
+  // constant pool cache
+  st->print_cr(" - constant pool at " INTPTR_FORMAT " = " INTPTR_FORMAT, interpreter_frame_cache_addr(), *interpreter_frame_cache_addr());
+  // method data
+  st->print_cr(" - method data   at " INTPTR_FORMAT " = " INTPTR_FORMAT, interpreter_frame_mdx_addr(), *interpreter_frame_mdx_addr());
   // method
-  st->print(" - method [" INTPTR_FORMAT "]", (address)interpreter_frame_method());
-  st->fill_to(23);
+  st->print   (" - method        at " INTPTR_FORMAT " = " INTPTR_FORMAT, interpreter_frame_method_addr(), *interpreter_frame_method_addr());
+  st->fill_to(70);
   st->print("; ");
   interpreter_frame_method()->print_name(st);
   st->cr();
+  // last sp
+  st->print_cr(" - last sp       at " INTPTR_FORMAT " = " INTPTR_FORMAT, interpreter_frame_last_sp_addr(), *interpreter_frame_last_sp_addr());
+  // sender sp
+  st->print_cr(" - sender sp     at " INTPTR_FORMAT " = " INTPTR_FORMAT, interpreter_frame_sender_sp_addr(), *interpreter_frame_sender_sp_addr());
+  // old fp
+  st->print_cr(" - old fp        at " INTPTR_FORMAT " = " INTPTR_FORMAT, link_addr(), *link_addr());
+  // return address
+  st->print_cr(" - return pc     at " INTPTR_FORMAT " = " INTPTR_FORMAT, sender_pc_addr(), *sender_pc_addr());
+
+  // locals
+  for (i = interpreter_frame_method()->max_locals() - 1; i >= 0; i--) {
+    intptr_t* x = interpreter_frame_local_at(i);
+    st->print (" - local         at " INTPTR_FORMAT " = " INTPTR_FORMAT, x, *x);
+    st->fill_to(70);
+    st->print_cr("; #%d", i);
+  }
+
+  // fp
+  st->print_cr(" - fp                                  = " INTPTR_FORMAT, fp());
 #endif
 }
 
--- a/src/share/vm/runtime/frame.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/frame.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -206,6 +206,7 @@
  public:
   // Link (i.e., the pointer to the previous frame)
   intptr_t* link() const;
+  intptr_t** link_addr() const;
   void set_link(intptr_t* addr);
 
   // Return address
@@ -305,6 +306,7 @@
   jint  interpreter_frame_expression_stack_size() const;
 
   intptr_t* interpreter_frame_sender_sp() const;
+  intptr_t** interpreter_frame_sender_sp_addr() const;
 
 #ifndef CC_INTERP
   // template based interpreter deoptimization support
--- a/src/share/vm/runtime/globals.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/globals.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -674,7 +674,7 @@
   develop(bool, TraceCallFixup, false,                                      \
           "traces all call fixups")                                         \
                                                                             \
-  develop(bool, DeoptimizeALot, false,                                      \
+  product(bool, DeoptimizeALot, false,                                      \
           "deoptimize at every exit from the runtime system")               \
                                                                             \
   notproduct(ccstrlist, DeoptimizeOnlyAt, "",                               \
@@ -937,6 +937,9 @@
   diagnostic(ccstr, PrintAssemblyOptions, NULL,                             \
           "Options string passed to disassembler.so")                       \
                                                                             \
+  product(bool, PrintNMethodStatistics, false,                              \
+          "Print a summary statistic for the generated nmethods")           \
+                                                                            \
   diagnostic(bool, PrintNMethods, false,                                    \
           "Print assembly code for nmethods when generated")                \
                                                                             \
@@ -1328,7 +1331,7 @@
   develop(bool, TraceClassInitialization, false,                            \
           "Trace class initialization")                                     \
                                                                             \
-  develop(bool, TraceExceptions, false,                                     \
+  product(bool, TraceExceptions, false,                                     \
           "Trace exceptions")                                               \
                                                                             \
   develop(bool, TraceICs, false,                                            \
@@ -2988,9 +2991,12 @@
           "Distance to prefetch destination array in arracopy")             \
                                                                             \
   /* deoptimization */                                                      \
-  develop(bool, TraceDeoptimization, false,                                 \
+  product(bool, TraceDeoptimization, false,                                 \
           "Trace deoptimization")                                           \
                                                                             \
+  product(bool, PrintDeoptimizationDetails, false,                          \
+          "Print more information about deoptimization")                    \
+                                                                            \
   develop(bool, DebugDeoptimization, false,                                 \
           "Tracing various information while debugging deoptimization")     \
                                                                             \
@@ -3142,7 +3148,7 @@
           "if non-zero, start verifying C heap after Nth call to "          \
           "malloc/realloc/free")                                            \
                                                                             \
-  product(intx, TypeProfileWidth,     2,                                   \
+  product_pd(intx, TypeProfileWidth,                                        \
           "number of receiver types to record in call/cast profile")        \
                                                                             \
   develop(intx, BciProfileWidth,      2,                                    \
@@ -3823,7 +3829,7 @@
           "Skip assert() and verify() which page-in unwanted shared "       \
           "objects. ")                                                      \
                                                                             \
-  diagnostic(bool, EnableInvokeDynamic, true,                               \
+  diagnostic(bool, EnableInvokeDynamic, false,                              \
           "support JSR 292 (method handles, invokedynamic, "                \
           "anonymous classes")                                              \
                                                                             \
--- a/src/share/vm/runtime/java.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/java.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -30,6 +30,9 @@
 #include "compiler/compileBroker.hpp"
 #include "compiler/compilerOracle.hpp"
 #include "interpreter/bytecodeHistogram.hpp"
+#ifdef GRAAL
+#include "graal/graalCompiler.hpp"
+#endif
 #include "memory/genCollectedHeap.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/universe.hpp"
@@ -251,9 +254,12 @@
     Runtime1::print_statistics();
     Deoptimization::print_statistics();
     SharedRuntime::print_statistics();
+  }
+#endif /* COMPILER1 */
+
+  if(PrintNMethodStatistics) {
     nmethod::print_statistics();
   }
-#endif /* COMPILER1 */
 
 #ifdef COMPILER2
   if ((PrintOptoStatistics || LogVMOutput || LogCompilation) && UseCompiler) {
@@ -365,6 +371,9 @@
   if (CITime) {
     CompileBroker::print_times();
   }
+  if(PrintNMethodStatistics) {
+    nmethod::print_statistics();
+  }
 #ifdef COMPILER2
   if (PrintPreciseBiasedLockingStatistics) {
     OptoRuntime::print_named_counters();
@@ -426,6 +435,10 @@
   #define BEFORE_EXIT_DONE    2
   static jint volatile _before_exit_status = BEFORE_EXIT_NOT_RUN;
 
+#ifdef GRAAL
+  GraalCompiler::instance()->exit();
+#endif
+
   // Note: don't use a Mutex to guard the entire before_exit(), as
   // JVMTI post_thread_end_event and post_vm_death_event will run native code.
   // A CAS or OSMutex would work just fine but then we need to manipulate
--- a/src/share/vm/runtime/javaCalls.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/javaCalls.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -61,7 +61,8 @@
 
   guarantee(thread->is_Java_thread(), "crucial check - the VM thread cannot and must not escape to Java code");
   assert(!thread->owns_locks(), "must release all locks when leaving VM");
-  guarantee(!thread->is_Compiler_thread(), "cannot make java calls from the compiler");
+  // (tw) may we do this?
+  // guarantee(!thread->is_Compiler_thread(), "cannot make java calls from the compiler");
   _result   = result;
 
   // Allocate handle block for Java code. This must be done before we change thread_state to _thread_in_Java_or_stub,
@@ -201,6 +202,23 @@
   }
 }
 
+// ============ Interface calls ============
+
+void JavaCalls::call_interface(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
+  CallInfo callinfo;
+  Handle receiver = args->receiver();
+  KlassHandle recvrKlass(THREAD, receiver.is_null() ? (klassOop)NULL : receiver->klass());
+  LinkResolver::resolve_interface_call(
+          callinfo, receiver, recvrKlass, spec_klass, name, signature,
+          KlassHandle(), false, true, CHECK);
+  methodHandle method = callinfo.selected_method();
+  assert(method.not_null(), "should have thrown exception");
+
+  // Invoke the method
+  JavaCalls::call(result, method, args, CHECK);
+}
+
+
 // ============ Virtual calls ============
 
 void JavaCalls::call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
@@ -355,7 +373,8 @@
 #endif
 
 
-  assert(!thread->is_Compiler_thread(), "cannot compile from the compiler");
+  // (tw) may we do this?
+  //assert(!thread->is_Compiler_thread(), "cannot compile from the compiler");
   if (CompilationPolicy::must_be_compiled(method)) {
     CompileBroker::compile_method(method, InvocationEntryBci,
                                   CompilationPolicy::policy()->initial_compile_level(),
--- a/src/share/vm/runtime/javaCalls.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/javaCalls.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -204,6 +204,12 @@
   static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS);
   static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS);
 
+  // interface call
+  // ------------
+
+  // The receiver must be first oop in argument list
+  static void call_interface(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS);
+
   // virtual call
   // ------------
 
--- a/src/share/vm/runtime/reflectionUtils.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/reflectionUtils.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -26,6 +26,9 @@
 #include "classfile/javaClasses.hpp"
 #include "memory/universe.inline.hpp"
 #include "runtime/reflectionUtils.hpp"
+#ifdef GRAAL
+#include "graal/graalJavaAccess.hpp"
+#endif
 
 KlassStream::KlassStream(instanceKlassHandle klass, bool local_only, bool classes_only) {
   _klass = klass;
@@ -75,6 +78,12 @@
     offset = sun_reflect_UnsafeStaticFieldAccessorImpl::base_offset();
     _filtered_fields->append(new FilteredField(SystemDictionary::reflect_UnsafeStaticFieldAccessorImpl_klass(), offset));
   }
+#ifdef GRAAL
+  compute_offset(offset, SystemDictionary::HotSpotMethodResolved_klass(), "javaMirror", "Ljava/lang/Object;", false);
+  _filtered_fields->append(new FilteredField(SystemDictionary::HotSpotMethodResolved_klass(), offset));
+  compute_offset(offset, SystemDictionary::HotSpotMethodData_klass(), "hotspotMirror", "Ljava/lang/Object;", false);
+  _filtered_fields->append(new FilteredField(SystemDictionary::HotSpotMethodData_klass(), offset));
+#endif
 }
 
 int FilteredFieldStream::field_count() {
--- a/src/share/vm/runtime/rframe.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/rframe.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -152,11 +152,11 @@
 
 void RFrame::print(const char* kind) {
 #ifndef PRODUCT
-#ifdef COMPILER2
+//#ifdef COMPILER2
   int cnt = top_method()->interpreter_invocation_count();
-#else
-  int cnt = top_method()->invocation_count();
-#endif
+//#else
+//  int cnt = top_method()->invocation_count();
+//#endif
   tty->print("%3d %s ", _num, is_interpreted() ? "I" : "C");
   top_method()->print_short_name(tty);
   tty->print_cr(": inv=%5d(%d) cst=%4d", _invocations, cnt, cost());
--- a/src/share/vm/runtime/sharedRuntime.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -651,6 +651,26 @@
   assert(nm != NULL, "must exist");
   ResourceMark rm;
 
+#ifdef GRAAL
+  // lookup exception handler for this pc
+  int catch_pco = ret_pc - nm->code_begin();
+  ExceptionHandlerTable table(nm);
+  HandlerTableEntry *t = table.entry_for(catch_pco, -1, 0);
+  if (t != NULL) {
+    return nm->code_begin() + t->pco();
+  } else {
+    // there is no exception handler for this pc => deoptimize
+    nm->make_not_entrant();
+    JavaThread* thread = JavaThread::current();
+    RegisterMap reg_map(thread);
+    frame runtime_frame = thread->last_frame();
+    frame caller_frame = runtime_frame.sender(&reg_map);
+    Deoptimization::deoptimize_frame(thread, caller_frame.id());
+    return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
+  }
+
+#else
+
   ScopeDesc* sd = nm->scope_desc_at(ret_pc);
   // determine handler bci, if any
   EXCEPTION_MARK;
@@ -730,6 +750,7 @@
   }
 
   return nm->code_begin() + t->pco();
+#endif
 }
 
 JRT_ENTRY(void, SharedRuntime::throw_AbstractMethodError(JavaThread* thread))
@@ -768,6 +789,15 @@
   throw_and_post_jvmti_exception(thread, exception);
 JRT_END
 
+address SharedRuntime::deoptimization_continuation(JavaThread* thread, address pc, nmethod* nm)
+{
+  if (TraceSignals) {
+    tty->print_cr(err_msg("Deoptimizing on implicit exception at relative pc=%d in method %s", pc - nm->entry_point(), nm->method()->name()->as_C_string()));
+  }
+  thread->_ScratchA = (intptr_t)pc;
+  return (SharedRuntime::deopt_blob()->jmp_uncommon_trap());
+}
+
 JRT_ENTRY(void, SharedRuntime::throw_WrongMethodTypeException(JavaThread* thread, oopDesc* required, oopDesc* actual))
   assert(thread == JavaThread::current() && required->is_oop() && actual->is_oop(), "bad args");
   ResourceMark rm;
@@ -781,6 +811,10 @@
 {
   address target_pc = NULL;
 
+  if (TraceSignals) {
+    tty->print_cr("Searching for continuation for implicit exception at %d!", pc);
+  }
+
   if (Interpreter::contains(pc)) {
 #ifdef CC_INTERP
     // C++ interpreter doesn't throw implicit exceptions
@@ -860,7 +894,11 @@
 #ifndef PRODUCT
           _implicit_null_throws++;
 #endif
+#ifdef GRAAL
+          target_pc = deoptimization_continuation(thread, pc, nm);
+#else
           target_pc = nm->continuation_for_implicit_exception(pc);
+#endif
           // If there's an unexpected fault, target_pc might be NULL,
           // in which case we want to fall through into the normal
           // error handling code.
@@ -876,7 +914,14 @@
 #ifndef PRODUCT
         _implicit_div0_throws++;
 #endif
+#ifdef GRAAL
+        if (TraceSignals) {
+          tty->print_cr("graal implicit div0");
+        }
+        target_pc = deoptimization_continuation(thread, pc, nm);
+#else
         target_pc = nm->continuation_for_implicit_exception(pc);
+#endif
         // If there's an unexpected fault, target_pc might be NULL,
         // in which case we want to fall through into the normal
         // error handling code.
@@ -2778,7 +2823,7 @@
   // ResourceObject, so do not put any ResourceMarks in here.
   char *s = sig->as_C_string();
   int len = (int)strlen(s);
-  *s++; len--;                  // Skip opening paren
+  s++; len--;                  // Skip opening paren
   char *t = s+len;
   while( *(--t) != ')' ) ;      // Find close paren
 
--- a/src/share/vm/runtime/sharedRuntime.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/sharedRuntime.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -187,6 +187,7 @@
   static void    throw_NullPointerException(JavaThread* thread);
   static void    throw_NullPointerException_at_call(JavaThread* thread);
   static void    throw_StackOverflowError(JavaThread* thread);
+  static address deoptimization_continuation(JavaThread* thread, address pc, nmethod* nm);
   static void    throw_WrongMethodTypeException(JavaThread* thread, oopDesc* required, oopDesc* actual);
   static address continuation_for_implicit_exception(JavaThread* thread,
                                                      address faulting_pc,
--- a/src/share/vm/runtime/stackValue.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/stackValue.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -118,6 +118,22 @@
          val = (oop)NULL;
       }
 #endif
+#ifndef PRODUCT
+      if (val != NULL && !val->is_oop()) {
+        ResourceMark rm;
+        tty->print_cr("found wrong oop " INTPTR_FORMAT " at location " INTPTR_FORMAT " (%d):", val, value_addr, val->is_oop());
+        if (fr->cb() != NULL) {
+          CodeBlob* cb = fr->cb();
+          if (cb->is_nmethod()) {
+            nmethod* nm = (nmethod*)cb;
+            tty->print_cr("method is %s", nm->method()->name()->as_C_string());
+          }
+        }
+        sv->print();
+        tty->print_cr("");
+        tty->print_cr("one less %d; one more %d", (*(((oop *)value_addr) - 1))->is_oop(), (*(((oop *)value_addr) + 1))->is_oop());
+      }
+#endif
       Handle h(val); // Wrap a handle around the oop
       return new StackValue(h);
     }
--- a/src/share/vm/runtime/sweeper.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/sweeper.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -320,10 +320,10 @@
 
 class NMethodMarker: public StackObj {
  private:
-  CompilerThread* _thread;
+  JavaThread* _thread;
  public:
   NMethodMarker(nmethod* nm) {
-    _thread = CompilerThread::current();
+    _thread = JavaThread::current();
     _thread->set_scanned_nmethod(nm);
   }
   ~NMethodMarker() {
--- a/src/share/vm/runtime/thread.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/thread.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -29,6 +29,9 @@
 #include "classfile/vmSymbols.hpp"
 #include "code/scopeDesc.hpp"
 #include "compiler/compileBroker.hpp"
+#ifdef GRAAL
+#include "graal/graalCompiler.hpp"
+#endif
 #include "interpreter/interpreter.hpp"
 #include "interpreter/linkResolver.hpp"
 #include "interpreter/oopMapCache.hpp"
@@ -1273,7 +1276,9 @@
 
   // Set the claimed par_id to -1 (ie not claiming any par_ids)
   set_claimed_par_id(-1);
-
+  
+  _env   = NULL;
+  _buffer_blob = NULL;
   set_saved_exception_pc(NULL);
   set_threadObj(NULL);
   _anchor.clear();
@@ -1298,6 +1303,7 @@
   _in_deopt_handler = 0;
   _doing_unsafe_access = false;
   _stack_guard_state = stack_guard_unused;
+  _graal_deopt_info = NULL;
   _exception_oop = NULL;
   _exception_pc  = 0;
   _exception_handler_pc = 0;
@@ -1316,6 +1322,7 @@
   _do_not_unlock_if_synchronized = false;
   _cached_monitor_info = NULL;
   _parker = Parker::Allocate(this) ;
+  _scanned_nmethod = NULL;
 
 #ifndef PRODUCT
   _jmp_ring_index = 0;
@@ -2031,7 +2038,9 @@
 
   // Do not throw asynchronous exceptions against the compiler thread
   // (the compiler thread should not be a Java thread -- fix in 1.4.2)
-  if (is_Compiler_thread()) return;
+
+  // (tw) May we do this?
+  //if (is_Compiler_thread()) return;
 
   {
     // Actually throw the Throwable against the target Thread - however
@@ -2612,12 +2621,20 @@
   f->do_oop((oop*) &_threadObj);
   f->do_oop((oop*) &_vm_result);
   f->do_oop((oop*) &_vm_result_2);
+  f->do_oop((oop*) &_graal_deopt_info);
   f->do_oop((oop*) &_exception_oop);
   f->do_oop((oop*) &_pending_async_exception);
 
   if (jvmti_thread_state() != NULL) {
     jvmti_thread_state()->oops_do(f);
   }
+
+  if (_scanned_nmethod != NULL && cf != NULL) {
+      // Safepoints can occur when the sweeper is scanning an nmethod so
+      // process it here to make sure it isn't unloaded in the middle of
+      // a scan.
+      cf->do_code_blob(_scanned_nmethod);
+    }
 }
 
 void JavaThread::nmethods_do(CodeBlobClosure* cf) {
@@ -3036,35 +3053,25 @@
 
 static void compiler_thread_entry(JavaThread* thread, TRAPS) {
   assert(thread->is_Compiler_thread(), "must be compiler thread");
+// XXX (gd) currently we still start c1 compiler threads even with Graal, they just die immediately, more compileBroker cleanup is needed to eliminate that
+#ifndef GRAAL
   CompileBroker::compiler_thread_loop();
+#endif
 }
 
 // Create a CompilerThread
 CompilerThread::CompilerThread(CompileQueue* queue, CompilerCounters* counters)
 : JavaThread(&compiler_thread_entry) {
-  _env   = NULL;
   _log   = NULL;
   _task  = NULL;
   _queue = queue;
   _counters = counters;
-  _buffer_blob = NULL;
-  _scanned_nmethod = NULL;
 
 #ifndef PRODUCT
   _ideal_graph_printer = NULL;
 #endif
 }
 
-void CompilerThread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
-  JavaThread::oops_do(f, cf);
-  if (_scanned_nmethod != NULL && cf != NULL) {
-    // Safepoints can occur when the sweeper is scanning an nmethod so
-    // process it here to make sure it isn't unloaded in the middle of
-    // a scan.
-    cf->do_code_blob(_scanned_nmethod);
-  }
-}
-
 // ======= Threads ========
 
 // The Threads class links together all active threads, and provides
@@ -4060,7 +4067,9 @@
   {
     MutexLockerEx ml(doLock ? Threads_lock : NULL);
     ALL_JAVA_THREADS(p) {
-      if (p->is_Compiler_thread()) continue;
+      
+      // (tw) May we do this?
+      //if (p->is_Compiler_thread()) continue;
 
       address pending = (address)p->current_pending_monitor();
       if (pending == monitor) {             // found a match
--- a/src/share/vm/runtime/thread.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/thread.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -734,6 +734,11 @@
   JavaThread*    _next;                          // The next thread in the Threads list
   oop            _threadObj;                     // The Java level thread object
 
+  // (tw) Necessary for holding a compilation buffer and ci environment. Moved from CompilerThread to JavaThread in order to enable code installation from Java application code.
+  BufferBlob*   _buffer_blob;
+  ciEnv*        _env;
+  bool          _is_compiling;
+
 #ifdef ASSERT
  private:
   int _java_call_counter;
@@ -861,8 +866,15 @@
 
  private:
 
+  // graal needs some place to put the dimensions
+  jint graal_multinewarray_storage[256];
+
+  volatile oop _graal_deopt_info;
+
   StackGuardState        _stack_guard_state;
 
+  nmethod*      _scanned_nmethod;  // nmethod being scanned by the sweeper
+
   // Compiler exception handling (NOTE: The _exception_oop is *NOT* the same as _pending_exception. It is
   // used to temp. parsing values into and out of the runtime system during exception handling for compiled
   // code)
@@ -871,9 +883,6 @@
   volatile address _exception_handler_pc;        // PC for handler of exception
   volatile int     _is_method_handle_return;     // true (== 1) if the current exception PC is a MethodHandle call site.
 
-  // support for compilation
-  bool    _is_compiling;                         // is true if a compilation is active inthis thread (one compilation per thread possible)
-
   // support for JNI critical regions
   jint    _jni_active_critical;                  // count of entries into JNI critical region
 
@@ -933,6 +942,16 @@
   struct JNINativeInterface_* get_jni_functions() {
     return (struct JNINativeInterface_ *)_jni_environment.functions;
   }
+  
+  bool is_compiling() const                      { return _is_compiling; }
+  void set_compiling(bool b)                     { _is_compiling = b; }
+
+  // Get/set the thread's compilation environment.
+  ciEnv*        env()                            { return _env; }
+  void          set_env(ciEnv* env)              { _env = env; }
+
+  BufferBlob*   get_buffer_blob()                { return _buffer_blob; }
+  void          set_buffer_blob(BufferBlob* b)   { _buffer_blob = b; };
 
   // This function is called at thread creation to allow
   // platform specific thread variables to be initialized.
@@ -950,13 +969,15 @@
 
   void cleanup_failed_attach_current_thread();
 
+  // Track the nmethod currently being scanned by the sweeper
+  void          set_scanned_nmethod(nmethod* nm) {
+    assert(_scanned_nmethod == NULL || nm == NULL, "should reset to NULL before writing a new value");
+    _scanned_nmethod = nm;
+  }
+
   // Testers
   virtual bool is_Java_thread() const            { return true;  }
 
-  // compilation
-  void set_is_compiling(bool f)                  { _is_compiling = f; }
-  bool is_compiling() const                      { return _is_compiling; }
-
   // Thread chain operations
   JavaThread* next() const                       { return _next; }
   void set_next(JavaThread* p)                   { _next = p; }
@@ -1212,6 +1233,9 @@
   MemRegion deferred_card_mark() const           { return _deferred_card_mark; }
   void set_deferred_card_mark(MemRegion mr)      { _deferred_card_mark = mr;   }
 
+  oop      graal_deopt_info() const              { return _graal_deopt_info; }
+  void set_graal_deopt_info(oop o)               { _graal_deopt_info = o; }
+
   // Exception handling for compiled methods
   oop      exception_oop() const                 { return _exception_oop; }
   address  exception_pc() const                  { return _exception_pc; }
@@ -1291,12 +1315,14 @@
   static ByteSize thread_state_offset()          { return byte_offset_of(JavaThread, _thread_state        ); }
   static ByteSize saved_exception_pc_offset()    { return byte_offset_of(JavaThread, _saved_exception_pc  ); }
   static ByteSize osthread_offset()              { return byte_offset_of(JavaThread, _osthread            ); }
+  static ByteSize graal_deopt_info_offset()      { return byte_offset_of(JavaThread, _graal_deopt_info    ); }
   static ByteSize exception_oop_offset()         { return byte_offset_of(JavaThread, _exception_oop       ); }
   static ByteSize exception_pc_offset()          { return byte_offset_of(JavaThread, _exception_pc        ); }
   static ByteSize exception_handler_pc_offset()  { return byte_offset_of(JavaThread, _exception_handler_pc); }
   static ByteSize is_method_handle_return_offset() { return byte_offset_of(JavaThread, _is_method_handle_return); }
   static ByteSize stack_guard_state_offset()     { return byte_offset_of(JavaThread, _stack_guard_state   ); }
   static ByteSize suspend_flags_offset()         { return byte_offset_of(JavaThread, _suspend_flags       ); }
+  static ByteSize graal_multinewarray_storage_offset() { return byte_offset_of(JavaThread, graal_multinewarray_storage); }
 
   static ByteSize do_not_unlock_if_synchronized_offset() { return byte_offset_of(JavaThread, _do_not_unlock_if_synchronized); }
   static ByteSize should_post_on_exceptions_flag_offset() {
@@ -1731,13 +1757,10 @@
  private:
   CompilerCounters* _counters;
 
-  ciEnv*        _env;
   CompileLog*   _log;
   CompileTask*  _task;
   CompileQueue* _queue;
-  BufferBlob*   _buffer_blob;
 
-  nmethod*      _scanned_nmethod;  // nmethod being scanned by the sweeper
 
  public:
 
@@ -1747,18 +1770,18 @@
 
   bool is_Compiler_thread() const                { return true; }
   // Hide this compiler thread from external view.
-  bool is_hidden_from_external_view() const      { return true; }
+  // (tw) For Graal, the compiler thread should be visible.
+  bool is_hidden_from_external_view() const      {
+#ifdef GRAAL
+    return !DebugGraal;
+#else
+    return true;
+#endif
+  }
 
   CompileQueue* queue()                          { return _queue; }
   CompilerCounters* counters()                   { return _counters; }
 
-  // Get/set the thread's compilation environment.
-  ciEnv*        env()                            { return _env; }
-  void          set_env(ciEnv* env)              { _env = env; }
-
-  BufferBlob*   get_buffer_blob()                { return _buffer_blob; }
-  void          set_buffer_blob(BufferBlob* b)   { _buffer_blob = b; };
-
   // Get/set the thread's logging information
   CompileLog*   log()                            { return _log; }
   void          init_log(CompileLog* log) {
@@ -1767,11 +1790,6 @@
     _log = log;
   }
 
-  // GC support
-  // Apply "f->do_oop" to all root oops in "this".
-  // Apply "cf->do_code_blob" (if !NULL) to all code blobs active in frames
-  void oops_do(OopClosure* f, CodeBlobClosure* cf);
-
 #ifndef PRODUCT
 private:
   IdealGraphPrinter *_ideal_graph_printer;
@@ -1783,12 +1801,6 @@
   // Get/set the thread's current task
   CompileTask*  task()                           { return _task; }
   void          set_task(CompileTask* task)      { _task = task; }
-
-  // Track the nmethod currently being scanned by the sweeper
-  void          set_scanned_nmethod(nmethod* nm) {
-    assert(_scanned_nmethod == NULL || nm == NULL, "should reset to NULL before writing a new value");
-    _scanned_nmethod = nm;
-  }
 };
 
 inline CompilerThread* CompilerThread::current() {
--- a/src/share/vm/runtime/vframe.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/vframe.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -266,8 +266,8 @@
 
   // Get oopmap describing oops and int for current bci
   InterpreterOopMap oop_mask;
-  if (TraceDeoptimization && Verbose) {
-    methodHandle m_h(thread(), method());
+  if (PrintDeoptimizationDetails) {
+    methodHandle m_h(method());
     OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask);
   } else {
     method()->mask_for(bci(), &oop_mask);
@@ -333,7 +333,7 @@
 
   InterpreterOopMap oop_mask;
   // Get oopmap describing oops and int for current bci
-  if (TraceDeoptimization && Verbose) {
+  if (PrintDeoptimizationDetails) {
     methodHandle m_h(method());
     OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask);
   } else {
--- a/src/share/vm/runtime/vframeArray.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/vframeArray.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "classfile/vmSymbols.hpp"
+#include "code/scopeDesc.hpp"
 #include "interpreter/interpreter.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
@@ -62,7 +63,7 @@
   _method = vf->method();
   _bci    = vf->raw_bci();
   _reexecute = vf->should_reexecute();
-
+  
   int index;
 
   // Get the monitors off-stack
@@ -126,7 +127,6 @@
 
   // Now the expressions off-stack
   // Same silliness as above
-
   StackValueCollection *exprs = vf->expressions();
   _expressions = new StackValueCollection(exprs->size());
   for(index = 0; index < exprs->size(); index++) {
@@ -251,6 +251,7 @@
       case Deoptimization::Unpack_uncommon_trap:
       case Deoptimization::Unpack_reexecute:
         // redo last byte code
+        assert(should_reexecute(), "");
         pc  = Interpreter::deopt_entry(vtos, 0);
         use_next_mdp = false;
         break;
@@ -306,22 +307,41 @@
       iframe()->interpreter_frame_set_mdp(mdp);
     }
   }
+  
+  if (PrintDeoptimizationDetails) {
+    tty->print_cr("Expressions size: %d", expressions()->size());
+  }
 
   // Unpack expression stack
   // If this is an intermediate frame (i.e. not top frame) then this
   // only unpacks the part of the expression stack not used by callee
   // as parameters. The callee parameters are unpacked as part of the
   // callee locals.
-  int i;
-  for(i = 0; i < expressions()->size(); i++) {
+  for(int i = 0; i < expressions()->size(); i++) {
     StackValue *value = expressions()->at(i);
     intptr_t*   addr  = iframe()->interpreter_frame_expression_stack_at(i);
     switch(value->type()) {
       case T_INT:
         *addr = value->get_int();
+#ifndef PRODUCT
+        if (PrintDeoptimizationDetails) {
+          tty->print_cr("Reconstructed expression %d (INT): %d", i, (int)(*addr));
+        }
+#endif
         break;
       case T_OBJECT:
         *addr = value->get_int(T_OBJECT);
+#ifndef PRODUCT
+        if (PrintDeoptimizationDetails) {
+          tty->print("Reconstructed expression %d (OBJECT): ", i);
+          oop o = (oop)(*addr);
+          if (o == NULL) {
+            tty->print_cr("NULL");
+          } else {
+            tty->print_cr(err_msg("%s", o->blueprint()->name()->as_C_string()));
+          }
+        }
+#endif
         break;
       case T_CONFLICT:
         // A dead stack slot.  Initialize to null in case it is an oop.
@@ -334,15 +354,31 @@
 
 
   // Unpack the locals
-  for(i = 0; i < locals()->size(); i++) {
+  for(int i = 0; i < locals()->size(); i++) {
     StackValue *value = locals()->at(i);
     intptr_t* addr  = iframe()->interpreter_frame_local_at(i);
     switch(value->type()) {
       case T_INT:
         *addr = value->get_int();
+#ifndef PRODUCT
+        if (PrintDeoptimizationDetails) {
+          tty->print_cr("Reconstructed local %d (INT): %d", i, (int)(*addr));
+        }
+#endif
         break;
       case T_OBJECT:
         *addr = value->get_int(T_OBJECT);
+#ifndef PRODUCT
+        if (PrintDeoptimizationDetails) {
+          tty->print("Reconstructed local %d (OBJECT): ", i);
+          oop o = (oop)(*addr);
+          if (o == NULL) {
+            tty->print_cr("NULL");
+          } else {
+            tty->print_cr(err_msg("%s", o->blueprint()->name()->as_C_string()));
+          }
+        }
+#endif
         break;
       case T_CONFLICT:
         // A dead location. If it is an oop then we need a NULL to prevent GC from following it
@@ -384,18 +420,13 @@
   }
 
 #ifndef PRODUCT
-  if (TraceDeoptimization && Verbose) {
+  if (PrintDeoptimizationDetails) {
     ttyLocker ttyl;
     tty->print_cr("[%d Interpreted Frame]", ++unpack_counter);
     iframe()->print_on(tty);
     RegisterMap map(thread);
     vframe* f = vframe::new_vframe(iframe(), &map, thread);
     f->print();
-
-    tty->print_cr("locals size     %d", locals()->size());
-    tty->print_cr("expression size %d", expressions()->size());
-
-    method()->print_value();
     tty->cr();
     // method()->print_codes();
   } else if (TraceDeoptimization) {
--- a/src/share/vm/runtime/vframe_hp.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/vframe_hp.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -70,6 +70,12 @@
     }
   }
 
+  if (PrintDeoptimizationDetails) {
+    tty->print_cr("bci=%d length=%d", this->bci(), length);
+    tty->print_cr(err_msg("method name = %s", this->method()->name()->as_C_string()));
+    tty->print_cr("relative pc=%d", this->fr().pc() - this->nm()->code_begin());
+  }
+
   for( int i = 0; i < length; i++ ) {
     result->add( create_stack_value(scv_list->at(i)) );
   }
--- a/src/share/vm/runtime/vframe_hp.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/vframe_hp.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -66,7 +66,7 @@
   // Returns SynchronizationEntryBCI or bci() (used for synchronization)
   int raw_bci() const;
 
- protected:
+ //protected:
   ScopeDesc* _scope;
 
 
--- a/src/share/vm/runtime/vm_version.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/runtime/vm_version.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -119,8 +119,12 @@
   #define VMTYPE "Zero"
 #endif // SHARK
 #else // ZERO
+#ifdef GRAAL
+   #define VMTYPE "Graal"
+#else // GRAAL
    #define VMTYPE COMPILER1_PRESENT("Client")   \
                   COMPILER2_PRESENT("Server")
+#endif // GRAAL
 #endif // ZERO
 #endif // TIERED
 #endif // KERNEL
--- a/src/share/vm/shark/sharkCacheDecache.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/shark/sharkCacheDecache.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -151,8 +151,10 @@
 
 void SharkDecacher::end_frame() {
   // Record the scope
+  methodHandle null_mh;
   debug_info()->describe_scope(
     pc_offset(),
+    null_mh,
     target(),
     bci(),
     true,
--- a/src/share/vm/utilities/exceptions.cpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/utilities/exceptions.cpp	Mon Feb 27 13:10:13 2012 +0100
@@ -95,7 +95,8 @@
 #endif // ASSERT
 
   if (thread->is_VM_thread()
-      || thread->is_Compiler_thread() ) {
+	  // TODO(tw): May we do this?
+      /*|| thread->is_Compiler_thread()*/ ) {
     // We do not care what kind of exception we get for the vm-thread or a thread which
     // is compiling.  We just install a dummy exception object
     thread->set_pending_exception(Universe::vm_exception(), file, line);
@@ -118,7 +119,8 @@
   }
 
   if (thread->is_VM_thread()
-      || thread->is_Compiler_thread() ) {
+	  // TODO(tw): May we do this?
+     /* || thread->is_Compiler_thread()*/ ) {
     // We do not care what kind of exception we get for the vm-thread or a thread which
     // is compiling.  We just install a dummy exception object
     thread->set_pending_exception(Universe::vm_exception(), file, line);
--- a/src/share/vm/utilities/globalDefinitions.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/utilities/globalDefinitions.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -106,9 +106,9 @@
 // log2_intptr(sizeof(class JavaThread)) - log2_intptr(64);
 // see os::set_memory_serialize_page()
 #ifdef _LP64
-const int SerializePageShiftCount = 4;
+const int SerializePageShiftCount = 5;
 #else
-const int SerializePageShiftCount = 3;
+const int SerializePageShiftCount = 4;
 #endif
 
 // An opaque struct of heap-word width, so that HeapWord* can be a generic
--- a/src/share/vm/utilities/macros.hpp	Fri Feb 24 18:08:59 2012 -0800
+++ b/src/share/vm/utilities/macros.hpp	Mon Feb 27 13:10:13 2012 +0100
@@ -74,6 +74,12 @@
 #define NOT_COMPILER2(code) code
 #endif // COMPILER2
 
+#ifdef GRAAL
+#define IS_GRAAL(code) code
+#else
+#define IS_GRAAL(code)
+#endif
+
 #ifdef TIERED
 #define TIERED_ONLY(code) code
 #define NOT_TIERED(code)
Binary file test/runtime/7020373/testcase.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/BatikSVGProxy/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.svg" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.svg.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/BatikSVGProxy/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.svg
+OpenIDE-Module-Layer: com/sun/hotspot/igv/svg/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/svg/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/BatikSVGProxy/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.svg-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/BatikSVGProxy/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,5 @@
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=ebcf0422
+nbproject/build-impl.xml.script.CRC32=42ef3ff6
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.47.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/BatikSVGProxy/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/BatikSVGProxy/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.svg</code-name-base>
+            <suite-component/>
+            <module-dependencies/>
+            <public-packages>
+                <package>com.sun.hotspot.igv.svg</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/BatikSVGProxy/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/BatikSVG.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.svg;
+
+import java.awt.Graphics2D;
+import java.io.Writer;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import org.w3c.dom.DOMImplementation;
+
+/**
+ * Utility class
+ * @author Thomas Wuerthinger
+ */
+public class BatikSVG {
+
+    private BatikSVG() {
+    }
+
+    private static Constructor SVGGraphics2DConstructor;
+    private static Method streamMethod;
+    private static Method createDefaultMethod;
+    private static Method getDOMImplementationMethod;
+    private static Method setEmbeddedFontsOnMethod;
+    private static Class<?> classSVGGraphics2D;
+
+    /**
+     * Creates a graphics object that allows to be exported to SVG data using the {@link #printToStream(Graphics2D, Writer, boolean) printToStream} method.
+     * @return the newly created Graphics2D object or null if the library does not exist
+     */
+    public static Graphics2D createGraphicsObject() {
+        try {
+            if (SVGGraphics2DConstructor == null) {
+                ClassLoader cl = BatikSVG.class.getClassLoader();
+                Class<?> classGenericDOMImplementation = cl.loadClass("org.apache.batik.dom.GenericDOMImplementation");
+                Class<?> classSVGGeneratorContext = cl.loadClass("org.apache.batik.svggen.SVGGeneratorContext");
+                classSVGGraphics2D = cl.loadClass("org.apache.batik.svggen.SVGGraphics2D");
+                getDOMImplementationMethod = classGenericDOMImplementation.getDeclaredMethod("getDOMImplementation", new Class[0]);
+                createDefaultMethod = classSVGGeneratorContext.getDeclaredMethod("createDefault", new Class[]{org.w3c.dom.Document.class});
+                setEmbeddedFontsOnMethod = classSVGGeneratorContext.getDeclaredMethod("setEmbeddedFontsOn", new Class[]{boolean.class});
+                streamMethod = classSVGGraphics2D.getDeclaredMethod("stream", Writer.class, boolean.class);
+                SVGGraphics2DConstructor = classSVGGraphics2D.getConstructor(classSVGGeneratorContext, boolean.class);
+            }
+            DOMImplementation dom = (DOMImplementation) getDOMImplementationMethod.invoke(null);
+            org.w3c.dom.Document document = dom.createDocument("http://www.w3.org/2000/svg", "svg", null);
+            Object ctx = createDefaultMethod.invoke(null, document);
+            setEmbeddedFontsOnMethod.invoke(ctx, true);
+            Graphics2D svgGenerator = (Graphics2D) SVGGraphics2DConstructor.newInstance(ctx, true);
+            return svgGenerator;
+        } catch (ClassNotFoundException e) {
+            return null;
+        } catch (NoSuchMethodException e) {
+            return null;
+        } catch (IllegalAccessException e) {
+            return null;
+        } catch (InvocationTargetException e) {
+            return null;
+        } catch (InstantiationException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Serializes a graphics object to a stream in SVG format.
+     * @param svgGenerator the graphics object. Only graphics objects created by the {@link #createGraphicsObject() createGraphicsObject} method are valid.
+     * @param stream the stream to which the data is written
+     * @param useCSS whether to use CSS styles in the SVG output
+     */
+    public static void printToStream(Graphics2D svgGenerator, Writer stream, boolean useCSS) {
+        assert classSVGGraphics2D != null;
+        assert classSVGGraphics2D.isInstance(svgGenerator);
+        try {
+            streamMethod.invoke(svgGenerator, stream, useCSS);
+        } catch (IllegalAccessException e) {
+            assert false;
+        } catch (InvocationTargetException e) {
+            assert false;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=BatikSVGProxy
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/layer.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
+<filesystem>
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/package-info.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2008, 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.
+ *
+ */
+/**
+ * This package is used to proxy the SVG export functionality of the BatikSVG library. Reflection is used such that the
+ * library is optional and need not be present at build time.
+ */
+package com.sun.hotspot.igv.svg;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.bytecodes" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.bytecodes.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.bytecodes
+OpenIDE-Module-Layer: com/sun/hotspot/igv/bytecodes/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/bytecodes/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.bytecodes-impl" basedir="..">
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+        <condition>
+            <not>
+                <available file="${harness.dir}" type="dir"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=1dee290d
+build.xml.script.CRC32=d594034f
+build.xml.stylesheet.CRC32=79c3b980
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=1dee290d
+nbproject/build-impl.xml.script.CRC32=b4dab126
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/nbproject/platform.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.javahelp,\
+    org.netbeans.modules.masterfs,\
+    org.netbeans.modules.options.keymap,\
+    org.netbeans.modules.sendopts,\
+    org.netbeans.modules.templates,\
+    org.openide.compat,\
+    org.openide.execution,\
+    org.openide.util.enumerations
+enabled.clusters=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.bytecodes</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.jdesktop.layout</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.16.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.explorer</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.34.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.nodes</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.20.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.39.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages/>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,5 @@
+CTL_BytecodeViewAction=Bytecode
+CTL_BytecodeViewTopComponent=Bytecode
+CTL_SelectBytecodesAction=Select nodes
+HINT_BytecodeViewTopComponent=Shows the bytecode associated with the displayed graph.
+OpenIDE-Module-Name=Bytecodes
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.bytecodes;
+
+import com.sun.hotspot.igv.data.InputBytecode;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Properties.StringPropertyMatcher;
+import java.awt.Image;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import javax.swing.Action;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.openide.util.ImageUtilities;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class BytecodeNode extends AbstractNode {
+
+    private Set<InputNode> nodes;
+
+    public BytecodeNode(InputBytecode bytecode, InputGraph graph, String bciValue) {
+
+        super(Children.LEAF);
+        this.setDisplayName(bytecode.getBci() + " " + bytecode.getName());
+
+        bciValue = bytecode.getBci() + " " + bciValue;
+        bciValue = bciValue.trim();
+
+        Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<>(graph.getNodes());
+        StringPropertyMatcher matcher = new StringPropertyMatcher("bci", bciValue);
+        List<InputNode> nodeList = selector.selectMultiple(matcher);
+        if (nodeList.size() > 0) {
+            nodes = new LinkedHashSet<>();
+            for (InputNode n : nodeList) {
+                nodes.add(n);
+            }
+            this.setDisplayName(this.getDisplayName() + " (" + nodes.size() + " nodes)");
+        }
+    }
+
+    @Override
+    public Image getIcon(int i) {
+        if (nodes != null) {
+            return ImageUtilities.loadImage("com/sun/hotspot/igv/bytecodes/images/link.png");
+        } else {
+            return ImageUtilities.loadImage("com/sun/hotspot/igv/bytecodes/images/bytecode.png");
+        }
+    }
+
+    @Override
+    public Image getOpenedIcon(int i) {
+        return getIcon(i);
+    }
+
+    @Override
+    public Action[] getActions(boolean b) {
+        return new Action[]{(Action) SelectBytecodesAction.findObject(SelectBytecodesAction.class, true)};
+    }
+
+    @Override
+    public Action getPreferredAction() {
+        return (Action) SelectBytecodesAction.findObject(SelectBytecodesAction.class, true);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <T extends Node.Cookie> T getCookie(Class<T> aClass) {
+        if (aClass == SelectBytecodesCookie.class && nodes != null) {
+            return (T) (new SelectBytecodesCookie(nodes));
+        }
+        return super.getCookie(aClass);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.bytecodes;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.openide.util.NbBundle;
+import org.openide.windows.TopComponent;
+
+/**
+ * @author Thomas Wuerthinger
+ */
+public class BytecodeViewAction extends AbstractAction {
+
+    public BytecodeViewAction() {
+        super(NbBundle.getMessage(BytecodeViewAction.class, "CTL_BytecodeViewAction"));
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent evt) {
+        TopComponent win = BytecodeViewTopComponent.findInstance();
+        win.open();
+        win.requestActive();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.form	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.3" maxVersion="1.3" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <EmptySpace min="0" pref="400" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <EmptySpace min="0" pref="300" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+</Form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.bytecodes;
+
+import com.sun.hotspot.igv.data.Group;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import java.awt.BorderLayout;
+import java.io.Serializable;
+import javax.swing.SwingUtilities;
+import org.openide.ErrorManager;
+import org.openide.explorer.ExplorerManager;
+import org.openide.explorer.ExplorerUtils;
+import org.openide.explorer.view.BeanTreeView;
+import org.openide.util.*;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
+
+/**
+ * @author Thomas Wuerthinger
+ */
+final class BytecodeViewTopComponent extends TopComponent implements ExplorerManager.Provider, LookupListener {
+
+    private static BytecodeViewTopComponent instance;
+    private static final String PREFERRED_ID = "BytecodeViewTopComponent";
+    private ExplorerManager manager;
+    private BeanTreeView treeView;
+    private Lookup.Result result = null;
+    private MethodNode rootNode;
+
+    private BytecodeViewTopComponent() {
+        initComponents();
+        setName(NbBundle.getMessage(BytecodeViewTopComponent.class, "CTL_BytecodeViewTopComponent"));
+        setToolTipText(NbBundle.getMessage(BytecodeViewTopComponent.class, "HINT_BytecodeViewTopComponent"));
+
+        manager = new ExplorerManager();
+        rootNode = new MethodNode(null, null, "");
+        manager.setRootContext(rootNode);
+
+        setLayout(new BorderLayout());
+
+        treeView = new BeanTreeView();
+        treeView.setRootVisible(false);
+        this.add(BorderLayout.CENTER, treeView);
+        associateLookup(ExplorerUtils.createLookup(manager, getActionMap()));
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+            .add(0, 400, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+            .add(0, 300, Short.MAX_VALUE)
+        );
+    }// </editor-fold>//GEN-END:initComponents
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    // End of variables declaration//GEN-END:variables
+
+    /**
+     * Gets default instance. Do not use directly: reserved for *.settings files only,
+     * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
+     * To obtain the singleton instance, use {@link findInstance}.
+     */
+    public static synchronized BytecodeViewTopComponent getDefault() {
+        if (instance == null) {
+            instance = new BytecodeViewTopComponent();
+        }
+        return instance;
+    }
+
+    /**
+     * Obtain the BytecodeViewTopComponent instance. Never call {@link #getDefault} directly!
+     */
+    public static synchronized BytecodeViewTopComponent findInstance() {
+        TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
+        if (win == null) {
+            ErrorManager.getDefault().log(ErrorManager.WARNING, "Cannot find BytecodeView component. It will not be located properly in the window system.");
+            return getDefault();
+        }
+        if (win instanceof BytecodeViewTopComponent) {
+            return (BytecodeViewTopComponent) win;
+        }
+        ErrorManager.getDefault().log(ErrorManager.WARNING, "There seem to be multiple components with the '" + PREFERRED_ID + "' ID. That is a potential source of errors and unexpected behavior.");
+        return getDefault();
+    }
+
+    @Override
+    public int getPersistenceType() {
+        return TopComponent.PERSISTENCE_ALWAYS;
+    }
+
+    @Override
+    public void componentOpened() {
+        Lookup.Template<InputGraphProvider> tpl = new Lookup.Template<>(InputGraphProvider.class);
+        result = Utilities.actionsGlobalContext().lookup(tpl);
+        result.addLookupListener(this);
+    }
+
+    @Override
+    public void componentClosed() {
+        result.removeLookupListener(this);
+        result = null;
+    }
+
+    @Override
+    public Object writeReplace() {
+        return new ResolvableHelper();
+    }
+
+    @Override
+    protected String preferredID() {
+        return PREFERRED_ID;
+    }
+
+    @Override
+    public ExplorerManager getExplorerManager() {
+        return manager;
+    }
+
+    @Override
+    public void requestActive() {
+        super.requestActive();
+        this.treeView.requestFocus();
+    }
+
+    @Override
+    public boolean requestFocus(boolean temporary) {
+        this.treeView.requestFocus();
+        return super.requestFocus(temporary);
+    }
+
+    @Override
+    protected boolean requestFocusInWindow(boolean temporary) {
+        this.treeView.requestFocus();
+        return super.requestFocusInWindow(temporary);
+    }
+
+    @Override
+    public void resultChanged(LookupEvent lookupEvent) {
+        final InputGraphProvider p = null; // TODO(tw): FIXME //.getLast(InputGraphProvider.class);//)Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
+        if (p != null) {
+            SwingUtilities.invokeLater(new Runnable() {
+                @Override
+                public void run() {
+                    InputGraph graph = p.getGraph();
+                    if (graph != null) {
+                        Group g = graph.getGroup();
+                        rootNode.update(graph, g.getMethod());
+                    }
+                }
+            });
+        }
+    }
+
+    final static class ResolvableHelper implements Serializable {
+
+        private static final long serialVersionUID = 1L;
+
+        public Object readResolve() {
+            return BytecodeViewTopComponent.getDefault();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponentSettings.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd">
+<settings version="1.0">
+    <module name="com.sun.hotspot.igv.bytecodes" spec="1.0"/>
+    <instanceof class="org.openide.windows.TopComponent"/>
+    <instanceof class="com.sun.hotspot.igv.bytecodes.BytecodeViewTopComponent"/>
+    <instance class="com.sun.hotspot.igv.bytecodes.BytecodeViewTopComponent" method="getDefault"/>
+</settings>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponentWstcref.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE tc-ref PUBLIC "-//NetBeans//DTD Top Component in Mode Properties 2.0//EN" "http://www.netbeans.org/dtds/tc-ref2_0.dtd">
+<tc-ref version="2.0" >
+    <module name="com.sun.hotspot.igv.bytecodes" spec="1.0"/>
+    <tc-id id="BytecodeViewTopComponent"/>
+    <state opened="true"/>
+</tc-ref>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/MethodNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.bytecodes;
+
+import com.sun.hotspot.igv.data.InputBytecode;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.InputMethod;
+import java.awt.Image;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.openide.util.ImageUtilities;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class MethodNode extends AbstractNode {
+
+    private static class MethodNodeChildren extends Children.Keys<InputBytecode> {
+
+        private InputMethod method;
+        private InputGraph graph;
+        private String bciString;
+
+        public MethodNodeChildren(InputMethod method, InputGraph graph, String bciString) {
+            this.method = method;
+            this.bciString = bciString;
+            this.graph = graph;
+        }
+
+        @Override
+        protected Node[] createNodes(InputBytecode bc) {
+            if (bc.getInlined() == null) {
+                return new Node[]{new BytecodeNode(bc, graph, bciString)};
+            } else {
+                return new Node[]{new BytecodeNode(bc, graph, bciString), new MethodNode(bc.getInlined(), graph, bc.getBci() + " " + bciString)};
+            }
+        }
+
+        @Override
+        public void addNotify() {
+            if (method != null) {
+                setKeys(method.getBytecodes());
+            }
+        }
+
+        public void setMethod(InputMethod method, InputGraph graph) {
+            this.method = method;
+            this.graph = graph;
+            addNotify();
+        }
+    }
+
+    /** Creates a new instance of MethodNode */
+    public MethodNode(InputMethod method, InputGraph graph, String bciString) {
+        super((method != null && method.getBytecodes().size() == 0) ? Children.LEAF : new MethodNodeChildren(method, graph, bciString));
+        if (method != null) {
+            this.setDisplayName(method.getName());
+        }
+    }
+
+    @Override
+    public Image getIcon(int i) {
+        return ImageUtilities.loadImage("com/sun/hotspot/igv/bytecodes/images/method.png");
+    }
+
+    @Override
+    public Image getOpenedIcon(int i) {
+        return getIcon(i);
+    }
+
+    public void update(InputGraph graph, InputMethod method) {
+        ((MethodNodeChildren) this.getChildren()).setMethod(method, graph);
+        if (method != null) {
+            this.setDisplayName(method.getName());
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.bytecodes;
+
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import org.openide.nodes.Node;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CookieAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class SelectBytecodesAction extends CookieAction {
+
+    @Override
+    protected void performAction(Node[] activatedNodes) {
+        SelectBytecodesCookie c = activatedNodes[0].getCookie(SelectBytecodesCookie.class);
+        InputGraphProvider p = null; // TODO: fixme LookupHistory.getLast(InputGraphProvider.class);//Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
+        if (p != null) {
+            p.setSelectedNodes(c.getNodes());
+        }
+    }
+
+    @Override
+    protected int mode() {
+        return CookieAction.MODE_EXACTLY_ONE;
+    }
+
+    @Override
+    public String getName() {
+        return NbBundle.getMessage(SelectBytecodesAction.class, "CTL_SelectBytecodesAction");
+    }
+
+    @Override
+    protected Class[] cookieClasses() {
+        return new Class[]{
+            SelectBytecodesCookie.class
+        };
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+        putValue("noIconInMenu", Boolean.TRUE);
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/SelectBytecodesCookie.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.bytecodes;
+
+import com.sun.hotspot.igv.data.InputNode;
+import java.util.Collections;
+import java.util.Set;
+import org.openide.nodes.Node;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class SelectBytecodesCookie implements Node.Cookie {
+
+    private Set<InputNode> nodes;
+
+    /** Creates a new instance of SelectBytecodesCookie */
+    public SelectBytecodesCookie(Set<InputNode> nodes) {
+        this.nodes = nodes;
+    }
+
+    public Set<InputNode> getNodes() {
+        return Collections.unmodifiableSet(nodes);
+    }
+}
Binary file visualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/bytecode.png has changed
Binary file visualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/link.png has changed
Binary file visualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/method.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/layer.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
+<filesystem>
+    <folder name="Actions">
+        <folder name="Edit">
+            <file name="com-sun-hotspot-igv-bytecodes-SelectBytecodesAction.instance"/>
+        </folder>
+        <folder name="Window">
+            <file name="com-sun-hotspot-igv-bytecodes-BytecodeViewAction.instance"/>
+        </folder>
+    </folder>
+    <folder name="Menu">
+        <folder name="Window">
+            <file name="BytecodeViewAction.shadow">
+                <attr name="originalFile" stringvalue="Actions/Window/com-sun-hotspot-igv-bytecodes-BytecodeViewAction.instance"/>
+            </file>
+        </folder>
+    </folder>
+    <folder name="Windows2">
+        <folder name="Components">
+            <file name="BytecodeViewTopComponent.settings" url="BytecodeViewTopComponentSettings.xml"/>
+        </folder>
+        <folder name="Modes">
+            <folder name="customRightTopMode">
+                <file name="BytecodeViewTopComponent.wstcref" url="BytecodeViewTopComponentWstcref.xml"/>
+            </folder>
+        </folder>
+    </folder>
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="at.ssw.visualizer.cfg" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project at.ssw.visualizer.cfg.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: at.ssw.visualizer.cfg
+OpenIDE-Module-Layer: at/ssw/visualizer/cfg/layer.xml
+OpenIDE-Module-Localizing-Bundle: at/ssw/visualizer/cfg/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="at.ssw.visualizer.cfg-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=d86dea19
+build.xml.script.CRC32=ec651852
+build.xml.stylesheet.CRC32=a56c6a5b@2.47.1
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=d86dea19
+nbproject/build-impl.xml.script.CRC32=d9cb852b
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.47.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/nbproject/platform.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,204 @@
+cluster.path=\
+    ${nbplatform.active.dir}/ide:\
+    ${nbplatform.active.dir}/platform
+disabled.modules=\
+    com.jcraft.jsch,\
+    com.jcraft.jzlib,\
+    org.apache.commons.codec,\
+    org.apache.commons.httpclient,\
+    org.apache.commons.io,\
+    org.apache.commons.lang,\
+    org.apache.commons.logging,\
+    org.apache.ws.commons.util,\
+    org.apache.xml.resolver,\
+    org.apache.xmlrpc,\
+    org.eclipse.core.contenttype,\
+    org.eclipse.core.jobs,\
+    org.eclipse.core.net,\
+    org.eclipse.core.runtime,\
+    org.eclipse.core.runtime.compatibility.auth,\
+    org.eclipse.equinox.app,\
+    org.eclipse.equinox.common,\
+    org.eclipse.equinox.preferences,\
+    org.eclipse.equinox.registry,\
+    org.eclipse.equinox.security,\
+    org.eclipse.jgit,\
+    org.eclipse.mylyn.bugzilla.core,\
+    org.eclipse.mylyn.commons.core,\
+    org.eclipse.mylyn.commons.net,\
+    org.eclipse.mylyn.commons.xmlrpc,\
+    org.eclipse.mylyn.tasks.core,\
+    org.mozilla.rhino.patched,\
+    org.netbeans.api.debugger,\
+    org.netbeans.api.java.classpath,\
+    org.netbeans.api.xml,\
+    org.netbeans.core.browser,\
+    org.netbeans.core.execution,\
+    org.netbeans.core.ide,\
+    org.netbeans.core.io.ui,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.nativeaccess,\
+    org.netbeans.core.osgi,\
+    org.netbeans.lib.cvsclient,\
+    org.netbeans.lib.terminalemulator,\
+    org.netbeans.libs.antlr3.runtime,\
+    org.netbeans.libs.bytelist,\
+    org.netbeans.libs.commons_net,\
+    org.netbeans.libs.freemarker,\
+    org.netbeans.libs.git,\
+    org.netbeans.libs.ini4j,\
+    org.netbeans.libs.jaxb,\
+    org.netbeans.libs.jsr223,\
+    org.netbeans.libs.junit4,\
+    org.netbeans.libs.jvyamlb,\
+    org.netbeans.libs.lucene,\
+    org.netbeans.libs.smack,\
+    org.netbeans.libs.svnClientAdapter,\
+    org.netbeans.libs.svnClientAdapter.javahl,\
+    org.netbeans.libs.svnClientAdapter.svnkit,\
+    org.netbeans.libs.swingx,\
+    org.netbeans.libs.xerces,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.bugtracking,\
+    org.netbeans.modules.bugtracking.bridge,\
+    org.netbeans.modules.bugzilla,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.csl.api,\
+    org.netbeans.modules.css.editor,\
+    org.netbeans.modules.css.lib,\
+    org.netbeans.modules.css.visual,\
+    org.netbeans.modules.db,\
+    org.netbeans.modules.db.core,\
+    org.netbeans.modules.db.dataview,\
+    org.netbeans.modules.db.drivers,\
+    org.netbeans.modules.db.kit,\
+    org.netbeans.modules.db.metadata.model,\
+    org.netbeans.modules.db.mysql,\
+    org.netbeans.modules.db.sql.editor,\
+    org.netbeans.modules.db.sql.visualeditor,\
+    org.netbeans.modules.dbapi,\
+    org.netbeans.modules.defaults,\
+    org.netbeans.modules.derby,\
+    org.netbeans.modules.dlight.nativeexecution,\
+    org.netbeans.modules.dlight.terminal,\
+    org.netbeans.modules.editor.bookmarks,\
+    org.netbeans.modules.editor.bracesmatching,\
+    org.netbeans.modules.editor.codetemplates,\
+    org.netbeans.modules.editor.completion,\
+    org.netbeans.modules.editor.guards,\
+    org.netbeans.modules.editor.indent.project,\
+    org.netbeans.modules.editor.kit,\
+    org.netbeans.modules.editor.macros,\
+    org.netbeans.modules.editor.structure,\
+    org.netbeans.modules.extbrowser,\
+    org.netbeans.modules.extexecution,\
+    org.netbeans.modules.extexecution.destroy,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.git,\
+    org.netbeans.modules.glassfish.common,\
+    org.netbeans.modules.gototest,\
+    org.netbeans.modules.gsf.codecoverage,\
+    org.netbeans.modules.gsf.testrunner,\
+    org.netbeans.modules.html,\
+    org.netbeans.modules.html.editor,\
+    org.netbeans.modules.html.editor.lib,\
+    org.netbeans.modules.html.lexer,\
+    org.netbeans.modules.html.parser,\
+    org.netbeans.modules.html.validation,\
+    org.netbeans.modules.httpserver,\
+    org.netbeans.modules.hudson,\
+    org.netbeans.modules.hudson.git,\
+    org.netbeans.modules.hudson.mercurial,\
+    org.netbeans.modules.hudson.subversion,\
+    org.netbeans.modules.hudson.tasklist,\
+    org.netbeans.modules.ide.kit,\
+    org.netbeans.modules.image,\
+    org.netbeans.modules.javascript.editing,\
+    org.netbeans.modules.javascript.hints,\
+    org.netbeans.modules.javascript.kit,\
+    org.netbeans.modules.javascript.refactoring,\
+    org.netbeans.modules.jellytools.ide,\
+    org.netbeans.modules.jumpto,\
+    org.netbeans.modules.keyring.impl,\
+    org.netbeans.modules.languages,\
+    org.netbeans.modules.languages.diff,\
+    org.netbeans.modules.languages.manifest,\
+    org.netbeans.modules.languages.yaml,\
+    org.netbeans.modules.lexer.nbbridge,\
+    org.netbeans.modules.localhistory,\
+    org.netbeans.modules.mercurial,\
+    org.netbeans.modules.netbinox,\
+    org.netbeans.modules.parsing.api,\
+    org.netbeans.modules.parsing.lucene,\
+    org.netbeans.modules.print.editor,\
+    org.netbeans.modules.project.ant,\
+    org.netbeans.modules.project.libraries,\
+    org.netbeans.modules.projectui,\
+    org.netbeans.modules.projectui.buildmenu,\
+    org.netbeans.modules.projectuiapi,\
+    org.netbeans.modules.properties,\
+    org.netbeans.modules.properties.syntax,\
+    org.netbeans.modules.refactoring.api,\
+    org.netbeans.modules.schema2beans,\
+    org.netbeans.modules.server,\
+    org.netbeans.modules.servletapi,\
+    org.netbeans.modules.spellchecker,\
+    org.netbeans.modules.spellchecker.apimodule,\
+    org.netbeans.modules.spellchecker.bindings.htmlxml,\
+    org.netbeans.modules.spellchecker.bindings.properties,\
+    org.netbeans.modules.spellchecker.dictionary_en,\
+    org.netbeans.modules.spellchecker.kit,\
+    org.netbeans.modules.spi.actions,\
+    org.netbeans.modules.subversion,\
+    org.netbeans.modules.swing.validation,\
+    org.netbeans.modules.target.iterator,\
+    org.netbeans.modules.tasklist.kit,\
+    org.netbeans.modules.tasklist.projectint,\
+    org.netbeans.modules.tasklist.todo,\
+    org.netbeans.modules.tasklist.ui,\
+    org.netbeans.modules.terminal,\
+    org.netbeans.modules.usersguide,\
+    org.netbeans.modules.utilities,\
+    org.netbeans.modules.utilities.project,\
+    org.netbeans.modules.versioning,\
+    org.netbeans.modules.versioning.indexingbridge,\
+    org.netbeans.modules.versioning.system.cvss.installer,\
+    org.netbeans.modules.versioning.util,\
+    org.netbeans.modules.web.client.tools.api,\
+    org.netbeans.modules.web.common,\
+    org.netbeans.modules.web.indent,\
+    org.netbeans.modules.xml,\
+    org.netbeans.modules.xml.axi,\
+    org.netbeans.modules.xml.catalog,\
+    org.netbeans.modules.xml.core,\
+    org.netbeans.modules.xml.jaxb.api,\
+    org.netbeans.modules.xml.lexer,\
+    org.netbeans.modules.xml.multiview,\
+    org.netbeans.modules.xml.retriever,\
+    org.netbeans.modules.xml.schema.completion,\
+    org.netbeans.modules.xml.schema.model,\
+    org.netbeans.modules.xml.tax,\
+    org.netbeans.modules.xml.text,\
+    org.netbeans.modules.xml.tools,\
+    org.netbeans.modules.xml.wsdl.model,\
+    org.netbeans.modules.xml.xam,\
+    org.netbeans.modules.xml.xdm,\
+    org.netbeans.modules.xsl,\
+    org.netbeans.spi.debugger.ui,\
+    org.netbeans.spi.editor.hints,\
+    org.netbeans.spi.navigator,\
+    org.netbeans.spi.palette,\
+    org.netbeans.spi.tasklist,\
+    org.netbeans.spi.viewmodel,\
+    org.netbeans.swing.dirchooser,\
+    org.openide.compat,\
+    org.openide.execution,\
+    org.openide.options,\
+    org.openide.util.enumerations
+## Not disabled because of NetBeans bug 206347:
+## Applications not using OSGi don't start on NbP 7.1
+#   org.netbeans.core.netigso,\
+#   org.netbeans.libs.felix,\
+#   org.netbeans.libs.osgi,\
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>at.ssw.visualizer.cfg</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.oracle.graal.visualizer.editor</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.oracle.graal.visualizer.sharedactions</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.eclipse.draw2d</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.jdesktop.layout</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.4.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.api.visual</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>2.9.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.options.api</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.5</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.40.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.actions</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.6.1.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.11.1.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.dialogs</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.5</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.loaders</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.5</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.nodes</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.2.0.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.9.0.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.3.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.16</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>at.ssw.visualizer.cfg</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/META-INF/services/com.oracle.graal.visualizer.editor.CompilationViewerFactory	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+at.ssw.visualizer.cfg.CfgCompilationViewerFactory
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=ControlFlowEditor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/CfgCompilationViewer.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,235 @@
+/*
+ * 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 at.ssw.visualizer.cfg;
+
+import at.ssw.visualizer.cfg.action.*;
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import at.ssw.visualizer.cfg.graph.EdgeWidget;
+import at.ssw.visualizer.cfg.graph.NodeWidget;
+import at.ssw.visualizer.cfg.model.CfgEdge;
+import at.ssw.visualizer.cfg.model.CfgNode;
+import at.ssw.visualizer.cfg.preferences.CfgPreferences;
+import at.ssw.visualizer.cfg.preferences.FlagsSetting;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import com.oracle.graal.visualizer.editor.CompilationViewer;
+import com.sun.hotspot.igv.data.InputGraph;
+import java.awt.Color;
+import java.awt.Component;
+import java.beans.PropertyChangeEvent;
+import javax.swing.*;
+import javax.swing.border.Border;
+import org.netbeans.api.visual.widget.Widget;
+import org.openide.awt.Toolbar;
+import org.openide.util.Lookup;
+import org.openide.util.actions.SystemAction;
+import org.openide.util.lookup.Lookups;
+
+class CfgCompilationViewer implements CompilationViewer {
+
+    private CfgScene scene;
+    private JScrollPane jScrollPane;
+    private ControlFlowGraph cfg;
+    private JComponent myView;
+
+    public CfgCompilationViewer(InputGraph cfg) {
+        this.cfg = cfg;
+
+       // setIcon(ImageUtilities.loadImage("at/ssw/visualizer/cfg/icons/cfg.gif"));
+//        setName(cfg.getParent().getShortName());
+//        setToolTipText(cfg.getCompilation().getMethod() + " - " + cfg.getName());
+        // TODO(tw): Add title.
+
+        //panel setup
+        this.jScrollPane = new JScrollPane();
+        this.jScrollPane.setOpaque(true);
+        this.jScrollPane.setBorder(BorderFactory.createEmptyBorder());
+        this.jScrollPane.setViewportBorder(BorderFactory.createEmptyBorder());
+        this.scene = new CfgScene(jScrollPane, cfg);
+        this.myView = scene.createView();
+        this.jScrollPane.setViewportView(myView);
+        jScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
+        jScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
+        jScrollPane.getVerticalScrollBar().setEnabled(true);
+        jScrollPane.getHorizontalScrollBar().setEnabled(true);
+
+        //setup enviroment,register listeners
+        // TODO(tw): Add to lookup.
+//        selection = new Selection();
+//        selection.put(cfg);
+//        selection.put(scene);
+//        selection.addChangeListener(scene);
+
+        scene.validate();
+        scene.applyLayout();
+    }
+
+    public void propertyChange(PropertyChangeEvent evt) {
+        if (this.scene != null) {
+
+            String propName = evt.getPropertyName();
+            CfgPreferences prefs = CfgPreferences.getInstance();
+            switch (propName) {
+                case CfgPreferences.PROP_BACKGROUND_COLOR:
+                    scene.setBackground(prefs.getBackgroundColor());
+                    scene.revalidate();
+                    break;
+                case CfgPreferences.PROP_NODE_COLOR:
+                    for (NodeWidget nw : scene.getNodeWidgets()) {
+                        //only change the node color if its not a custom color
+                        if (!nw.isNodeColorCustomized()) {
+                            nw.setNodeColor(prefs.getNodeColor(), false);
+                        }
+                    }
+                    break;
+                case CfgPreferences.PROP_EDGE_COLOR:
+                    for (CfgEdge e : scene.getEdges()) {
+                        if (!e.isBackEdge() && !e.isXhandler()) {
+                            EdgeWidget w = (EdgeWidget) scene.findWidget(e);
+                            w.setLineColor(prefs.getEdgeColor());
+                        }
+                    }
+                    break;
+                case CfgPreferences.PROP_BACK_EDGE_COLOR:
+                    for (CfgEdge e : scene.getEdges()) {
+                        if (e.isBackEdge()) {
+                            EdgeWidget w = (EdgeWidget) scene.findWidget(e);
+                            w.setLineColor(prefs.getBackedgeColor());
+                        }
+                    }
+                    break;
+                case CfgPreferences.PROP_EXCEPTION_EDGE_COLOR:
+                    for (CfgEdge e : scene.getEdges()) {
+                        if (e.isXhandler()) {
+                            EdgeWidget w = (EdgeWidget) scene.findWidget(e);
+                            w.setLineColor(prefs.getExceptionEdgeColor());
+                        }
+                    }
+                    break;
+                case CfgPreferences.PROP_BORDER_COLOR:
+                    for (CfgNode n : scene.getNodes()) {
+                        NodeWidget nw = (NodeWidget) scene.findWidget(n);
+                        nw.setBorderColor(prefs.getBorderColor());
+                    }
+                    break;
+                case CfgPreferences.PROP_TEXT_FONT:
+                    for (CfgNode n : scene.getNodes()) {
+                        NodeWidget nw = (NodeWidget) scene.findWidget(n);
+                        nw.adjustFont(prefs.getTextFont());
+                    }
+                    break;
+                case CfgPreferences.PROP_TEXT_COLOR:
+                    for (CfgNode n : scene.getNodes()) {
+                        NodeWidget nw = (NodeWidget) scene.findWidget(n);
+                        nw.setForeground(prefs.getTextColor());
+                    }
+                    break;
+                case CfgPreferences.PROP_FLAGS:
+                    FlagsSetting fs = CfgPreferences.getInstance().getFlagsSetting();
+                    for (CfgNode n : scene.getNodes()) {
+                        NodeWidget nw = (NodeWidget) scene.findWidget(n);
+                        Color nodeColor = fs.getColor(n.getBasicBlock().getFlags());
+                        if (nodeColor != null) {
+                            nw.setNodeColor(nodeColor, true);
+                        } else {
+                            nw.setNodeColor(CfgPreferences.getInstance().getNodeColor(), false);
+                        }
+                    }
+                    break;
+                case CfgPreferences.PROP_SELECTION_COLOR_BG:
+                case CfgPreferences.PROP_SELECTION_COLOR_FG:
+                    for (CfgNode n : scene.getNodes()) {
+                        Widget w = scene.findWidget(n);
+                        w.revalidate();
+                    }
+                    break;
+            }
+            scene.validate();
+        }
+
+    }
+
+    /*@Override
+    public Component getToolBarComponent() {
+        Toolbar tb = new Toolbar("CfgToolbar");
+
+        tb.setBorder((Border) UIManager.get("Nb.Editor.Toolbar.border"));
+
+        //zoomin/zoomout buttons
+        tb.add(SystemAction.get(ZoominAction.class).getToolbarPresenter());
+        tb.add(SystemAction.get(ZoomoutAction.class).getToolbarPresenter());
+        tb.addSeparator();
+
+        //router buttons
+        ButtonGroup routerButtons = new ButtonGroup();
+        UseDirectLineRouterAction direct = SystemAction.get(UseDirectLineRouterAction.class);
+        UseBezierRouterAction bezier = SystemAction.get(UseBezierRouterAction.class);
+        JToggleButton button = (JToggleButton) direct.getToolbarPresenter();
+        button.getModel().setGroup(routerButtons);
+        button.setSelected(true);
+        tb.add(button);
+        button = (JToggleButton) bezier.getToolbarPresenter();
+        button.getModel().setGroup(routerButtons);
+        tb.add(button);
+        tb.addSeparator();
+
+        //layout buttons
+        tb.add(SystemAction.get(HierarchicalNodeLayoutAction.class).getToolbarPresenter());
+        tb.add(SystemAction.get(HierarchicalCompoundLayoutAction.class).getToolbarPresenter());
+
+        tb.addSeparator();
+        tb.add(SystemAction.get(ShowAllAction.class).getToolbarPresenter());
+        tb.addSeparator();
+
+        //cluster button
+        tb.add(SystemAction.get(SwitchLoopClustersAction.class).getToolbarPresenter());
+        tb.addSeparator();
+
+        //show/hide edge button
+        tb.add(SystemAction.get(ShowEdgesAction.class).getToolbarPresenter());
+        tb.add(SystemAction.get(HideEdgesAction.class).getToolbarPresenter());
+        tb.addSeparator();
+
+        //color button       
+        JComponent colorButton = SystemAction.get(ColorAction.class).getToolbarPresenter();
+        scene.addCfgEventListener((CfgEventListener) colorButton);
+        tb.add(colorButton);
+
+        //export button           
+        tb.add(SystemAction.get(ExportAction.class).getToolbarPresenter());
+        tb.doLayout();
+
+        return tb;
+    }*/
+
+    @Override
+    public Lookup getLookup() {
+        return Lookups.fixed(scene);
+    }
+
+    @Override
+    public Component getComponent() {
+        return jScrollPane;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/CfgCompilationViewerFactory.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,26 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package at.ssw.visualizer.cfg;
+
+import com.oracle.graal.visualizer.editor.CompilationViewer;
+import com.oracle.graal.visualizer.editor.CompilationViewerFactory;
+import com.oracle.graal.visualizer.editor.DiagramViewModel;
+import com.oracle.graal.visualizer.editor.SplitCompilationViewerFactory;
+import com.sun.hotspot.igv.data.InputGraph;
+
+public class CfgCompilationViewerFactory extends SplitCompilationViewerFactory {
+
+    @Override
+    public String getName() {
+        return "CFG";
+    }
+
+    @Override
+    protected CompilationViewer createViewer(InputGraph graph) {
+        return new CfgCompilationViewer(graph);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/CfgEditorContext.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,10 @@
+
+package at.ssw.visualizer.cfg;
+
+public abstract class CfgEditorContext {
+      
+    public static final int LAYOUT_HIERARCHICALNODELAYOUT = 1;
+    public static final int LAYOUT_HIERARCHICALCOMPOUNDLAYOUT = 2;
+       
+    public static final int MAX_AUTOEDGESVISIBLE = 8;            
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/action/AbstractCfgEditorAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+package at.ssw.visualizer.cfg.action;
+
+
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JMenuItem;
+import org.openide.util.Utilities;
+import org.openide.util.actions.CallableSystemAction;
+
+/**
+ * The common superclass of all concrete actions related to the CFG visualizer.
+ *
+ * @author Bernhard Stiftner
+ * @author Rumpfhuber Stefan
+ */
+public abstract class AbstractCfgEditorAction extends CallableSystemAction {
+
+    CfgScene topComponent = null;
+    
+    public AbstractCfgEditorAction() {        
+        setEnabled(false);
+
+    }
+       
+    protected CfgScene getEditor() {
+        return Utilities.actionsGlobalContext().lookup(CfgScene.class);
+    }
+    
+    @Override
+    public JMenuItem getMenuPresenter() {
+        return new JMenuItem(this);
+    }
+
+   
+    @Override
+    public JComponent getToolbarPresenter() {
+        JButton b = new JButton(this);
+        if (getIcon() != null) {
+            b.setText(null);
+            b.setToolTipText(getName());
+        }
+        return b;
+    }
+
+   
+    @Override
+    public JMenuItem getPopupPresenter() {       
+        return new JMenuItem(this);
+    }
+    
+   
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/action/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+CTL_SomeAction=test
+CTL_SomeAction2=test
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/action/HideEdgesAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,52 @@
+/*
+ * 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 at.ssw.visualizer.cfg.action;
+
+
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionRegistration;
+
+@ActionID(id = "at.ssw.visualizer.cfg.action.HideEdges", category = "View")
+@ActionRegistration(displayName = "Hide Edges", iconBase="at/ssw/visualizer/cfg/icons/hideedges.gif")
+@ActionReference(path = "CompilationViewer/CFG/Actions", position = 180)
+public class HideEdgesAction implements ActionListener {
+
+    private List<CfgScene> scenes;
+    
+    public HideEdgesAction(List<CfgScene> scenes) {
+        this.scenes = scenes;
+    }
+    
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        for (CfgScene scene : scenes) {
+             scene.setSelectedEdgesVisibility(false);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/action/HierarchicalCompoundLayoutAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,52 @@
+/*
+ * 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 at.ssw.visualizer.cfg.action;
+
+import at.ssw.visualizer.cfg.CfgEditorContext;
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionRegistration;
+
+
+@ActionID(id = "at.ssw.visualizer.cfg.action.HierarchicalCompoundLayout", category = "View")
+@ActionRegistration(displayName = "Compound Layout", iconBase="at/ssw/visualizer/cfg/icons/arrangeloop.gif")
+@ActionReference(path = "CompilationViewer/CFG/Actions", position = 150)
+public class HierarchicalCompoundLayoutAction implements ActionListener {
+    List<CfgScene> scenes;
+    
+    public HierarchicalCompoundLayoutAction(List<CfgScene> scenes) {
+        this.scenes = scenes;
+    }
+    
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        for (CfgScene s : scenes) {
+            s.setSceneLayout(CfgEditorContext.LAYOUT_HIERARCHICALCOMPOUNDLAYOUT);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/action/HierarchicalNodeLayoutAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,52 @@
+/*
+ * 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 at.ssw.visualizer.cfg.action;
+
+import at.ssw.visualizer.cfg.CfgEditorContext;
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionRegistration;
+
+
+@ActionID(id = "at.ssw.visualizer.cfg.action.HierarchicalNodeLayout", category = "View")
+@ActionRegistration(displayName = "Layout", iconBase="at/ssw/visualizer/cfg/icons/arrangehier.gif")
+@ActionReference(path = "CompilationViewer/CFG/Actions", position = 160)
+public class HierarchicalNodeLayoutAction implements ActionListener {
+    List<CfgScene> scenes;
+    
+    public HierarchicalNodeLayoutAction(List<CfgScene> scenes) {
+        this.scenes = scenes;
+    }
+    
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        for (CfgScene s : scenes) {
+            s.setSceneLayout(CfgEditorContext.LAYOUT_HIERARCHICALNODELAYOUT);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/action/ShowEdgesAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,52 @@
+/*
+ * 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 at.ssw.visualizer.cfg.action;
+
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionRegistration;
+
+
+@ActionID(id = "ShowEdges", category = "View")
+@ActionRegistration(displayName = "Show Edges", iconBase="at/ssw/visualizer/cfg/icons/showedges.gif")
+@ActionReference(path = "CompilationViewer/CFG/Actions", position = 170)
+public class ShowEdgesAction implements ActionListener {
+
+    private List<CfgScene> scenes;
+    
+    public ShowEdgesAction(List<CfgScene> scenes) {
+        this.scenes = scenes;
+    }
+    
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        for (CfgScene scene : scenes) {
+             scene.setSelectedEdgesVisibility(true);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/graph/CfgScene.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,836 @@
+package at.ssw.visualizer.cfg.graph;
+
+import at.ssw.visualizer.cfg.model.CfgEdge;
+import at.ssw.visualizer.cfg.CfgEditorContext;
+import at.ssw.visualizer.cfg.action.HideEdgesAction;
+import at.ssw.visualizer.cfg.action.ShowEdgesAction;
+import at.ssw.visualizer.cfg.graph.layout.HierarchicalCompoundLayout;
+import at.ssw.visualizer.cfg.graph.layout.HierarchicalNodeLayout;
+import at.ssw.visualizer.cfg.model.CfgEnv;
+import at.ssw.visualizer.cfg.model.CfgNode;
+import at.ssw.visualizer.cfg.model.LoopInfo;
+import at.ssw.visualizer.cfg.preferences.CfgPreferences;
+import at.ssw.visualizer.cfg.visual.PolylineRouter;
+import at.ssw.visualizer.cfg.visual.PolylineRouterV2;
+import at.ssw.visualizer.cfg.visual.WidgetCollisionCollector;
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import com.oracle.graal.visualizer.sharedactions.ZoomCookie;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.event.ActionEvent;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.prefs.PreferenceChangeEvent;
+import java.util.prefs.PreferenceChangeListener;
+import java.util.prefs.Preferences;
+import javax.swing.AbstractAction;
+import javax.swing.JComponent;
+import javax.swing.JMenu;
+import javax.swing.JPopupMenu;
+import javax.swing.JScrollPane;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.EventListenerList;
+import org.netbeans.api.visual.action.ActionFactory;
+import org.netbeans.api.visual.action.MoveProvider;
+import org.netbeans.api.visual.action.PopupMenuProvider;
+import org.netbeans.api.visual.action.RectangularSelectDecorator;
+import org.netbeans.api.visual.action.RectangularSelectProvider;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.anchor.Anchor;
+import org.netbeans.api.visual.anchor.AnchorFactory;
+import org.netbeans.api.visual.graph.GraphScene;
+import org.netbeans.api.visual.graph.layout.GraphLayout;
+import org.netbeans.api.visual.layout.LayoutFactory;
+import org.netbeans.api.visual.layout.SceneLayout;
+import org.netbeans.api.visual.router.Router;
+import org.netbeans.api.visual.router.Router.*;
+import org.netbeans.api.visual.router.RouterFactory;
+import org.netbeans.api.visual.widget.ConnectionWidget;
+import org.netbeans.api.visual.widget.LayerWidget;
+import org.netbeans.api.visual.widget.Widget;
+import org.openide.util.NbPreferences;
+import org.openide.util.actions.SystemAction;
+
+public final class CfgScene extends GraphScene<CfgNode, CfgEdge> implements ChangeListener, ZoomCookie {
+
+    private LayerWidget mainLayer = new LayerWidget(this);
+    private LayerWidget connectionLayer = new LayerWidget(this);
+    private LayerWidget interractionLayer = new LayerWidget(this);
+    private LayerWidget clusterLayer = new LayerWidget(this);
+    private Set<CfgNode> selectedNodes = Collections.<CfgNode>emptySet();
+    private Map<Integer, LoopClusterWidget> loopidx2clusterwidget = new HashMap<>();
+    private Map<CfgNode, EdgeSwitchWidget> inputSwitches = new HashMap<>();
+    private Map<CfgNode, EdgeSwitchWidget> outputSwitches = new HashMap<>();
+    private WidgetAction moveAction = ActionFactory.createMoveAction(ActionFactory.createFreeMoveStrategy(), this.createMoveProvider());
+    private SceneLayout sceneLayout;
+    private CfgEnv env;
+    private int currentLayout = -1;
+    private JScrollPane scrollPane;
+    private WidgetAction contextPopupAction = this.createContextMenuAction(this);
+    private List<NodeWidget> nodeWidgets = null;
+    private boolean loopClustersVisible = true;
+    private static String PREFERENCE_LOOP_CLUSTER = "loopClusters";
+    private static String PREFERENCE_ROUTER = "router";
+    private static String PREFERENCE_LAYOUT = "layout";
+
+    public static Preferences getPreferences() {
+        return NbPreferences.forModule(CfgScene.class);
+    }
+    private final PreferenceChangeListener preferenceChangeListener = new PreferenceChangeListener() {
+        @Override
+        public void preferenceChange(PreferenceChangeEvent evt) {
+            if (evt.getKey().equals(PREFERENCE_ROUTER)) {
+                setUseBezierRouter(Boolean.parseBoolean(evt.getNewValue()));
+            } else if (evt.getKey().equals(PREFERENCE_LOOP_CLUSTER)) {
+                setLoopWidgets(Boolean.parseBoolean(evt.getNewValue()));
+            }
+        }
+    };
+
+    public CfgScene(final JScrollPane scrollPane, final ControlFlowGraph cfg) {
+        addChild(clusterLayer);
+        addChild(mainLayer);
+        addChild(interractionLayer);
+        addChild(connectionLayer);
+        this.scrollPane = scrollPane;
+        this.loadModel(new CfgEnv(cfg));
+        this.getInputBindings().setZoomActionModifiers(0);
+        this.getActions().addAction(ActionFactory.createMouseCenteredZoomAction(1.1));
+        this.getActions().addAction(ActionFactory.createPanAction());
+        this.getActions().addAction(ActionFactory.createRectangularSelectAction(
+                this.createSelectDecorator(this),
+                interractionLayer,
+                this.createRectangularSelectProvider()));
+        this.getActions().addAction(this.contextPopupAction);
+        this.addSceneListener(createSceneListener(this));
+        this.validate();
+
+        getPreferences().addPreferenceChangeListener(preferenceChangeListener);
+        this.loadDefaults();
+    }
+
+    private void loadModel(CfgEnv cfgenv) {
+        this.env = cfgenv;
+        for (CfgNode n : env.getNodes()) {
+            addNode(n);
+        }
+        for (CfgEdge e : env.getEdges()) {
+            addEdge(e);
+            setEdgeSource(e, e.getSourceNode());
+            setEdgeTarget(e, e.getTargetNode());
+        }
+        this.stackLoops(cfgenv.getLoopMap());
+        this.autoHideEdges();
+    }
+
+    public void loadDefaults() {
+        CfgPreferences prefs = CfgPreferences.getInstance();
+        this.setBackground(prefs.getBackgroundColor());
+        setUseBezierRouter(getPreferences().getBoolean(PREFERENCE_ROUTER, true));
+        setLoopWidgets(getPreferences().getBoolean(PREFERENCE_LOOP_CLUSTER, true));
+        setSceneLayout(getPreferences().getInt(PREFERENCE_LAYOUT, CfgEditorContext.LAYOUT_HIERARCHICALNODELAYOUT));
+    }
+
+    //sets the parent Widget of all LoopClusterWidgets
+    private void stackLoops(Map<CfgNode, LoopInfo> map) {
+        this.clusterLayer.removeChildren();
+
+        Set<LoopInfo> cache = new HashSet<>();
+        for (LoopInfo info : map.values()) {
+            if (cache.contains(info)) {
+                continue;
+            }
+            LoopClusterWidget widget = this.loopidx2clusterwidget.get(info.getLoopIndex());
+            LoopInfo parent = info.getParent();
+            while (parent != null) {
+                LoopClusterWidget parentWidget = this.loopidx2clusterwidget.get(parent.getLoopIndex());
+                assert parentWidget != null;
+                if (widget.getParentWidget() != null) {
+                    widget.removeFromParent();
+                }
+                parentWidget.addChild(widget);
+                widget = parentWidget;
+                parent = parent.getParent();
+            }
+            widget.removeFromParent();
+            this.clusterLayer.addChild(widget);//parent == null => parent is clusterlayer
+        }
+    }
+
+    //hide in|output edges 
+    private void autoHideEdges() {
+        for (CfgNode n : this.getNodes()) {
+            int fanin = n.getInputEdges().length;
+            int fanout = n.getOutputEdges().length;
+            if (fanin > CfgEditorContext.MAX_AUTOEDGESVISIBLE) {
+                assert (inputSwitches.containsKey(n));
+                if (this.inputSwitches.containsKey(n)) {
+                    EdgeSwitchWidget esw = this.inputSwitches.get(n);
+                    esw.changeEdgeVisibility(false);
+                }
+            }
+            if (fanout > CfgEditorContext.MAX_AUTOEDGESVISIBLE) {
+                if (this.outputSwitches.containsKey(n)) {
+                    EdgeSwitchWidget esw = this.outputSwitches.get(n);
+                    esw.changeEdgeVisibility(false);
+                }
+            }
+        }
+
+    }
+
+    //apply current cfggraphscene layout  
+    public void applyLayout() {
+        this.sceneLayout.invokeLayoutImmediately();
+    }
+
+    //returns a Set with the currently selected Nodes    
+    public Set<CfgNode> getSelectedNodes() {
+        return Collections.<CfgNode>unmodifiableSet(selectedNodes);
+    }
+
+    public Map<Integer, LoopClusterWidget> getLoopidx2clusterwidget() {
+        return loopidx2clusterwidget;
+    }
+
+    /**
+     * Sets the color of the currently selected Nodes If the supplied color is null the default color will be used
+     */
+    public void setSelectedNodesColor(Color color) {
+        if (color == null) { //set default color
+            CfgPreferences prefs = CfgPreferences.getInstance();
+            boolean customized = false;
+            for (CfgNode n : this.selectedNodes) {
+                color = null;
+                color = prefs.getFlagsSetting().getColor(n.getBasicBlock().getFlags());
+                customized = (color != null);
+                NodeWidget nw = (NodeWidget) this.findWidget(n);
+                nw.setNodeColor((customized) ? color : prefs.getNodeColor(), customized);
+            }
+        } else {
+            for (CfgNode n : this.selectedNodes) {
+                NodeWidget nw = (NodeWidget) this.findWidget(n);
+                nw.setNodeColor(color, true);
+            }
+        }
+        this.validate();
+    }
+
+    public void setSelectedEdgesVisibility(boolean visible) {
+        for (CfgNode n : this.selectedNodes) {
+            EdgeSwitchWidget in = this.inputSwitches.get(n);
+            EdgeSwitchWidget out = this.outputSwitches.get(n);
+            if (in != null) {
+                in.changeEdgeVisibility(visible);
+            }
+            if (out != null) {
+                out.changeEdgeVisibility(visible);
+            }
+        }
+        this.validate();
+    }
+
+    public EdgeSwitchWidget getInputSwitch(CfgNode n) {
+        return this.inputSwitches.get(n);
+    }
+
+    public EdgeSwitchWidget getOutputSwitch(CfgNode n) {
+        return this.outputSwitches.get(n);
+    }
+
+    public CfgEnv getCfgEnv() {
+        return env;
+    }
+
+    public boolean isLoopClusterVisible() {
+        return loopClustersVisible;
+    }
+
+    public void setLoopWidgets(boolean visible) {
+        for (Widget w : this.loopidx2clusterwidget.values()) {
+            w.setVisible(visible);
+            w.revalidate();
+        }
+        this.loopClustersVisible = visible;
+        this.validate();
+        getPreferences().putBoolean(PREFERENCE_LOOP_CLUSTER, visible);
+    }
+    
+    private void setUseBezierRouter(boolean value) {
+        Router router;
+        if (value) {
+            router = new PolylineRouterV2(new WidgetCollisionCollector() {
+                @Override
+                public void collectCollisions(List<Widget> collisions) {
+                    collisions.addAll(getNodeWidgets());
+                }
+            });
+        } else {
+            router = RouterFactory.createDirectRouter();
+        }
+
+        for (CfgEdge e : this.getEdges()) {
+            EdgeWidget ew = (EdgeWidget) this.findWidget(e);
+            ew.setRouter(router);
+        }
+        this.validate();
+        getPreferences().putBoolean(PREFERENCE_ROUTER, value);
+    }
+
+    public Collection<NodeWidget> getNodeWidgets() {
+        if (nodeWidgets != null && nodeWidgets.size() == this.getNodes().size()) {
+            return nodeWidgets;
+        }
+
+        List<NodeWidget> widgets = new ArrayList<>();
+        for (CfgNode n : this.getNodes()) {
+            NodeWidget w = (NodeWidget) this.findWidget(n);
+            widgets.add(w);
+        }
+
+        nodeWidgets = Collections.unmodifiableList(widgets);
+        return widgets;
+    }
+
+    public void setSceneLayout(int newLayout) {
+
+        GraphLayout<CfgNode, CfgEdge> graphLayout = null;
+
+        switch (newLayout) {
+            case CfgEditorContext.LAYOUT_HIERARCHICALNODELAYOUT:
+                graphLayout = new HierarchicalNodeLayout(this);
+                break;
+
+            case CfgEditorContext.LAYOUT_HIERARCHICALCOMPOUNDLAYOUT:
+                graphLayout = new HierarchicalCompoundLayout(this);
+                break;
+        }
+
+        this.currentLayout = newLayout;
+        if (graphLayout != null) {
+            this.sceneLayout = LayoutFactory.createSceneGraphLayout(this, graphLayout);
+        }
+        
+        getPreferences().putInt(PREFERENCE_LAYOUT, newLayout);
+        sceneLayout.invokeLayoutImmediately();
+    }
+
+    @Override
+    protected void attachEdgeSourceAnchor(CfgEdge edge, CfgNode oldSourceNode, CfgNode sourceNode) {
+        Anchor sourceAnchor;
+        EdgeWidget edgeWidget = (EdgeWidget) findWidget(edge);
+        Widget sourceWidget = findWidget(sourceNode);
+
+        if (edge.isSymmetric()) {
+            sourceAnchor = new SymmetricAnchor(sourceWidget, true, true);
+        } else {
+            sourceAnchor = AnchorFactory.createRectangularAnchor(sourceWidget);
+        }
+        edgeWidget.setSourceAnchor(sourceAnchor);
+    }
+
+    @Override
+    protected void attachEdgeTargetAnchor(CfgEdge edge, CfgNode oldtarget, CfgNode targetNode) {
+        Anchor targetAnchor;
+        ConnectionWidget edgeWidget = (ConnectionWidget) findWidget(edge);
+        Widget targetWidget = findWidget(targetNode);
+
+        if (edge.isSymmetric()) {
+            targetAnchor = new SymmetricAnchor(targetWidget, true, false);
+        } else {
+            targetAnchor = AnchorFactory.createRectangularAnchor(targetWidget);
+        }
+        edgeWidget.setTargetAnchor(targetAnchor);
+    }
+
+    @Override
+    protected Widget attachEdgeWidget(CfgEdge edge) {
+        EdgeWidget widget = new EdgeWidget(this, edge);
+        connectionLayer.addChild(widget);
+        attachSourceSwitchWidget(edge);
+        attachTargetSwitchWidget(edge);
+        return widget;
+    }
+
+    @Override
+    protected Widget attachNodeWidget(CfgNode node) {
+        this.nodeWidgets = null;
+
+        NodeWidget nw = new NodeWidget(this, node);
+        WidgetAction.Chain actions = nw.getActions();
+        actions.addAction(this.contextPopupAction);
+        actions.addAction(this.moveAction);
+        actions.addAction(this.createObjectHoverAction());
+
+        if (node.isLoopMember()) {
+            LoopClusterWidget loopWidget = this.attachLoopMember(node);
+            loopWidget.addMember(nw);
+        }
+        mainLayer.addChild(nw);
+        return nw;
+    }
+
+    private LoopClusterWidget attachLoopMember(CfgNode node) {
+        LoopClusterWidget lw = this.loopidx2clusterwidget.get(node.getLoopIndex());
+        if (lw == null) {
+            lw = new LoopClusterWidget(this, node.getLoopDepth(), node.getLoopIndex());
+            this.loopidx2clusterwidget.put(node.getLoopIndex(), lw);
+            this.clusterLayer.addChild(lw);
+        }
+        return lw;
+    }
+
+    private boolean detachLoopMember(CfgNode node, NodeWidget nodeWidget) {
+        LoopClusterWidget rm = this.loopidx2clusterwidget.get(node.getLoopIndex());
+        if (rm == null) {
+            return false;//not added
+        }
+        if (rm.removeMember(nodeWidget)) {
+            if (rm.getMembers().isEmpty()) {
+                this.loopidx2clusterwidget.remove(rm.getLoopIndex());
+                List<Widget> childs = new ArrayList<>(rm.getChildren());
+                for (Widget w : childs) {//append stacked loopwidgets
+                    w.removeFromParent();
+                    rm.getParentWidget().addChild(w);
+                }
+                rm.removeFromParent();
+            }
+            return true;
+        }
+        return false;
+    }
+
+    //this function is not invoked by any class  of the module
+    //however to ensure that the edge switches are treatet corretly
+    //when a future version removes nodes it was implemented too.
+    @Override
+    protected void detachNodeWidget(CfgNode node, Widget nodeWidget) {
+        if (node.isLoopMember() && nodeWidget instanceof NodeWidget) {
+            this.detachLoopMember(node, (NodeWidget) nodeWidget);
+        }
+        super.detachNodeWidget(node, nodeWidget);
+        assert nodeWidget.getParentWidget() == null;
+        if (this.inputSwitches.containsKey(node)) {
+            EdgeSwitchWidget esw = this.inputSwitches.remove(node);
+            this.connectionLayer.removeChild(esw);
+        }
+        if (this.outputSwitches.containsKey(node)) {
+            EdgeSwitchWidget esw = this.outputSwitches.remove(node);
+            this.connectionLayer.removeChild(esw);
+        }
+    }
+
+    protected EdgeSwitchWidget attachSourceSwitchWidget(CfgEdge e) {
+        CfgNode sourceNode = e.getSourceNode();
+        NodeWidget sourceWidget = (NodeWidget) this.findWidget(sourceNode);
+        EdgeSwitchWidget out = outputSwitches.get(sourceNode);
+        if (out == null) {
+            out = new EdgeSwitchWidget(this, sourceWidget, true);
+            this.connectionLayer.addChild(out);
+            outputSwitches.put(sourceNode, out);
+        }
+        return out;
+    }
+
+    protected EdgeSwitchWidget attachTargetSwitchWidget(CfgEdge e) {
+        CfgNode targetNode = e.getTargetNode();
+        NodeWidget targetWidget = (NodeWidget) this.findWidget(targetNode);
+        EdgeSwitchWidget in = inputSwitches.get(targetNode);
+        if (in == null) {
+            in = new EdgeSwitchWidget(this, targetWidget, false);
+            this.connectionLayer.addChild(in);
+            inputSwitches.put(targetNode, in);
+        }
+        return in;
+    }
+
+    //resets the selection state of all NodeWidgets
+    private void cleanNodeSelection() {
+        if (!this.selectedNodes.isEmpty()) {
+            this.userSelectionSuggested(Collections.<CfgNode>emptySet(), false);
+            this.selectedNodes = Collections.<CfgNode>emptySet();
+            this.validate();
+        }
+    }
+
+    //sets the scene & global node selection
+    public void setNodeSelection(Set<CfgNode> newSelection) {
+        this.setSceneSelection(newSelection);
+        this.updateGlobalSelection();
+    }
+
+    //sets the scene selection
+    private void setSceneSelection(Set<CfgNode> newSelection) {
+        if (newSelection.equals(selectedNodes)) {
+            return;
+        }
+
+        this.selectedNodes = newSelection;
+
+        Set<Object> selectedObjects = new HashSet<>();
+
+        for (CfgNode n : newSelection) {
+            selectedObjects.addAll(this.findNodeEdges(n, true, true));
+        }
+        selectedObjects.addAll(newSelection);
+
+        //if the selection gets updated from a change in the block view
+        //the scene will be centered
+        if (selectionUpdating) {
+            this.centerSelection();
+        }
+
+        this.userSelectionSuggested(selectedObjects, false);
+        this.validate();
+    }
+
+    //updates selection of Block View
+    public void updateGlobalSelection() {
+        // TODO(tw): Add selection management.
+//        Selection selection = SelectionManager.getDefault().getCurSelection();
+//        ArrayList<BasicBlock> newBlocks = new ArrayList<BasicBlock>();
+//        for (CfgNode n : this.selectedNodes) {
+//            newBlocks.add(n.getBasicBlock());
+//        }
+//        BasicBlock[] curBlocks = newBlocks.toArray(new BasicBlock[newBlocks.size()]);     
+//        selection.put(curBlocks);
+    }
+    private boolean selectionUpdating = false;
+
+    //change of blockview selection   
+    public void stateChanged(ChangeEvent event) {
+        if (selectionUpdating) {
+            return;
+        }
+
+        selectionUpdating = true;
+
+        Object source = event.getSource();
+//        if(source instanceof Selection){
+//            Selection selection=(Selection) source;
+//            Set<CfgNode> newSelection = new HashSet<CfgNode>();
+//            BasicBlock[] newBlocks = selection.get(BasicBlock[].class);                  
+//            if (newBlocks != null) {
+//                for(BasicBlock b : newBlocks){
+//                    for(CfgNode n : this.getNodes()){
+//                        if(n.getBasicBlock() == b) newSelection.add(n);
+//                    }
+//                }
+//                this.setSceneSelection(newSelection);                               
+//            } 
+//        }       
+        selectionUpdating = false;
+        // TODO(tw): Add selection management.
+    }
+
+    //centers the viewport on the currently selected nodewidgets
+    private void centerSelection() {
+        Point sceneCenter = null;
+        Collection<CfgNode> nodes = this.selectedNodes;
+        if (nodes.size() == 0) {
+            nodes = this.getNodes();
+        }
+
+        for (CfgNode n : nodes) {
+            if (sceneCenter == null) {
+                sceneCenter = this.findWidget(n).getLocation();
+                continue;
+            }
+            Point location = this.findWidget(n).getLocation();
+            sceneCenter.x = (location.x + sceneCenter.x) / 2;
+            sceneCenter.y = (location.y + sceneCenter.y) / 2;
+        }
+
+        JComponent view = this.getView();
+        if (view != null) {
+            Rectangle viewBounds = view.getVisibleRect();
+
+            Point viewCenter = this.convertSceneToView(sceneCenter);
+
+            view.scrollRectToVisible(new Rectangle(
+                    viewCenter.x - viewBounds.width / 2,
+                    viewCenter.y - viewBounds.height / 2,
+                    viewBounds.width,
+                    viewBounds.height));
+        }
+    }
+
+    public void zoomScene() {
+        JScrollPane pane = scrollPane;
+        Rectangle prefBounds = this.getPreferredBounds();
+        Dimension viewDim = pane.getViewportBorderBounds().getSize();
+
+        double realwidth = (double) prefBounds.width * this.getZoomFactor();
+        double realheight = (double) prefBounds.height * this.getZoomFactor();
+
+        double zoomX = (double) viewDim.width / realwidth;
+        double zoomY = (double) viewDim.height / realheight;
+        double zoomFactor = Math.min(zoomX, zoomY);
+        this.setZoomFactor(zoomFactor * 0.9);
+    }
+
+    //Enables Antialiasing
+    @Override
+    public void paintChildren() {
+        Object anti = getGraphics().getRenderingHint(RenderingHints.KEY_ANTIALIASING);
+        Object textAnti = getGraphics().getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING);
+
+        getGraphics().setRenderingHint(
+                RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+        getGraphics().setRenderingHint(
+                RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+
+        super.paintChildren();
+
+        getGraphics().setRenderingHint(RenderingHints.KEY_ANTIALIASING, anti);
+        getGraphics().setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, textAnti);
+    }
+
+    //select provider for node selection
+    private RectangularSelectProvider createRectangularSelectProvider() {
+        return new RectangularSelectProvider() {
+
+            public void performSelection(Rectangle rectangle) {
+                HashSet<CfgNode> set = new HashSet<>();
+
+                //change to a rectangle with (x,offsetY) at the top left
+                if (rectangle.width < 0) {
+                    rectangle.x = rectangle.x + rectangle.width;
+                    rectangle.width *= -1;
+                }
+                if (rectangle.height < 0) {
+                    rectangle.y = rectangle.y + rectangle.height;
+                    rectangle.height *= -1;
+                }
+
+                for (NodeWidget n : getNodeWidgets()) {
+                    Point p = n.getLocation();
+                    if (p != null && rectangle.contains(p)) {
+                        set.add(n.getNodeModel());
+                    }
+                }
+                setNodeSelection(set);
+            }
+        };
+    }
+
+    //select decorator for node selection
+    private RectangularSelectDecorator createSelectDecorator(final CfgScene scene) {
+        return new RectangularSelectDecorator() {
+
+            public Widget createSelectionWidget() {
+                scene.cleanNodeSelection();//unselected all nodes
+                scene.revalidate();
+                return new SelectionWidget(getScene());
+            }
+        };
+    }
+
+    private MoveProvider createMoveProvider() {
+        return new MoveProvider() {
+
+            private HashMap<Widget, Point> originals = new HashMap<>();
+            private Point original = null;
+
+            public void movementStarted(Widget widget) {
+                originals.clear();
+                NodeWidget nw = (NodeWidget) widget;
+                if (selectedNodes.contains(nw.getNodeModel())) {//move current selection
+                    for (CfgNode n : selectedNodes) {
+                        Widget w = findWidget(n);
+                        originals.put(w, w.getLocation());
+                    }
+                } else {//a newly-selected node will be moved               
+                    CfgNode n = nw.getNodeModel();
+                    HashSet<CfgNode> selectedNode = new HashSet<>(1);
+                    selectedNode.add(n);
+                    setNodeSelection(selectedNode);
+                    originals.put(widget, widget.getPreferredLocation());
+                    widget.revalidate();
+                    validate();
+
+                }
+            }
+
+            public void movementFinished(Widget widget) {
+                NodeWidget nw = (NodeWidget) widget;
+                if (selectedNodes.contains(nw.getNodeModel())) {
+                    return;//to be able to move the current selection
+                }
+
+                HashSet<CfgNode> selectedNode = new HashSet<>(1);
+                selectedNode.add(nw.getNodeModel());
+                setNodeSelection(selectedNode);
+                originals.clear();
+                original = null;
+
+            }
+
+            public Point getOriginalLocation(Widget widget) {
+                if (original == null) {
+                    original = widget.getLocation();
+                }
+
+                return original;
+            }
+            //todo : find a cache algorithm which only routes edges
+            //which are intersected by bounds of the moved rectangle
+
+            public void setNewLocation(Widget widget, Point location) {
+                Point org = getOriginalLocation(widget);
+                int dx = location.x - org.x;
+                int dy = location.y - org.y;
+                for (Map.Entry<Widget, Point> entry : originals.entrySet()) {
+                    Point point = entry.getValue();
+                    entry.getKey().setPreferredLocation(new Point(point.x + dx, point.y + dy));
+                }
+                for (CfgEdge e : getEdges()) {
+                    EdgeWidget ew = (EdgeWidget) findWidget(e);
+                    if (ew.isVisible()) {
+                        ew.reroute();
+                    }
+                }
+            }
+        };
+    }
+
+    private WidgetAction createContextMenuAction(final CfgScene scene) {
+        return ActionFactory.createPopupMenuAction(new PopupMenuProvider() {
+
+            public JPopupMenu getPopupMenu(Widget widget, Point point) {
+                JPopupMenu menu = new JPopupMenu();
+                NodeWidget nw = null;
+                if (widget instanceof NodeWidget) {
+                    nw = (NodeWidget) widget;
+                    if (!selectedNodes.contains(nw.getNodeModel())) {
+                        HashSet<CfgNode> selectedNode = new HashSet<>(1);
+                        selectedNode.add(nw.getNodeModel());
+                        setNodeSelection(selectedNode);
+                    }
+                } else if (scene.getSelectedNodes().size() == 1) {
+                    nw = (NodeWidget) scene.findWidget(scene.getSelectedNodes().iterator().next());
+                }
+
+                if (nw != null) {
+                    CfgNode node = nw.getNodeModel();
+                    ArrayList<CfgNode> successors = new ArrayList<>();
+                    ArrayList<CfgNode> predecessors = new ArrayList<>();
+                    for (CfgEdge e : node.getOutputEdges()) {
+                        successors.add(e.getTargetNode());
+                    }
+                    for (CfgEdge e : node.getInputEdges()) {
+                        predecessors.add(e.getSourceNode());
+                    }
+
+                    if (predecessors.size() > 0) {
+                        Collections.sort(predecessors, new NodeNameComparator());
+                        JMenu predmenu = new JMenu("Go to predecessor");
+                        for (CfgNode n : predecessors) {
+                            GotoNodeAction action = new GotoNodeAction(n);
+                            predmenu.add(action);
+                        }
+                        menu.add(predmenu);
+                    }
+                    if (successors.size() > 0) {
+                        Collections.sort(successors, new NodeNameComparator());
+                        JMenu succmenu = new JMenu("Go to successor");
+                        for (CfgNode n : successors) {
+                            GotoNodeAction action = new GotoNodeAction(n);
+                            succmenu.add(action);
+                        }
+                        menu.add(succmenu);
+                    }
+                    if (successors.size() > 0 || predecessors.size() > 0) {
+                        menu.addSeparator();
+                    }
+                }
+
+                return menu;
+            }
+        });
+    }
+
+    @Override
+    public void zoomIn() {
+        this.setZoomFactor(this.getZoomFactor() * 1.1);
+        this.validate();
+    }
+
+    @Override
+    public void zoomOut() {
+        this.setZoomFactor(this.getZoomFactor() * 0.9);
+        this.validate();
+    }
+
+    @Override
+    public void showAll() {
+        this.zoomScene();
+        this.validate();
+    }
+
+    private class NodeNameComparator implements Comparator<CfgNode> {
+
+        public int compare(CfgNode node1, CfgNode node2) {
+            String name1 = node1.getBasicBlock().getName().substring(1);
+            String name2 = node2.getBasicBlock().getName().substring(1);
+            Integer blocknum1 = Integer.parseInt(name1);
+            Integer blocknum2 = Integer.parseInt(name2);
+            return blocknum1.compareTo(blocknum2);
+        }
+    }
+
+    private class GotoNodeAction extends AbstractAction {
+
+        CfgNode node;
+
+        GotoNodeAction(CfgNode node) {
+            super(node.getBasicBlock().getName());
+            this.node = node;
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            Set<CfgNode> nodes = new HashSet<>(1);
+            nodes.add(node);
+            setNodeSelection(nodes);
+            centerSelection();
+        }
+    }
+
+    private SceneListener createSceneListener(final CfgScene scene) {
+        return new SceneListener() {
+
+            public void sceneRepaint() {
+            }
+
+            public void sceneValidating() {
+            }
+
+            public void sceneValidated() {
+                if (scene.isLoopClusterVisible()) { //update only if visible
+                    for (LoopClusterWidget cw : getLoopidx2clusterwidget().values()) {
+                        cw.updateClusterBounds();
+                    }
+                }
+                for (EdgeSwitchWidget esw : inputSwitches.values()) {
+                    esw.updatePosition();
+                }
+
+                for (EdgeSwitchWidget esw : outputSwitches.values()) {
+                    esw.updatePosition();
+                }
+            }
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/graph/EdgeSwitchWidget.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,290 @@
+package at.ssw.visualizer.cfg.graph;
+
+import at.ssw.visualizer.cfg.model.CfgEdge;
+import at.ssw.visualizer.cfg.model.CfgNode;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+import java.util.ArrayList;
+import java.util.Collection;
+import org.netbeans.api.visual.action.ActionFactory;
+import org.netbeans.api.visual.action.SelectProvider;
+import org.netbeans.api.visual.action.TwoStateHoverProvider;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.model.ObjectState;
+import org.netbeans.api.visual.widget.Widget;
+
+
+public class EdgeSwitchWidget extends Widget {
+    private final static Color color_enabled = Color.gray;
+    private final static Color color_hover = Color.lightGray; 
+    private float width=1;
+    private float height=1;
+    private CfgScene scene;
+    private NodeWidget nodeWidget;    
+    private boolean output;
+    private WidgetAction hoverAction;
+    private static final String TT_HIDE_EDGES = "Hide Edges";
+    private static final String TT_SHOW_EDGES = "Show Edges";   
+    private static SelectProvider selectProvider = createSelectProvider();
+     
+    
+    public EdgeSwitchWidget(final CfgScene scene, NodeWidget nodeWidget, boolean output) {        
+        super(scene);
+        this.scene = scene;   
+        this.output = output;
+        this.nodeWidget = nodeWidget;  
+  
+        this.getActions().addAction(ActionFactory.createSelectAction(selectProvider));
+        TwoStateHoverProvider ts = new TsHover(this);   
+        WidgetAction wa = ActionFactory.createHoverAction(ts);
+        this.hoverAction = wa;
+        this.getActions().addAction(wa);
+        scene.getActions().addAction(wa);
+        this.setToolTipText(TT_HIDE_EDGES);      
+        this.setForeground(color_enabled);
+        this.setState(ObjectState.createNormal());
+    }
+    
+    
+    @Override
+    protected Rectangle calculateClientArea() {
+       if (this.nodeWidget.getBounds() == null) return new Rectangle(0, 0, 1, 1);
+       int hw = (int) (this.width / 2);
+       int hh = (int) (this.height /2);
+       
+       return new Rectangle(-hw, -hh, 2*hw, 2*hh); 
+   }    
+     
+   
+    public void updatePosition() { 
+        if (this.nodeWidget.getBounds() != null) {   
+            this.width = nodeWidget.getBounds().width*9;
+            this.width /=10;
+            this.height = nodeWidget.getBounds().height/4;      
+            int offset=(int)(2 * (height / 3));
+                        
+            Rectangle bounds = nodeWidget.getBounds();
+            Point location = nodeWidget.getLocation();
+          
+            Point newLoc = new Point();           
+            newLoc.x = location.x;
+             
+            if(output) {               
+                newLoc.y = +location.y + bounds.height/2+offset;      
+            }else {            
+                newLoc.y = location.y - bounds.height/2-offset;
+            }          
+            this.setPreferredLocation(newLoc);           
+        }           
+    }
+ 
+    private Collection<CfgEdge> getEdges(){
+        Collection<CfgEdge> edges;
+        CfgNode node = nodeWidget.getNodeModel();
+        if (output) {
+            edges = scene.findNodeEdges(node, true, false);
+        } else {
+            edges = scene.findNodeEdges(node, false, true);
+        }
+        return edges;
+    }
+ 
+    //change visibility for all Edges
+    public void changeEdgeVisibility(boolean visible){
+        Collection<CfgEdge> edges = this.getEdges();  
+            
+        for(CfgEdge e: edges) {
+            EdgeWidget ew = (EdgeWidget) scene.findWidget(e);
+            if(visible != ew.isEdgeVisible()){              
+                ew.setEdgeVisible(visible);     
+                if(output){
+                    scene.getInputSwitch(e.getTargetNode()).updateStatus();
+                } else {
+                    scene.getOutputSwitch(e.getSourceNode()).updateStatus();
+                }              
+            }
+        }
+        if(visible)    
+            this.setToolTipText(TT_HIDE_EDGES); 
+        else 
+            this.setToolTipText(TT_SHOW_EDGES);
+   
+        this.setForeground(color_enabled);
+        this.bringToBack();
+        ObjectState os = this.getState();   
+        this.setState(os.deriveSelected(!visible));
+    }
+    
+    /**
+     *  Update the status of the switch to the current state of the edges
+     *  usually needed when the opposit switch changes the state
+     */
+    private void updateStatus(){
+        Collection<CfgEdge> edges = this.getEdges(); 
+        boolean hiddenFound=false;
+        for(CfgEdge e: edges) {
+            EdgeWidget ew = (EdgeWidget) scene.findWidget(e);
+            if(!ew.isVisible()) {
+                hiddenFound=true;
+                break;
+            }
+        }        
+        ObjectState os = this.getState();
+        if(os.isSelected() && !hiddenFound) {
+            this.setState(os.deriveSelected(false));
+            setToolTipText(TT_HIDE_EDGES);
+        } else if (!os.isSelected() && hiddenFound) {
+            this.setState(os.deriveSelected(true));
+            setToolTipText(TT_SHOW_EDGES); 
+        }
+        this.revalidate();
+    }
+    
+
+    public void startPreview() {        
+        ObjectState os = this.getState();
+        
+        for(CfgEdge e : getEdges()) {
+            EdgeWidget ew = (EdgeWidget) scene.findWidget(e);
+            if(!os.isSelected() || !ew.isVisible()){             
+                ObjectState edgeState = ew.getState();              
+                ew.setState(edgeState.deriveHighlighted(true));
+            }
+        }               
+    }
+    
+    public void endPreview(){       
+       for(CfgEdge e : getEdges()) {
+            EdgeWidget ew = (EdgeWidget) scene.findWidget(e);
+            ObjectState os = ew.getState();          
+            ew.setState(os.deriveHighlighted(false));
+        }      
+    }
+  
+    /**
+     * shows or hides the edges of the switch
+     */
+    public void switchEdges() { 
+        endPreview();
+        ObjectState os = this.getState();
+        Collection<CfgEdge> edges = this.getEdges(); 
+        ArrayList<CfgEdge> updates = new ArrayList<>();
+        boolean visible=os.isSelected();
+        this.setState(os.deriveSelected(!visible));     
+        for(CfgEdge e: edges) {
+            EdgeWidget ew = (EdgeWidget) scene.findWidget(e);
+                if(ew.isEdgeVisible() != visible){
+                    updates.add(e);
+                    ew.setEdgeVisible(visible);
+                    if(output){
+                        scene.getInputSwitch(e.getTargetNode()).updateStatus();
+                    } else {
+                        scene.getOutputSwitch(e.getSourceNode()).updateStatus();
+                    }      
+                }
+        }
+        if(visible)
+             this.setToolTipText(TT_HIDE_EDGES);    
+        else
+             this.setToolTipText(TT_SHOW_EDGES);    
+               
+        revalidate();   
+    }
+  
+  
+
+ 
+    private class TsHover implements TwoStateHoverProvider {       
+        EdgeSwitchWidget tw;    
+       
+        TsHover(EdgeSwitchWidget tw) {
+            this.tw = tw;
+        }
+       
+        public void unsetHovering(Widget w) {
+            w.setForeground(color_enabled);  
+            ObjectState state = w.getState();          
+            w.setState(state.deriveWidgetHovered(false));           
+            w.bringToBack();
+            endPreview();
+        }
+
+        public void setHovering(Widget w) {        
+            ObjectState state = w.getState();          
+            w.setState(state.deriveWidgetHovered(true));          
+            w.setForeground(color_hover);
+            w.bringToFront();
+            nodeWidget.bringToFront();                
+            startPreview();
+        }
+    }
+    
+    @Override
+    public void paintWidget() {   
+        ObjectState os = this.getState();       
+        if(!os.isHovered() && !os.isSelected()) return; //all previewEdges visible and not hovering, 
+                                                        //no need to paint the switch         
+        float hw = width/2;    
+        Polygon pol = new Polygon();
+        pol.addPoint(0,(int) -height/2); 
+        pol.addPoint((int)hw,(int) height/2);
+        pol.addPoint((int)-hw,(int) height/2);  
+        Graphics2D gr = getGraphics();
+        gr.setColor(this.getForeground());
+        BasicStroke bs = new BasicStroke(2.0f, BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
+        gr.setStroke(bs);
+        AffineTransform previousTransform;
+        previousTransform = gr.getTransform ();
+        if(output) {
+            if(os.isSelected() ){//hidden
+                 gr.scale(1.0, -1.0);
+            }
+        } else { //input switch
+            if(os.isHovered() && !os.isSelected()){
+                 gr.scale(1.0, -1.0);
+            }     
+        }            
+        gr.fillPolygon(pol);
+        gr.setTransform(previousTransform);
+        
+    }
+    
+   
+    
+    //the constructor adds the hover WidgetAction to the scene
+    //the action is removed from the scene when the object gets destroyed
+    @Override
+    protected void finalize() throws Throwable { 
+        this.getScene().getActions().removeAction(hoverAction);
+        this.getActions().removeAction(hoverAction);
+    }
+    
+    @Override
+    public String toString(){
+        return "EDGESWITCH("+this.nodeWidget.getNodeModel().toString()+")";
+    }
+    
+    private static SelectProvider createSelectProvider() {
+        return new SelectProvider(){
+            public boolean isAimingAllowed(Widget arg0, Point arg1, boolean arg2) {
+                return false;
+            }
+            
+            public boolean isSelectionAllowed(Widget arg0, Point arg1, boolean arg2) {
+                return true;
+            }
+            
+            public void select(Widget w, Point arg1, boolean arg2) {              
+                if(w instanceof EdgeSwitchWidget){
+                    EdgeSwitchWidget tw = (EdgeSwitchWidget) w;                    
+                    tw.switchEdges();
+                }                                    
+            }
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/graph/EdgeWidget.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,97 @@
+package at.ssw.visualizer.cfg.graph;
+
+import at.ssw.visualizer.cfg.model.CfgEdge;
+import at.ssw.visualizer.cfg.preferences.CfgPreferences;
+import at.ssw.visualizer.cfg.visual.BezierWidget;
+import at.ssw.visualizer.cfg.visual.SplineConnectionWidget;
+import org.netbeans.api.visual.anchor.AnchorShapeFactory;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Stroke;
+import org.netbeans.api.visual.anchor.AnchorShape;
+import org.netbeans.api.visual.model.ObjectState;
+
+//public class EdgeWidget extends BezierWidget {
+public class EdgeWidget extends SplineConnectionWidget {
+    
+    private boolean visible=true;//to store the visible state when entering the preview 
+    protected static final Stroke selectedStroke = new BasicStroke(3.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
+    protected static final Stroke defaultStroke = new BasicStroke(1.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
+    protected static final Stroke previewStroke = new BasicStroke(
+            0.5f,                      // Width
+            BasicStroke.CAP_SQUARE,    // End cap
+            BasicStroke.JOIN_MITER,    // Join style
+            10.0f,                     // Miter limit
+            new float[] {5.0f, 5.0f},  // Dash pattern
+            0.0f);              
+    
+    
+    
+    public EdgeWidget(CfgScene scene, CfgEdge edge) {
+        super(scene);       
+        Color lineColor;
+        CfgPreferences prefs = CfgPreferences.getInstance();
+        
+        if(edge.isBackEdge()) 
+            lineColor = prefs.getBackedgeColor();       
+        else if (edge.isXhandler())
+            lineColor = prefs.getExceptionEdgeColor();
+        else    
+            lineColor = prefs.getEdgeColor();
+        
+        setLineColor(lineColor);
+        AnchorShape as;
+        if(edge.isReflexive())//small Arrow
+            as = AnchorShapeFactory.createTriangleAnchorShape(6, true, false, 5);
+        else
+            as =AnchorShapeFactory.createTriangleAnchorShape(10, true, false, 9);
+    
+        setTargetAnchorShape(as);  
+        setToolTipText(edge.toString());              
+    }
+ 
+    public CfgEdge getEdgeModel() {
+        CfgScene scene = (CfgScene) this.getScene();
+        return (CfgEdge) scene.findObject(this);
+    }
+    
+    public void setEdgeVisible(boolean visible) {
+        this.visible=visible;
+        this.setVisible(visible);
+        this.reroute();
+        this.revalidate();
+    }
+    
+    
+    public boolean isEdgeVisible(){
+        return visible;
+    }
+    
+        
+    @Override
+    public void notifyStateChanged(ObjectState oldState, ObjectState newState) {
+       setForeground (getLineColor());
+      
+       if(newState.isHighlighted() && !oldState.isHighlighted()){
+            this.setStroke(previewStroke);
+            this.setVisible(true);
+       } else {
+           if(newState.isSelected()){
+                this.setStroke(selectedStroke);
+           } else {
+                this.setStroke(defaultStroke);
+           }
+           if(this.isEdgeVisible()){
+                this.setVisible(true);
+           } else {
+                this.setVisible(false);
+           }
+       }       
+    }
+    
+    
+    @Override
+    public String toString(){
+        return "EdgeWidget[" + getEdgeModel().toString() + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/graph/LoopClusterWidget.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,107 @@
+package at.ssw.visualizer.cfg.graph;
+
+import at.ssw.visualizer.cfg.model.LoopInfo;
+import java.awt.Color;
+import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import org.netbeans.api.visual.action.ActionFactory;
+import org.netbeans.api.visual.action.EditProvider;
+import org.netbeans.api.visual.border.BorderFactory;
+import org.netbeans.api.visual.widget.Widget;
+
+public class LoopClusterWidget extends Widget implements Comparable<LoopClusterWidget> {
+    private static final int INSET = 10;//min space between node members and cluster border
+    private static final int DASHSIZE = 10;  
+    private Color color = Color.BLUE;
+    private int loopIndex;
+    private int loopDepth; 
+    private CfgScene cfgscene;
+    private ArrayList<NodeWidget> members = new ArrayList<>();
+  
+    public LoopClusterWidget(CfgScene scene,  int loopdepth, final int loopindex) {
+        super(scene);
+        this.cfgscene = scene;
+        this.loopIndex = loopindex;
+        this.loopDepth = loopdepth;          
+        this.setBorder(BorderFactory.createDashedBorder(color, DASHSIZE, DASHSIZE/2, true));          
+        this.getActions().addAction(ActionFactory.createEditAction( new EditProvider() { //double click action
+            public void edit(Widget w) {
+                if(w instanceof LoopClusterWidget){                 
+                    for(LoopInfo info : cfgscene.getCfgEnv().getLoopMap().values()){
+                        if(info.getLoopIndex() == loopindex){              
+                            cfgscene.setNodeSelection(info.getMembers());                         
+                            break;
+                        }
+                    }   
+                }
+            }
+        }));
+               
+    }
+
+    public List<NodeWidget> getMembers() {
+        return members;
+    }
+
+    public int getLoopIndex() {
+        return loopIndex;
+    }
+    
+    public void addMember(NodeWidget nw) {
+        assert(!this.members.contains(nw));        
+        members.add(nw);       
+    }
+
+    public boolean removeMember(NodeWidget nw) {
+        if(this.members.contains(nw)){
+            members.remove(nw);       
+            return true;
+        }
+        return false;
+    }
+  
+    public void setrandomColor(){
+        if(this.loopDepth == 0 ) return; 
+        Random rand = new Random();
+        Color randColor = Color.getHSBColor(rand.nextFloat()%360,0.1f,1.0f);      
+        this.setBackground(randColor);
+    }
+    
+    //updates the bounds of the widget,
+    //and revalidates the widget if a membernode changed the scene position
+    public void updateClusterBounds(){      
+        Rectangle boundRect=null;
+        
+        for(NodeWidget nw : this.members){
+            if(boundRect==null){
+                boundRect = nw.convertLocalToScene(nw.getBounds());  
+            } else {
+                boundRect = boundRect.union(nw.convertLocalToScene(nw.getBounds()));
+            }  
+        }
+        if(boundRect==null) return;
+        for(Widget w : this.getChildren()) {
+            if(w instanceof LoopClusterWidget) {            
+                LoopClusterWidget lc = (LoopClusterWidget)w;
+                lc.updateClusterBounds();
+                boundRect = boundRect.union(w.convertLocalToScene(w.getBounds()));
+            }
+        }
+       
+        boundRect.grow(INSET, INSET);
+        this.setPreferredBounds(boundRect);               
+    }
+    
+    
+    public int compareTo(LoopClusterWidget o) {
+        return new Integer(this.loopDepth).compareTo(o.loopDepth);
+    }
+    
+    
+    @Override
+    public String toString(){
+        return "LoopCluster: [DEPTH "+this.loopDepth+ "] [INDEX "+this.loopIndex+"]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/graph/NodeWidget.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,153 @@
+package at.ssw.visualizer.cfg.graph;
+
+import at.ssw.visualizer.cfg.model.CfgNode;
+import at.ssw.visualizer.cfg.preferences.CfgPreferences;
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.font.FontRenderContext;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RoundRectangle2D;
+import org.netbeans.api.visual.border.BorderFactory;
+import org.netbeans.api.visual.model.ObjectState;
+import org.netbeans.api.visual.widget.Widget;
+
+
+public class NodeWidget extends Widget  {    
+    
+    
+    //basic block node dimension
+    private final int halfheight=12;
+    private final int halfwidth=17;
+      
+    private final int height=halfheight*2+1;  
+    private final int width=halfwidth*2+1;     
+    private final int arcHeight=(halfheight/4)*3;
+    private final int arcWidth = arcHeight; 
+    private final int FONT_MAXSIZE=18;
+    
+    private int borderWidth;
+    private boolean nodeColorCustomized;
+    private String text;
+    private Rectangle2D fontRect;
+    private Color nodeColor;
+    
+    protected static final Color HOVER_BACKGROUND = new Color(0xEEEEEE);
+    protected static final Color HOVER_FOREGROUND = new Color(0xCDCDCD);
+
+    public NodeWidget(CfgScene scene, CfgNode nodeModel ){        
+        super(scene);   
+        this.setToolTipText("<html>" + nodeModel.getDescription().replaceAll("\n", "<br>") + "</html>");
+        this.text = nodeModel.getBasicBlock().getName();   
+        this.borderWidth = nodeModel.getLoopDepth()+1;           
+        this.setBorder(BorderFactory.createRoundedBorder(arcWidth+borderWidth, arcHeight+borderWidth, borderWidth, borderWidth, Color.BLACK, Color.BLACK));
+        CfgPreferences prefs = CfgPreferences.getInstance();
+        Color color = prefs.getFlagsSetting().getColor(nodeModel.getBasicBlock().getFlags());
+        this.nodeColorCustomized = (color!=null);
+        this.nodeColor = (nodeColorCustomized) ? color : prefs.getNodeColor();
+        this.adjustFont(null);   
+    }
+
+    public void setBorderColor(Color color){ 
+        this.setBorder(BorderFactory.createRoundedBorder(arcWidth+borderWidth, arcHeight+borderWidth, borderWidth, borderWidth, color, color));
+    }
+    
+    public boolean isNodeColorCustomized() {    
+        return nodeColorCustomized;        
+    }
+    
+    //sets a customColor node color
+    public void setNodeColor(Color color, boolean customColor) {
+        this.nodeColorCustomized=customColor;
+        this.nodeColor=color;
+        this.revalidate();
+    }
+    
+    public Color getNodeColor() {
+        return this.nodeColor;
+    }
+    
+    public CfgNode getNodeModel() {
+        CfgScene scene = (CfgScene) this.getScene();
+        return (CfgNode) scene.findObject(this);    
+    }
+      
+   
+    @Override
+    public void notifyStateChanged(ObjectState oldState, ObjectState newState) {
+        if(!oldState.equals(newState))
+            this.revalidate();
+        if(!oldState.isSelected() && newState.isSelected())
+            this.bringToFront();
+    }
+       
+    @Override
+    protected Rectangle calculateClientArea() {       
+        return new Rectangle(-(halfwidth+1), -(1+halfheight), width+1, height+1);//add border
+    }
+
+    public void adjustFont(Font font){
+        if(font==null)
+            font = CfgPreferences.getInstance().getTextFont();
+        if(font.getSize()>FONT_MAXSIZE){
+            font = new Font(font.getFamily(), font.getStyle(), FONT_MAXSIZE);
+        }
+        int size=font.getSize();
+        int fontStyle = font.getStyle();
+        String fontName = font.getFamily();
+        FontRenderContext frc = new FontRenderContext(new AffineTransform(), false, false);
+        Rectangle2D bounds = font.getStringBounds(text, frc);
+        while(size > 1 && bounds.getWidth() > width) {
+            font = new Font(fontName, fontStyle, --size);
+            bounds = font.getStringBounds(text, frc);
+        }       
+        this.fontRect=bounds;
+        this.setFont(font);
+    }
+
+    @Override
+    protected void paintWidget() {     
+        Graphics2D gr = getGraphics(); 
+        gr.setColor(nodeColor); 
+        Insets borderInsets  = this.getBorder().getInsets();    
+        RoundRectangle2D.Float innerRect = new RoundRectangle2D.Float(-(halfwidth+1), -(halfheight+1), width+1, height+1,arcWidth-1, arcHeight-1);    
+        gr.fill(innerRect);
+        gr.setColor(getForeground()); 
+        gr.setFont(getFont());
+        float textX  = (float)( - fontRect.getCenterX());
+        float textY  = (float)( - fontRect.getCenterY());                   
+        gr.drawString(text, textX, textY); 
+            
+        RoundRectangle2D.Float outerRect = new RoundRectangle2D.Float(-(halfwidth+borderInsets.left + 1), -(halfheight+borderInsets.top + 1), 
+            width+borderInsets.left + borderInsets.right + 1, height + borderInsets.top + borderInsets.bottom + 1, 
+            arcWidth + borderWidth, arcHeight + borderWidth); 
+
+        ObjectState os =this.getState();
+        if(os.isSelected()){
+            Composite composite = gr.getComposite();
+            gr.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.5f));                     
+            gr.setColor(CfgPreferences.getInstance().getSelectionColorForeground());
+            gr.fill(outerRect);
+            gr.setColor(CfgPreferences.getInstance().getSelectionColorBackground());            
+            gr.setComposite(composite);       
+        }  
+        if(os.isHovered()){
+            Composite composite = gr.getComposite();
+            gr.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.5f));
+            gr.setColor(HOVER_FOREGROUND);
+            gr.fill(outerRect); 
+            gr.setColor(HOVER_BACKGROUND);
+            gr.setComposite(composite);        
+        }       
+    }  
+    
+    @Override
+    public String toString() {
+        return "NodeWidget[" + getNodeModel().getBasicBlock().getName() + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/graph/SelectionWidget.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,39 @@
+package at.ssw.visualizer.cfg.graph;
+
+import at.ssw.visualizer.cfg.preferences.CfgPreferences;
+import java.awt.AlphaComposite;
+import java.awt.Composite;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import org.netbeans.api.visual.widget.Scene;
+import org.netbeans.api.visual.widget.Widget;
+
+
+public class SelectionWidget extends Widget {
+    public SelectionWidget(Scene scene) {
+        super(scene);
+    }
+    
+    public static void renderSelectedRect(Graphics2D gr, Rectangle rect) {
+        if (rect == null) {
+            return;
+        }
+        gr.setColor(CfgPreferences.getInstance().getSelectionColorBackground());
+        gr.fillRect(rect.x, rect.y, rect.width, rect.height);
+        gr.setColor(CfgPreferences.getInstance().getSelectionColorForeground());
+    }
+
+    public void renderSelectionRectangle(Graphics2D gr, Rectangle selectionRectangle) {
+        Composite composite = gr.getComposite();
+        gr.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.5f));
+       
+        renderSelectedRect(gr, selectionRectangle);
+        gr.setComposite(composite);
+    }
+    
+    @Override
+    public void paintWidget(){       
+        this.renderSelectionRectangle(this.getGraphics(), this.getBounds());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/graph/SymmetricAnchor.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,157 @@
+package at.ssw.visualizer.cfg.graph;
+
+import org.netbeans.api.visual.widget.Widget;
+import org.netbeans.api.visual.anchor.Anchor;
+import java.awt.*;
+
+
+/**
+ * This Anchor can be used with symmetric edges to create parallel Edges.
+ * Two Directed Edges are symmetric if they are connecting the same Nodes in different directions.
+ * e.g.  Nodes (1, 2) Edges(a , b)  with (1)-a->(2)  ,  (2)-b->(1)  
+ * Start-/End positions are calculated with a fixed offset to prevent edges from overlapping. 
+ * If the edges are drawn as straight lines they will appear as parallel edges.
+ */
+
+public final class SymmetricAnchor extends Anchor {
+    
+   private final static int OFFSET = 10;
+   private boolean includeBorders;  
+   private int offx;
+   private int offy;
+   
+   public SymmetricAnchor (Widget widget, boolean includeBorders, boolean source) {
+        super (widget);
+        this.includeBorders = includeBorders;        
+        if (source) {
+            offx = OFFSET;
+            offy = OFFSET;        
+        }
+        else {
+            offx = -OFFSET;
+            offy = -OFFSET;
+        }
+    }
+
+    public Result compute (Entry entry) {        
+        Point relatedLocation = //center of the widget 
+                getRelatedSceneLocation ();
+        Point oppositeLocation = //center of the widget
+                getOppositeSceneLocation (entry);
+
+        Widget widget = getRelatedWidget ();
+        Rectangle bounds = widget.getBounds ();
+        if (! includeBorders) {
+            Insets insets = widget.getBorder ().getInsets ();
+            bounds.x += insets.left;
+            bounds.y += insets.top;
+            bounds.width -= insets.left + insets.right;
+            bounds.height -= insets.top + insets.bottom;
+        }
+      
+        bounds = widget.convertLocalToScene (bounds);
+       
+        if (bounds.isEmpty ()  || relatedLocation.equals (oppositeLocation))
+            return new Anchor.Result (relatedLocation, Anchor.DIRECTION_ANY);
+
+        float dx  //distance  x-axis
+                = oppositeLocation.x - relatedLocation.x;
+        float dy  //distance y-axis  
+                = oppositeLocation.y - relatedLocation.y;
+       
+        
+        float ddx 
+                = Math.abs (dx) / (float) bounds.width;
+        float ddy = 
+                Math.abs (dy) / (float) bounds.height;
+
+        Anchor.Direction direction;
+      
+
+        if (ddx >= ddy) {
+            if(dx >= 0.0f){        
+                direction = Direction.RIGHT;
+                relatedLocation.y -= offy;
+            } else {
+                direction = Direction.LEFT;
+                relatedLocation.y += offy;
+            }         
+        } else {
+            if(dy >= 0.0f){
+                direction = Direction.BOTTOM;
+                relatedLocation.x += offx;
+            } else {
+                direction = Direction.TOP;
+                relatedLocation.x -= offx;            
+            }           
+        }
+        
+
+        float scale = 0.5f / Math.max (ddx, ddy);
+
+        float ex = scale * dx;
+        float ey = scale * dy;
+        
+        Point point = new Point (Math.round (relatedLocation.x + ex), Math.round (relatedLocation.y + ey));
+            
+         if(direction == Direction.RIGHT) {
+             int top = bounds.y;//-bounds.height;// left y of the widget
+             int bottom = bounds.y + bounds.height;// right y of the widget
+             if(point.y < top) {//above the widget
+                 int cor = top-point.y;
+                 point.x -= cor;
+                 point.y += cor;              
+             } else if ( point.y > bottom) {
+                 int cor = point.y-bottom;
+                 point.x -= cor;
+                 point.y -= cor;
+             }
+             
+         } else if (direction == Direction.LEFT) {
+             int top = bounds.y;//-bounds.height;// left y of the widget
+             int bottom = bounds.y + bounds.height;// right y of the widget
+                         
+           
+                        
+             if(point.y < top) {//above the widget
+                 int cor = top-point.y;
+                 point.x += cor;
+                 point.y += cor;
+             } else if ( point.y > bottom) {              
+                int cor = bottom-point.y;
+                point.x -= cor;
+                point.y += cor;
+             }
+            
+                      
+         } else if (direction == Direction.BOTTOM) {
+             int left = bounds.x;//-bounds.height;// left y of the widget
+             int right = bounds.x + bounds.width;// right y of the widget
+             if(point.x < left) {//above the widget
+                int cor = left-point.x;                
+                point.x += cor;
+                point.y -= cor;
+             } else if ( point.x > right) {
+                int cor = point.x- right;
+                point.x -= cor;
+                point.y -= cor;
+             }
+         
+         } else if (direction == Direction.TOP) {
+            int left = bounds.x;//-bounds.height;// left y of the widget
+            int right = bounds.x + bounds.width;// right y of the widget
+            if(point.x < left) {//above the widget
+                int cor = left-point.x;
+                point.x += cor;
+                point.y += cor;
+             } else if ( point.x > right) {
+                 int cor = point.x - right;
+                 point.x -= cor;
+                 point.y += cor;
+             }
+         
+         }          
+        
+        return new Anchor.Result (point, direction);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/graph/layout/HierarchicalCompoundLayout.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,102 @@
+package at.ssw.visualizer.cfg.graph.layout;
+
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import at.ssw.visualizer.cfg.model.CfgEdge;
+import at.ssw.visualizer.cfg.model.CfgNode;
+import at.ssw.visualizer.cfg.model.LoopInfo;
+import java.awt.Point;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.draw2d.geometry.Insets;
+import org.netbeans.api.visual.graph.layout.GraphLayout;
+import org.netbeans.api.visual.graph.layout.UniversalGraph;
+import org.eclipse.draw2d.graph.CompoundDirectedGraph;
+import org.eclipse.draw2d.graph.CompoundDirectedGraphLayout;
+import org.eclipse.draw2d.graph.Edge;
+import org.eclipse.draw2d.graph.EdgeList;
+import org.eclipse.draw2d.graph.Node;
+import org.eclipse.draw2d.graph.NodeList;
+import org.eclipse.draw2d.graph.Subgraph;
+import org.netbeans.api.visual.widget.Widget;
+
+public class HierarchicalCompoundLayout extends GraphLayout<CfgNode, CfgEdge> {
+           
+    private static final int TOP_BORDER = 20;
+    private static final int LEFT_BORDER = 20;
+    private int PADDING = 20;
+    private static final int INSET = 20;
+    private CfgScene scene;      
+       
+    public HierarchicalCompoundLayout(CfgScene scene){
+        this.scene = scene;         
+    }
+    
+    @Override
+    protected void performGraphLayout(UniversalGraph<CfgNode, CfgEdge> ug) {          
+        CompoundDirectedGraph dg = new CompoundDirectedGraph();
+        CompoundDirectedGraphLayout layout = new CompoundDirectedGraphLayout();
+        NodeList nodeList = dg.nodes;
+        EdgeList edgeList = dg.edges;
+                
+        Map<Integer, Subgraph> idx2graph = new HashMap<>();
+        Subgraph base = new Subgraph(0);
+        idx2graph.put(0, base);
+        base.insets=getInsets();
+        for(LoopInfo info : scene.getCfgEnv().getLoopMap().values()){           
+            Subgraph subg = new Subgraph(info.getLoopIndex());   
+            subg.insets=getInsets();
+            idx2graph.put(info.getLoopIndex(), subg);
+        }
+            
+        for(CfgNode n : scene.getCfgEnv().getNodes() ) {
+            Widget nodeWidget = scene.findWidget(n);
+            Node node = new Node(n);
+            node.width=nodeWidget.getBounds().width;
+            node.height = nodeWidget.getBounds().height;
+            node.setPadding(new Insets(PADDING, PADDING, PADDING, PADDING));          
+            Subgraph subg = idx2graph.get(n.getLoopIndex());
+            assert(subg != null);
+            node.setParent(subg);
+            subg.addMember(node);
+            nodeList.add(node);
+          
+        }             
+        nodeList.addAll(idx2graph.values());         
+        for(LoopInfo info : scene.getCfgEnv().getLoopMap().values()){
+            Subgraph subg = idx2graph.get(info.getLoopIndex());
+            if(info.getParent() != null){
+                Subgraph parentsubg = idx2graph.get(info.getParent().getLoopIndex());
+                Edge edge = new Edge(parentsubg, subg);
+                parentsubg.addMember(subg);
+                subg.setParent(parentsubg);              
+                edgeList.add(edge);     
+            }               
+        }   
+        for(CfgEdge e : scene.getCfgEnv().getEdges() ) {                      
+            if(e.isBackEdge()) continue;
+            Edge edge = new Edge(e, nodeList.getNode(e.getSourceNode().getNodeIndex()), nodeList.getNode(e.getTargetNode().getNodeIndex()));
+            edgeList.add(edge);
+        } 
+        layout.visit(dg);
+                
+        for(Object obj : dg.nodes){           
+            Node n = (Node) obj;
+            if(n.data instanceof CfgNode){
+                CfgNode cfgNode = (CfgNode) n.data;              
+                Point pos = new Point(n.x + LEFT_BORDER, n.y + TOP_BORDER);
+                Point scenepos = scene.convertLocalToScene(pos);
+                this.setResolvedNodeLocation(ug, cfgNode, scenepos); 
+            }
+        }      
+    }
+    
+    @Override
+    protected void performNodesLayout(UniversalGraph<CfgNode, CfgEdge> ug, Collection<CfgNode> collection) {        
+    }
+    
+    private Insets getInsets(){             
+        return new Insets(INSET, INSET, INSET, INSET);        
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/graph/layout/HierarchicalNodeLayout.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,69 @@
+package at.ssw.visualizer.cfg.graph.layout;
+
+import at.ssw.visualizer.cfg.graph.CfgScene;
+import at.ssw.visualizer.cfg.model.CfgEdge;
+import at.ssw.visualizer.cfg.model.CfgNode;
+import java.awt.Point;
+import java.util.Collection;
+import org.netbeans.api.visual.graph.layout.GraphLayout;
+import org.netbeans.api.visual.graph.layout.UniversalGraph;
+import org.eclipse.draw2d.graph.DirectedGraph;
+import org.eclipse.draw2d.graph.DirectedGraphLayout;
+import org.eclipse.draw2d.graph.Edge;
+import org.eclipse.draw2d.graph.EdgeList;
+import org.eclipse.draw2d.graph.Node;
+import org.eclipse.draw2d.graph.NodeList;
+import org.netbeans.api.visual.widget.Widget;
+
+
+public class HierarchicalNodeLayout extends GraphLayout<CfgNode, CfgEdge> {
+           
+    private static final int TOP_BORDER = 20;
+    private static final int LEFT_BORDER = 40;    
+    
+    private CfgScene scene;  
+    
+    public HierarchicalNodeLayout(CfgScene scene){
+        this.scene = scene;      
+    }
+    
+    @Override
+    protected void performGraphLayout(UniversalGraph<CfgNode, CfgEdge> ug) {  
+        DirectedGraph dg = new DirectedGraph();
+        DirectedGraphLayout layout = new DirectedGraphLayout();
+       
+        NodeList nodeList = dg.nodes;
+        EdgeList edgeList = dg.edges;
+        
+        for(CfgNode n : scene.getCfgEnv().getNodes() ) {
+            Widget nodeWidget = scene.findWidget(n);
+            Node node = new Node(n);           
+            node.width=nodeWidget.getBounds().width;
+            node.height = nodeWidget.getBounds().height;         
+            nodeList.add(node);
+        }
+        
+        for(CfgEdge e : scene.getCfgEnv().getEdges() ) {
+            if(e.isBackEdge()) continue;
+            Edge edge = new Edge(e, nodeList.getNode(e.getSourceNode().getNodeIndex()), 
+                    nodeList.getNode(e.getTargetNode().getNodeIndex()));            
+            edgeList.add(edge);
+        }        
+      
+        layout.visit(dg);
+        
+        for(Object obj : dg.nodes){
+            Node n = (Node) obj;
+            CfgNode cfgNode  = (CfgNode) n.data;
+            Point pos = new Point(n.x + LEFT_BORDER , n.y + TOP_BORDER);
+            Point scenepos = scene.convertLocalToScene(pos);
+            setResolvedNodeLocation(ug, cfgNode, scenepos);              
+        }
+        
+    }
+
+    @Override
+    protected void performNodesLayout(UniversalGraph<CfgNode, CfgEdge> ug, Collection<CfgNode> collection) {        
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/Icons.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,18 @@
+package at.ssw.visualizer.cfg.icons;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class Icons {
+    private static final String PATH = "at/ssw/visualizer/cfg/icons/";
+    
+    public static final String CFG = PATH + "cfg.gif";
+    
+    public static final String ICON_ZOOMIN = PATH + "zoomin.gif";
+    public static final String ICON_ZOOMOUT = PATH + "zoomout.gif";
+    public static final String ICON_DEFAULT = PATH + "arrangebfs.gif";
+
+    private Icons() {
+    }
+}
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/arrangebfs.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/arrangehier.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/arrangeloop.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/autosize_selection.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/bezierrouter.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/cfg.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/cfg32.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/cluster.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/color.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/combine.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/combine_disabled.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/disk.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/fanrouter.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/hideedges.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/hideedges_disabled.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/manhattanrouter.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/showedges.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/showedges_disabled.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/split.gif has changed
Binary file visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/icons/split_disabled.gif has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/layer.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
+<filesystem>
+    <folder name="OptionsDialog">
+        <file name="CFGOptions.instance">
+            <attr name="instanceClass" stringvalue="at.ssw.visualizer.cfg.preferences.CFGOptionsCategory"/>
+            <attr name="position" intvalue="1"/>
+        </file>              
+    </folder>   
+    <folder name="CompilationViewer">
+        <folder name="CFG">
+            <folder name="Actions">
+                <file name="com-oracle-graal-visualizer-cfg-RouterAction.instance">
+                    <attr name="displayName" stringvalue="Use bezier routing"/>
+                    <attr methodvalue="org.openide.awt.Actions.checkbox" name="instanceCreate"/>
+                    <attr name="iconBase" stringvalue="at/ssw/visualizer/cfg/icons/bezierrouter.gif"/>
+                    <attr name="preferencesNode" methodvalue="at.ssw.visualizer.cfg.graph.CfgScene.getPreferences"/>
+                    <attr name="preferencesKey" stringvalue="router"/>
+                </file>
+                <file name="com-oracle-graal-visualizer-cfg-LoopClusterAction.instance">
+                    <attr name="displayName" stringvalue="Show loop clusters"/>
+                    <attr methodvalue="org.openide.awt.Actions.checkbox" name="instanceCreate"/>
+                    <attr name="iconBase" stringvalue="at/ssw/visualizer/cfg/icons/cluster.gif"/>
+                    <attr name="preferencesNode" methodvalue="at.ssw.visualizer.cfg.graph.CfgScene.getPreferences"/>
+                    <attr name="preferencesKey" stringvalue="loopClusters"/>
+                </file>
+                <file name="com-oracle-graal-visualizer-sharedactions-ShowAllAction.shadow">
+                    <attr name="originalFile" stringvalue="Actions/View/com-oracle-graal-visualizer-sharedactions-ShowAllAction.instance"/>
+                </file>
+                <file name="com-oracle-graal-visualizer-sharedactions-ZoomInAction.shadow">
+                    <attr name="originalFile" stringvalue="Actions/View/com-oracle-graal-visualizer-sharedactions-ZoomInAction.instance"/>
+                </file>
+                <file name="com-oracle-graal-visualizer-sharedactions-ZoomOutAction.shadow">
+                    <attr name="originalFile" stringvalue="Actions/View/com-oracle-graal-visualizer-sharedactions-ZoomOutAction.instance"/>
+                </file>
+                <file name="com-oracle-graal-visualizer-sharedactions-ExportSVGAction.shadow">
+                    <attr name="originalFile" stringvalue="Actions/File/com-oracle-graal-visualizer-sharedactions-ExportSVGAction.instance"/>
+                </file>
+            </folder>
+        </folder>
+    </folder>
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/model/CfgEdge.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,10 @@
+package at.ssw.visualizer.cfg.model;
+
+public interface CfgEdge {
+    public CfgNode getSourceNode();
+    public CfgNode getTargetNode();
+    public boolean isXhandler();
+    public boolean isBackEdge();
+    public boolean isSymmetric();
+    public boolean isReflexive();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/model/CfgEdgeImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+package at.ssw.visualizer.cfg.model;
+
+public class CfgEdgeImpl implements CfgEdge {   
+    private CfgNodeImpl sourceNode;
+    private CfgNodeImpl targetNode;
+    private boolean symmetric;
+    private boolean backedge;
+
+    public CfgEdgeImpl(CfgNodeImpl sourceNode, CfgNodeImpl targetNode) {
+        this.sourceNode = sourceNode;
+        this.targetNode = targetNode;
+    }
+   
+    public void setSymmetric(boolean symmetric){
+        this.symmetric = symmetric;
+    }
+    
+    public void setBackEdge(boolean isBackedge){
+        this.backedge = isBackedge;
+    }
+        
+    public CfgNode getSourceNode() {
+        return sourceNode;
+    }
+
+    public CfgNode getTargetNode() {
+        return targetNode;
+    }
+
+    public boolean isBackEdge() {
+        return this.backedge;
+    }
+
+    public boolean isSymmetric() {
+        return symmetric;
+    }
+
+    public boolean isReflexive() {
+        return sourceNode==targetNode;
+    }
+    
+    public boolean isXhandler() {
+        return sourceNode.getBasicBlock().getXhandlers().contains(targetNode.getBasicBlock());
+    }
+
+    @Override
+    public String toString(){
+        return this.sourceNode.getBasicBlock().getName() + "->" + targetNode.getBasicBlock().getName();
+    }  
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/model/CfgEnv.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,297 @@
+package at.ssw.visualizer.cfg.model;
+
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+
+
+/**
+ * This is the container class for the data model,
+ * it prepares creates nodes and edges for the CfgScene
+ * from a ControlFlowGraph of the Compilation Model
+ */
+public class CfgEnv {
+    private ControlFlowGraph cfg;    
+    private Map<CfgNode, LoopInfo> loopMap;//maps: LoopHeader --> LoopInfo
+    private CfgNodeImpl[] nodeArr;
+    private CfgEdgeImpl[] edgeArr;
+       
+    public CfgEnv(ControlFlowGraph cfg) {
+        this.cfg = cfg;        
+        int blockCount = cfg.getBasicBlocks().size();
+        CfgNodeImpl[] nodes = new CfgNodeImpl[blockCount];
+        Map<BasicBlock, CfgNodeImpl> block2nodeMap = new HashMap<>();
+        Map<CfgNodeImpl, Set<CfgEdgeImpl>> inputMap = new HashMap<>();
+        ArrayList<CfgEdgeImpl> allEdges = new ArrayList<>();
+        List<BasicBlock> blocks = cfg.getBasicBlocks();           
+        //create nodes
+        for(int idx=0 ; idx < blockCount ; idx++) {
+            BasicBlock b = blocks.get(idx);
+            
+            String description = "Name: " + b.getName() + "\n";
+            description += "BCI: [" + b.getFromBci() + "," + b.getToBci() + "]\n";
+            if (b.getLoopDepth() > 0) {
+                description += "Loop " + b.getLoopIndex() + " Depth " + b.getLoopDepth() + "\n";
+            }
+            description += "Predecessors: " + getBlockList(b.getPredecessors()) + "\n";
+            description += "Successors: " + getBlockList(b.getSuccessors()) + "\n";
+            description += "XHandlers: " + getBlockList(b.getXhandlers());
+            if (b.getDominator() != null) {
+                description += "\nDominator: " + b.getDominator().getName();
+            } 
+            nodes[idx] = new CfgNodeImpl(b, idx, description);
+            block2nodeMap.put(b, nodes[idx]);
+        }
+        
+        
+        //create edges
+        Set<String> cache = new HashSet<>();//avoids identical edges with same source and same target
+        for(int i = 0 ; i < blockCount ; i++) {
+            BasicBlock b = blocks.get(i);       
+            List<CfgEdgeImpl> outputEdges = new ArrayList<>();           
+            
+            Set<BasicBlock> successors = new HashSet<>();
+            successors.addAll(b.getSuccessors());
+            successors.addAll(b.getXhandlers());
+            for(BasicBlock sb : successors) {  
+                CfgNodeImpl succNode = block2nodeMap.get(sb);
+                CfgEdgeImpl edge = new CfgEdgeImpl(nodes[i], succNode);                
+                if(cache.contains(edge.toString())) 
+                    continue;
+                cache.add(edge.toString());
+                //check for symtric edges              
+                if(sb.getXhandlers().contains(b) || sb.getSuccessors().contains(b)) 
+                    edge.setSymmetric(true);
+                outputEdges.add(edge);                         
+            }
+            allEdges.addAll(outputEdges);
+            nodes[i].setOutputEdges(outputEdges.toArray(new CfgEdgeImpl[outputEdges.size()]));    
+        }
+
+        for(CfgEdgeImpl e: allEdges) {
+            //CfgNodeImpl src = (CfgNodeImpl) e.getSourceNode();
+            CfgNodeImpl tar = (CfgNodeImpl) e.getTargetNode();
+            Set<CfgEdgeImpl> set = inputMap.get(tar);
+            if( set == null) {
+                set = new HashSet<>();      
+                set.add(e);
+                inputMap.put(tar, set);
+            }
+            set.add(e);    
+        }
+        for(CfgNodeImpl n : nodes){
+            Set<CfgEdgeImpl> inputEdges = inputMap.get(n);
+            if(inputEdges == null) continue;
+            n.setInputEdges(inputEdges.toArray(new CfgEdgeImpl[inputEdges.size()]));
+        }    
+        CfgEdgeImpl[] edges = allEdges.toArray(new CfgEdgeImpl[allEdges.size()]);
+        this.edgeArr=edges;
+        this.nodeArr=nodes;       
+        CfgNodeImpl rootNode = nodeArr[0];                   
+        setNodeLevels(rootNode);       
+        indexLoops(rootNode); 
+                          
+    }
+    
+    
+    private String getBlockList(List<? extends BasicBlock> blocks) {
+        if (blocks.size() == 0) {
+            return "None";
+        }
+        StringBuilder sb = new StringBuilder();
+        String prefix = "";
+        for (BasicBlock b : blocks) {
+            sb.append(prefix).append(b.getName());
+            prefix = ", ";
+        }
+        return sb.toString();
+    }
+ 
+    
+    public CfgNode[] getNodes(){
+        return this.nodeArr;
+    }
+    
+    public CfgEdge[] getEdges(){
+        return this.edgeArr;
+    }
+
+    public Map<CfgNode, LoopInfo> getLoopMap() {
+        return loopMap;
+    }
+
+    public void setLoopMap(Map<CfgNode, LoopInfo> loopMap) {
+        this.loopMap = loopMap;
+    }
+ 
+    private void indexLoops(CfgNodeImpl rootNode){
+         LoopEnv env = new LoopEnv(Arrays.asList(nodeArr));
+         loopDetection(env, rootNode);
+         calcLoopDepth(env);      
+                
+         int loopIndex=1;
+          
+         for(LoopInfo info : env.loopMap.values()) {
+             info.setLoopIndex(loopIndex++);
+             info.setLoopDepth(info.getHeader().getLoopDepth());
+             for(CfgNode n : info.getMembers()){
+                if(n.getLoopDepth()>info.getLoopDepth()) continue;
+                CfgNodeImpl ni = (CfgNodeImpl) n;  
+                ni.setLoopDepth(info.getLoopDepth());
+                ni.setLoopIndex(info.getLoopIndex());
+             }
+         }
+         
+         for(LoopInfo info : env.loopMap.values()) {          
+            HashSet<CfgNode> members =  new HashSet<>(info.getMembers());         
+            members.remove(info.getHeader());//remove own header
+            for(CfgNode n: members){              
+                if(n.isLoopHeader()) {                   
+                    LoopInfo memberInfo = env.loopMap.get(n);
+                    if (info.getLoopDepth() == memberInfo.getLoopDepth()-1)
+                        memberInfo.setParent(info);
+                }                    
+            }
+         }
+         this.loopMap = env.loopMap; 
+    }
+
+    
+    private class LoopEnv {   
+        Set<CfgNodeImpl> allNodes;
+        Set<CfgNodeImpl> activeNodes; 
+        Set<CfgNodeImpl> visitedNodes;       
+        Map<CfgNode, LoopInfo> loopMap;
+        private int loopIndex=0;
+        
+        public LoopEnv(Collection<CfgNodeImpl> nodes){
+            allNodes = new HashSet<>(nodes); 
+            activeNodes = new HashSet<>(2 * allNodes.size());
+            visitedNodes = new HashSet<>(2 * allNodes.size());   
+            loopMap = new HashMap<>();
+        }  
+        
+        public int getLoopIndex(){         
+            return ++loopIndex;           
+        }    
+    }
+      
+  
+    private void loopDetection(LoopEnv env, CfgNodeImpl root) {  
+        for (CfgNodeImpl n : env.allNodes) {
+            n.setLoopHeader(false);
+            for (CfgEdge e : n.getInputEdges()) {
+                CfgEdgeImpl ei = (CfgEdgeImpl) e;        
+                ei.setBackEdge(false);       
+            }
+        }
+        visit(env, root, null);
+    }
+   
+
+    
+    private void visit(LoopEnv env, CfgNodeImpl n, CfgEdgeImpl e) {
+        if (env.activeNodes.contains(n)) {
+            // This node is b loop header!
+            n.setLoopHeader(true);
+            e.setBackEdge(true);
+        } else if (!env.visitedNodes.contains(n)) {
+            env.visitedNodes.add(n);
+            env.activeNodes.add(n);
+            
+            for (CfgEdge edge : n.getOutputEdges()) {               
+                if(!edge.getTargetNode().isOSR()) {
+                    CfgEdgeImpl ei = (CfgEdgeImpl) edge;
+                    CfgNodeImpl ni = (CfgNodeImpl) edge.getTargetNode();
+                    visit(env, ni, ei);
+                }
+            }
+            env.activeNodes.remove(n);
+        }
+    }
+    
+    
+    
+    private void calcLoopDepth(LoopEnv env) {
+        for (CfgNodeImpl n : env.allNodes) {
+            env.visitedNodes.clear();
+
+            if (n.isLoopHeader()) {
+                LoopInfo loop = new LoopInfo();
+                loop.setHeader(n);
+                n.setLoopIndex(env.getLoopIndex());
+                HashSet<CfgNode> members = new HashSet<>();
+                loop.setMembers(members);
+                members.add(n);               
+                env.loopMap.put(loop.getHeader(), loop);
+                int loopDepth = n.getLoopDepth() + 1;
+                loop.setLoopDepth(loopDepth);
+                n.setLoopDepth(loopDepth);
+                for (CfgEdge e : n.getInputEdges())  {
+                    if (e.isBackEdge() && !e.getSourceNode().isOSR()) {
+                        CfgNodeImpl src = (CfgNodeImpl) e.getSourceNode();
+                        backwardIteration(env, n, src, loop);               
+                        loop.getBackEdges().add(e);
+                    }
+                }
+            }
+        }
+    }
+  
+
+    private void backwardIteration(LoopEnv env, CfgNodeImpl endNode, CfgNodeImpl n, LoopInfo loop) {
+        if (endNode != n && !env.visitedNodes.contains(n)) {
+            env.visitedNodes.add(n);
+
+            for (CfgEdge e : n.getInputEdges()) {
+                if (!e.getSourceNode().isOSR()) {
+                    CfgNodeImpl src = (CfgNodeImpl) e.getSourceNode();
+                    backwardIteration(env, endNode, src, loop);
+                }
+            }
+            loop.getMembers().add(n); 
+            n.setLoopDepth(n.getLoopDepth() + 1);
+        }
+    }
+    
+    private void setNodeLevels(CfgNode rootNode){
+        Set<CfgNode> cache = new HashSet<>();
+        Queue<CfgNode> queue = new LinkedList<>();
+        queue.add(rootNode);
+        cache.add(rootNode);
+        int level=0;
+        int[] nodeCount = new int[2];
+        nodeCount[0]=1;
+        while(!queue.isEmpty()){           
+            CfgNodeImpl curNode = (CfgNodeImpl) queue.poll();
+            curNode.setLevel(level);                 
+            nodeCount[0]--;       
+            for(CfgEdge outEdge : curNode.getOutputEdges()) {
+                CfgNode succNode = outEdge.getTargetNode();
+                if(cache.contains(succNode)) continue;
+                cache.add(succNode);
+                queue.add(succNode);
+                nodeCount[1]++;
+            }
+            if(nodeCount[0]==0){
+                nodeCount[0]=nodeCount[1];
+                nodeCount[1]=0;
+                level++;
+            }
+        }               
+    }
+
+    public ControlFlowGraph getCfg() {
+        return cfg;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/model/CfgNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,23 @@
+package at.ssw.visualizer.cfg.model;
+
+import at.ssw.visualizer.model.cfg.BasicBlock;
+
+
+public interface CfgNode {
+    //testers    
+    public boolean isOSR();
+    public boolean isRoot();
+    public boolean isLoopHeader();
+    public boolean isLoopMember();
+       
+    //getters
+    public int getLevel();
+    public int getLoopDepth();
+    public int getLoopIndex();
+    public int getNodeIndex();
+    public CfgEdge[] getInputEdges();
+    public CfgEdge[] getOutputEdges();
+    public BasicBlock getBasicBlock();
+    public String getDescription();
+   
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/model/CfgNodeImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,133 @@
+package at.ssw.visualizer.cfg.model;
+
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import java.awt.Color;
+
+
+
+public class CfgNodeImpl implements CfgNode {
+    private int nodeIndex;
+    private BasicBlock basicBlock;
+    private int level;   
+    private int loopDepth=0;
+    private int loopIndex=0; 
+    private boolean osr=false;
+    private CfgNodeImpl dominator=null;
+    private CfgEdgeImpl[] inputEdges = new CfgEdgeImpl[0];
+    private CfgEdgeImpl[] outputEdges = new CfgEdgeImpl[0];
+    private String description;
+    private Color customColor=null;
+    private boolean loopHeader;
+       
+    public CfgNodeImpl(BasicBlock bb, int nodeIndex, String description) {
+        this.basicBlock = bb;
+        this.nodeIndex = nodeIndex;  
+        this.description = description;
+        
+        if (bb.getPredecessors().size() == 1) {
+            BasicBlock pred = bb.getPredecessors().get(0);
+            boolean isStd = pred.getPredecessors().size() == 0;
+            if (isStd) {
+                for (String s : bb.getFlags()) {
+                    if (s.equals("osr")) {
+                        osr = true;
+                        break;
+                    }
+                }
+            }
+        }   
+    }
+
+    public int getNodeIndex() {
+        return nodeIndex;
+    }
+    
+    
+    public void setDominator(CfgNodeImpl dominator) {
+        this.dominator = dominator;
+    }
+
+    public void setLevel(int level) {
+        this.level = level;
+    }
+
+    public void setLoopDepth(int loopDepth) {
+        this.loopDepth = loopDepth;
+    }
+
+    public void setLoopHeader(boolean loopHeader) {
+        this.loopHeader = loopHeader;
+    }
+
+    public void setLoopIndex(int loopIndex) {
+        this.loopIndex = loopIndex;
+    }
+
+    public void setNodeIndex(int nodeIndex) {
+        this.nodeIndex = nodeIndex;
+    }
+       
+    public boolean isRoot() {
+        return nodeIndex==0;
+    }
+
+    public boolean isLoopHeader() {
+        return loopHeader;
+    }
+
+    public boolean isLoopMember() {
+        return loopIndex > 0;
+    }
+
+    public int getLevel() {
+        return level;
+    }
+
+    public BasicBlock getBasicBlock() {
+        return basicBlock;
+    }
+    
+    public int getLoopDepth() {
+        return loopDepth;
+    }
+
+    public int getLoopIndex() {
+        return loopIndex;
+    }
+   
+    public boolean isOSR() {
+        return osr;
+    }
+    
+    @Override
+    public String toString(){
+        return basicBlock.getName();
+    }
+
+    public void setInputEdges(CfgEdgeImpl[] inputEdges){
+        this.inputEdges = inputEdges;
+    }
+    
+    
+    public void setOutputEdges(CfgEdgeImpl[] outputEdges){
+        this.outputEdges = outputEdges;
+    }
+     
+    public CfgEdge[] getInputEdges() {
+        return this.inputEdges;
+    }
+
+    public CfgEdge[] getOutputEdges() {
+        return outputEdges;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setColor(Color color) {
+        this.customColor=color;
+    }
+
+   
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/model/LoopInfo.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+package at.ssw.visualizer.cfg.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+
+public class LoopInfo {  
+    private CfgNode header;//the target node of the backedge
+    private int loopIndex; //index of the min cycleSet
+    private int loopDepth; //nested depth >=1 
+    private LoopInfo parent=null;  
+    private Set<CfgNode> members;
+    private List<CfgEdge> backEdges = new ArrayList<>();//dfs backEdge
+
+    protected void setLoopDepth(int depth) {
+        this.loopDepth=depth;
+    }
+
+    protected void setLoopIndex(int loopIndex) {
+        this.loopIndex = loopIndex;
+    }
+
+    public int getLoopDepth() {
+        return loopDepth;
+    }
+            
+    public Set<CfgNode> getMembers() {
+        return members;
+    }
+
+    protected void setMembers(Set<CfgNode> members) {
+        this.members = members;
+    }
+        
+    public int getLoopIndex() {
+        return loopIndex;
+    }
+
+    protected void setParent(LoopInfo parent) {
+        this.parent = parent;
+    }
+    
+    public LoopInfo getParent(){
+        return parent;
+    }
+    
+    public List<CfgEdge> getBackEdges() {
+        return backEdges;
+    }
+
+    public CfgNode getHeader() {
+        return header;
+    }
+
+    protected void setHeader(CfgNode header) {
+        this.header = header;
+    }
+
+    @Override
+    public String toString(){
+        return "Loop(" + header.toString()+ ")-->" + members.toString();
+    }
+
+    
+  
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/preferences/CFGOptionsCategory.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,32 @@
+package at.ssw.visualizer.cfg.preferences;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import org.netbeans.spi.options.OptionsCategory;
+import org.netbeans.spi.options.OptionsPanelController;
+import org.openide.util.ImageUtilities;
+
+/**
+ * Descriptor for the settings page displayed in the options dialog.
+ *
+ * @author Bernhard Stiftner
+ */
+public class CFGOptionsCategory extends OptionsCategory {
+    
+    public OptionsPanelController create() {
+        return new CFGOptionsPanelController();
+    }
+
+    public String getCategoryName() {
+        return "Control Flow Graph";
+    }
+
+    @Override
+    public Icon getIcon() {
+        return new ImageIcon(ImageUtilities.loadImage("at/ssw/visualizer/cfg/icons/cfg32.gif"));
+    }
+
+    public String getTitle() {
+        return "CFG Visualizer";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/preferences/CFGOptionsPanel.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,482 @@
+package at.ssw.visualizer.cfg.preferences;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.AbstractAction;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.SwingConstants;
+
+/**
+ * The actual component for changing the CFG visualizer settings.
+ *
+ * @author Bernhard Stiftner
+ * @author Rumpfhuber Stefan
+ */
+public class CFGOptionsPanel extends JPanel {
+
+    List<ConfigurationElement> elements = new ArrayList<>();
+
+    /** Creates a new instance of CFGOptionsPanel */
+    public CFGOptionsPanel() {
+        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+        JPanel cfgPanel = new JPanel(new GridBagLayout());
+
+        // color/font settings
+        addColorChooser(cfgPanel, "Background color: ", new ColorChooser(CfgPreferences.PROP_BACKGROUND_COLOR){
+            @Override
+            public void apply() {
+                CfgPreferences.getInstance().setBackgroundColor(getColor());              
+            }
+
+            @Override
+            public void update() {
+               this.originalColor = CfgPreferences.getInstance().getBackgroundColor();
+               setColor(this.originalColor);
+            }
+            
+             public void reset() {
+                this.setColor(CfgPreferencesDefaults.DEFAULT_BACKGROUND_COLOR);
+            }
+            
+            
+           
+        });
+        addColorChooser(cfgPanel, "Back edge color: ", new ColorChooser(CfgPreferences.PROP_BACK_EDGE_COLOR){
+
+            @Override
+            public void apply() {               
+                CfgPreferences.getInstance().setBackedgeColor(getColor());                 
+            }
+
+            @Override
+            public void update() {
+                this.originalColor = CfgPreferences.getInstance().getBackedgeColor();
+                this.setColor(this.originalColor);
+
+            }
+
+            public void reset() {
+                this.setColor(CfgPreferencesDefaults.DEFAULT_BACKEDGE_COLOR);
+            }
+        });
+        addColorChooser(cfgPanel, "Edge color: ", new ColorChooser(CfgPreferences.PROP_EDGE_COLOR){
+
+            @Override
+            public void apply() {               
+                CfgPreferences.getInstance().setEdgeColor(getColor());  
+            }
+
+            @Override
+            public void update() {
+                this.originalColor = CfgPreferences.getInstance().getEdgeColor(); 
+                setColor(this.originalColor);
+            }
+            
+            public void reset() {
+                this.setColor(CfgPreferencesDefaults.DEFAULT_EDGE_COLOR);
+            }
+            
+        });
+        addColorChooser(cfgPanel, "Exception edge color: ", new ColorChooser(CfgPreferences.PROP_EXCEPTION_EDGE_COLOR){
+
+            @Override
+            public void apply() {             
+                CfgPreferences.getInstance().setExceptionEdgeColor(getColor());  
+            }
+
+            @Override
+            public void update() {
+                this.originalColor = CfgPreferences.getInstance().getExceptionEdgeColor();
+                setColor(this.originalColor);
+                
+            }
+            
+            public void reset() {
+                this.setColor(CfgPreferencesDefaults.DEFAULT_EXCEPTIONEDGE_COLOR);
+            }
+        });
+        addColorChooser(cfgPanel, "Node color: ", new ColorChooser(CfgPreferences.PROP_NODE_COLOR){
+
+            @Override
+            public void apply() {
+               CfgPreferences.getInstance().setNodeColor(getColor());  
+            }
+
+            @Override
+            public void update() {
+                this.originalColor = CfgPreferences.getInstance().getNodeColor();
+                setColor(this.originalColor);
+                
+            }
+            
+            public void reset() {
+                this.setColor(CfgPreferencesDefaults.DEFAUT_NODE_COLOR);
+            }
+        });
+        addColorChooser(cfgPanel, "Text color: ", new ColorChooser(CfgPreferences.PROP_TEXT_COLOR){
+
+            @Override
+            public void apply() {
+               CfgPreferences.getInstance().setTextColor(getColor());  
+            }
+
+            @Override
+            public void update() {
+               this.originalColor = CfgPreferences.getInstance().getTextColor();
+               
+            }
+            
+            public void reset() {
+                this.setColor(CfgPreferencesDefaults.DEFAULT_TEXT_COLOR);
+            }
+        });     
+        addColorChooser(cfgPanel, "Border color: ", new ColorChooser(CfgPreferences.PROP_BORDER_COLOR){
+
+            @Override
+            public void apply() {
+                CfgPreferences.getInstance().setBorderColor(getColor());  
+            }
+
+            @Override
+            public void update() {
+                this.originalColor = CfgPreferences.getInstance().getBorderColor();
+                setColor(this.originalColor);
+                
+            }
+            public void reset() {
+                this.setColor(CfgPreferencesDefaults.DEFAULT_BORDER_COLOR);
+            }
+        });
+        addColorChooser(cfgPanel, "Selected Nodes color: ", new ColorChooser(CfgPreferences.PROP_SELECTION_COLOR_FG){
+
+            @Override
+            public void apply() {
+                CfgPreferences.getInstance().setSelectionColorForeground(getColor());  
+            }
+
+            @Override
+            public void update() {
+                this.originalColor = CfgPreferences.getInstance().getSelectionColorForeground();
+                setColor(this.originalColor);
+            }
+            
+            public void reset() {
+                this.setColor(CfgPreferencesDefaults.DEFAULT_SELECTION_COLOR_FOREGROUND);
+            }
+        });
+        addColorChooser(cfgPanel, "Selection Rect color: ", new ColorChooser(CfgPreferences.PROP_SELECTION_COLOR_BG){
+
+            @Override
+            public void apply() {
+                CfgPreferences.getInstance().setSelectionColorBackground(getColor());
+            }
+
+            @Override
+            public void update() {
+                this.originalColor = CfgPreferences.getInstance().getSelectionColorBackground();
+                setColor(this.originalColor);
+            }
+            
+            public void reset() {
+                this.setColor(CfgPreferencesDefaults.DEFAULT_SELECTION_COLOR_BACKGROUND);
+            }
+        });
+        addFontChooser(cfgPanel, "Text font: ", new FontChooser(CfgPreferences.PROP_TEXT_FONT){
+
+            @Override
+            public void apply() {
+                CfgPreferences.getInstance().setTextFont(getSelectedFont());                
+            }
+
+            @Override
+            public void update() {
+                this.originalFont = CfgPreferences.getInstance().getTextFont();
+                this.setSelectedFont(originalFont);
+                
+            }
+            
+            public void reset() {
+                this.setSelectedFont(CfgPreferencesDefaults.DEFAULT_TEXT_FONT);
+            }
+        });
+
+        // flags editor
+        addFlagsEditor(cfgPanel, "Flags: ");
+        add(cfgPanel);
+
+        // add update button
+        Box hBox = new Box(BoxLayout.X_AXIS);
+        hBox.add(new JButton(new ResetAction()));
+        hBox.add(Box.createHorizontalGlue());
+        add(hBox);
+
+        add(Box.createVerticalGlue());
+    }
+    
+    public void update() {
+        for (ConfigurationElement e : elements) {          
+            e.update();
+        }
+    }
+
+    public void cancel() {
+        for (ConfigurationElement e : elements) {
+            e.update();
+        }
+    }
+
+    public void applyChanges() {
+        for (ConfigurationElement e : elements) {
+            if(e.isChanged())
+                e.apply();
+        }
+    }
+
+    public boolean isDataValid() {
+        return true;
+    }
+
+    public boolean isChanged() {
+        for (ConfigurationElement e : elements) {
+            if (e.isChanged()) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    public void loadDefault() {
+        for (ConfigurationElement e : elements) {
+            e.reset();
+        }
+    }
+
+    private void addColorChooser(JComponent c, String displayName, ColorChooser chooser) {
+        GridBagLayout layout = (GridBagLayout)c.getLayout();
+        GridBagConstraints constraints = new GridBagConstraints();
+        constraints.insets = new Insets(3, 3, 3, 3);
+        constraints.weightx = 0.0;
+        constraints.fill = GridBagConstraints.NONE;
+        constraints.anchor = GridBagConstraints.EAST;
+        JLabel label = new JLabel(displayName, JLabel.TRAILING);
+        layout.setConstraints(label, constraints);
+        c.add(label);
+        constraints.anchor = GridBagConstraints.WEST;
+        constraints.gridwidth = GridBagConstraints.REMAINDER;
+        layout.setConstraints(chooser, constraints);
+        c.add(chooser);
+        elements.add(chooser);
+        label.setLabelFor(chooser);
+    }
+
+   
+
+    private void addFontChooser(JComponent c, String displayName, FontChooser chooser) {
+        GridBagLayout layout = (GridBagLayout)c.getLayout();
+        GridBagConstraints constraints = new GridBagConstraints();
+        constraints.insets = new Insets(3, 3, 3, 3);
+        constraints.weightx = 0.0;
+        constraints.fill = GridBagConstraints.NONE;
+        constraints.anchor = GridBagConstraints.EAST;
+        JLabel label = new JLabel(displayName, JLabel.TRAILING);
+        layout.setConstraints(label, constraints);
+        c.add(label);
+        constraints.insets = new Insets(3, 3, 3, 1);
+        constraints.weightx = 1.0;
+        constraints.fill = GridBagConstraints.HORIZONTAL;
+        constraints.anchor = GridBagConstraints.CENTER;
+        layout.setConstraints(chooser.getPreview(), constraints);
+        c.add(chooser.getPreview());
+        constraints.insets = new Insets(3, 1, 3, 3);
+        constraints.weightx = 0.0;
+        constraints.fill = GridBagConstraints.NONE;
+        constraints.anchor = GridBagConstraints.EAST;
+        constraints.gridwidth = GridBagConstraints.REMAINDER;
+        layout.setConstraints(chooser.getButton(), constraints);
+        c.add(chooser.getButton());
+        elements.add(chooser);
+        label.setLabelFor(chooser.getButton());
+    }
+
+    private void addFlagsEditor(JComponent c, String displayName) {
+        GridBagLayout layout = (GridBagLayout)c.getLayout();
+        GridBagConstraints constraints = new GridBagConstraints();
+        constraints.insets = new Insets(3, 3, 3, 3);
+        constraints.weightx = 0.0;
+        constraints.fill = GridBagConstraints.NONE;
+        constraints.anchor = GridBagConstraints.NORTHEAST;
+        FlagsEditor flagsEditor = new FlagsEditor();
+        JLabel flagsLabel = new JLabel(displayName, JLabel.TRAILING);
+        flagsLabel.setVerticalAlignment(SwingConstants.TOP);
+        layout.setConstraints(flagsLabel, constraints);
+        c.add(flagsLabel);
+        constraints.weightx = 1.0;
+        constraints.weighty = 1.0;
+        constraints.fill = GridBagConstraints.BOTH;
+        constraints.anchor = GridBagConstraints.CENTER;
+        constraints.gridwidth = GridBagConstraints.REMAINDER;
+        layout.setConstraints(flagsEditor, constraints);
+        c.add(flagsEditor);
+        elements.add(flagsEditor);
+        flagsLabel.setLabelFor(flagsEditor);
+    }
+
+    
+    
+
+    interface ConfigurationElement {
+
+        public boolean isChanged();
+        
+        //apply changes to preferences
+        public void apply();
+        
+        //optain current value from preferences
+        public void update();
+        
+        //reset to default value
+        public void reset();
+        
+    }
+    
+    abstract class ColorChooser extends ColorChooserButton implements ConfigurationElement {
+
+        Color originalColor;//the color before any change
+        String propertyName;
+
+        public ColorChooser(String propertyName) {
+            this.propertyName = propertyName;
+        }
+        
+        public boolean isChanged() {
+            return !originalColor.equals(getColor());
+        }
+        
+        
+        public abstract void apply();
+        public abstract void update();
+
+    }
+    
+
+    abstract class FontChooser implements ConfigurationElement, ActionListener {
+
+        Font originalFont;
+        Font selectedFont;
+        String propertyName;
+        JTextField preview;
+        JButton button;
+
+        public FontChooser(String propertyName) {
+            this.propertyName = propertyName;
+            preview = new JTextField("");
+            preview.setEditable(false);
+            button = new JButton("...");
+            button.setMargin(new Insets(0, 0, 0, 0));
+            button.addActionListener(this);
+        }
+
+        public boolean isChanged() {
+            return !originalFont.equals(selectedFont);
+        }
+        
+        public abstract void apply();
+        
+        public abstract void update();
+        
+        public abstract void reset();
+
+        public JTextField getPreview() {
+            return preview;
+        }
+
+        public JButton getButton() {
+            return button;
+        };
+
+        public Font getSelectedFont() {
+            return selectedFont;
+        }
+
+        public void setSelectedFont(Font f) {
+            selectedFont = f;
+            preview.setText(fontToString(f));
+            preview.revalidate();
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            setSelectedFont(FontChooserDialog.show(selectedFont));
+        }
+
+        public String fontToString(Font font) {
+            StringBuffer sb = new StringBuffer();
+            sb.append(font.getName());
+            sb.append(" ");
+            sb.append(font.getSize());
+            if (font.isBold()) {
+                sb.append(" bold");
+            }
+            if (font.isItalic()) {
+                sb.append(" italic");
+            }
+            return sb.toString();
+        }
+
+    }
+
+    class FlagsEditor extends FlagsEditorPanel implements ConfigurationElement {
+
+        FlagsSetting originalFlags;
+
+        public FlagsEditor() {
+            super(null);    
+        }
+
+        public boolean isChanged() {
+            return !originalFlags.getFlagString().equals(getFlagString());
+        }
+
+        public void apply() {
+            CfgPreferences.getInstance().setFlagsSetting(new FlagsSetting(getFlagString()));
+            update();
+        }
+
+        public void update() {
+            originalFlags = CfgPreferences.getInstance().getFlagsSetting();
+            setFlagString(originalFlags.getFlagString());
+        }
+
+        public void reset() {
+            FlagsSetting defaultFlags = new FlagsSetting(CfgPreferencesDefaults.DEFAULT_FLAGSTRING);
+            setFlagString(defaultFlags.getFlagString());
+            colorButton.setColor(getParent().getBackground());            
+        }
+
+    }
+
+    class ResetAction extends AbstractAction {
+
+        public ResetAction() {
+            super("Reset");
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            CFGOptionsPanel.this.loadDefault();           
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/preferences/CFGOptionsPanelController.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+package at.ssw.visualizer.cfg.preferences;
+
+import java.beans.PropertyChangeListener;
+import javax.swing.JComponent;
+import org.netbeans.spi.options.OptionsPanelController;
+import org.openide.util.HelpCtx;
+import org.openide.util.Lookup;
+
+/**
+ * Controller for the settings page displayed in the options dialog.
+ *
+ * @author Bernhard Stiftner
+ */
+public class CFGOptionsPanelController extends OptionsPanelController {
+
+    CFGOptionsPanel optionsPanel;
+
+    
+    public void update() {
+        getOptionsPanel().update();       
+    }
+
+    public void applyChanges() {
+        getOptionsPanel().applyChanges();
+    }
+
+    public void cancel() {
+        getOptionsPanel().cancel();
+    }
+
+    public boolean isValid() {
+        return getOptionsPanel().isDataValid();
+    }
+
+    public boolean isChanged() {
+        return getOptionsPanel().isChanged();
+    }
+
+    public JComponent getComponent(Lookup masterLookup) {
+        return getOptionsPanel();
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+    
+    public void addPropertyChangeListener(PropertyChangeListener l) {
+        getOptionsPanel().addPropertyChangeListener(l);
+    }
+
+    //todo: investigate - who removes the changelistener ?
+    public void removePropertyChangeListener(PropertyChangeListener l) {
+        getOptionsPanel().removePropertyChangeListener(l);
+    }
+
+    private CFGOptionsPanel getOptionsPanel() {
+        if (optionsPanel == null) {
+            optionsPanel = new CFGOptionsPanel();
+        }
+        return optionsPanel;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/preferences/CfgPreferences.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,239 @@
+package at.ssw.visualizer.cfg.preferences;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.prefs.Preferences;
+import javax.swing.event.EventListenerList;
+import org.openide.util.NbPreferences;
+
+/**
+ * Replacement for old CFGSettings to remove dependency on deprecated SystemOption package
+ * 
+ * @author Rumpfhuber Stefan
+ */
+public class CfgPreferences  {
+    public static final String PROP_FLAGS = "flagsPreference";
+    public static final String PROP_TEXT_FONT = "textFontPreference";
+    public static final String PROP_TEXT_COLOR = "textColorPreference";
+    public static final String PROP_NODE_COLOR = "nodeColorPreference";
+    public static final String PROP_EDGE_COLOR = "edgeColorPreference";
+    public static final String PROP_BORDER_COLOR = "borderColorPreference";
+    public static final String PROP_BACK_EDGE_COLOR = "backEdgeColorPreference";
+    public static final String PROP_BACKGROUND_COLOR = "backgroundColorPreference";
+    public static final String PROP_SELECTION_COLOR_FG = "selectionColorFgPreference";
+    public static final String PROP_SELECTION_COLOR_BG = "selectionColorBgPreference";
+    public static final String PROP_EXCEPTION_EDGE_COLOR = "exceptionEdgeColorPreference";
+    
+    private static final String PROP_FONTNAME = "_FontFamily";
+    private static final String PROP_FONTSIZE = "_FontSize";
+    private static final String PROP_FONTSTYLE = "_FontStyle";
+    
+    protected static final String nodeName = "CfgPreferences";
+      
+    private static CfgPreferences instance = new CfgPreferences();
+    private EventListenerList listenerList;
+       
+    private FlagsSetting flagsSetting;
+    private Color node_color; 
+    private Color background_color; 
+    private Color backedge_color; 
+    private Color edge_color;
+    private Color border_color;
+    private Color exceptionEdgeColor;
+    private Color text_color;
+    private Font  text_font;
+    private Color selection_color_fg;
+    private Color selection_color_bg;
+    
+    
+    private  CfgPreferences(){        
+        listenerList = new EventListenerList();       
+        init();           
+    }
+    
+    public static CfgPreferences getInstance(){
+        return instance;
+    }
+
+    protected final Preferences getPreferences() {
+        return NbPreferences.forModule(this.getClass()).node("options").node(nodeName);
+    }
+    
+    
+    protected void init(){
+        Preferences prefs = this.getPreferences();
+        String flagString = prefs.get(PROP_FLAGS, CfgPreferencesDefaults.DEFAULT_FLAGSTRING);
+        flagsSetting = new FlagsSetting(flagString);
+        node_color = this.getColorProperty(PROP_NODE_COLOR, CfgPreferencesDefaults.DEFAUT_NODE_COLOR);
+        background_color = this.getColorProperty(PROP_BACKGROUND_COLOR, CfgPreferencesDefaults.DEFAULT_BACKGROUND_COLOR); 
+        backedge_color = this.getColorProperty(PROP_BACK_EDGE_COLOR, CfgPreferencesDefaults.DEFAULT_BACKEDGE_COLOR); 
+        edge_color = this.getColorProperty(PROP_EDGE_COLOR, CfgPreferencesDefaults.DEFAULT_EDGE_COLOR);
+        selection_color_fg= this.getColorProperty(PROP_SELECTION_COLOR_FG, CfgPreferencesDefaults.DEFAULT_SELECTION_COLOR_FOREGROUND);
+        border_color = this.getColorProperty(PROP_BORDER_COLOR, CfgPreferencesDefaults.DEFAULT_BORDER_COLOR);
+        exceptionEdgeColor = this.getColorProperty(PROP_EXCEPTION_EDGE_COLOR, CfgPreferencesDefaults.DEFAULT_EXCEPTIONEDGE_COLOR);
+        text_color= this.getColorProperty(PROP_TEXT_COLOR, CfgPreferencesDefaults.DEFAULT_TEXT_COLOR);
+        selection_color_bg = this.getColorProperty(PROP_SELECTION_COLOR_BG, CfgPreferencesDefaults.DEFAULT_SELECTION_COLOR_BACKGROUND);
+        selection_color_fg = this.getColorProperty(PROP_SELECTION_COLOR_FG, CfgPreferencesDefaults.DEFAULT_SELECTION_COLOR_FOREGROUND);
+        text_font = this.getFontProperty(PROP_TEXT_FONT, CfgPreferencesDefaults.DEFAULT_TEXT_FONT);     
+    }
+         
+    private void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
+        Object[] listeners = listenerList.getListenerList();   
+       
+        PropertyChangeEvent event = new PropertyChangeEvent(this, propertyName, oldValue, newValue);
+        for (int i = listeners.length - 2; i >= 0; i -= 2) {
+            if (listeners[i] == PropertyChangeListener.class) {
+                ((PropertyChangeListener) listeners[i+1]).propertyChange(event);
+            }
+        }
+    }
+    
+    private Font getFontProperty(String propName, Font defaultFont){
+        Preferences prefs = this.getPreferences();
+        String fontName = prefs.get(propName+PROP_FONTNAME, defaultFont.getFamily());
+        int fontSize = prefs.getInt(propName+PROP_FONTSIZE, defaultFont.getSize());
+        int fontStyle = prefs.getInt(propName+PROP_FONTSTYLE, defaultFont.getStyle());                
+        return new Font(fontName, fontStyle, fontSize);   
+    }
+       
+    private Color getColorProperty(String propName, Color defaultColor){
+        Preferences prefs = this.getPreferences();
+        int srgb = prefs.getInt(propName, defaultColor.getRGB());
+        if(srgb == defaultColor.getRGB())
+            return defaultColor;
+        return new Color(srgb);
+    }
+     
+    public Color getBackedgeColor() {
+        return backedge_color;
+    }
+  
+    public Color getBackgroundColor() {
+        return background_color;
+    }
+
+    public Color getBorderColor() {
+        return border_color;
+    }
+ 
+    public Color getEdgeColor() {
+        return edge_color;
+    }
+
+    public Color getExceptionEdgeColor() {
+        return exceptionEdgeColor;
+    }
+   
+    public Color getNodeColor() {
+        return node_color;
+    }
+
+    public Color getSelectionColorForeground() {
+        return selection_color_fg;
+    }
+    
+    public Color getSelectionColorBackground() {
+        return selection_color_bg;
+    }
+
+    public Color getTextColor() {
+        return text_color;
+    }
+
+    public Font getTextFont() {
+        return text_font;
+    }
+
+    public FlagsSetting getFlagsSetting() {
+        return flagsSetting;
+    }
+    
+    
+    public void setFlagsSetting(FlagsSetting flagsSetting) {
+        FlagsSetting old = this.getFlagsSetting();
+        this.flagsSetting = flagsSetting;
+        Preferences prefs = getPreferences();
+        firePropertyChange(PROP_FLAGS, old, flagsSetting);
+        prefs.put(PROP_FLAGS, flagsSetting.getFlagString());
+    }
+    
+
+    public void setTextFont(Font text_font) {
+        Font old = this.getTextFont();
+        Preferences prefs = getPreferences();
+        this.text_font = text_font;
+        firePropertyChange(PROP_TEXT_FONT, old, text_font);
+        prefs.put(PROP_TEXT_FONT + PROP_FONTNAME , text_font.getFamily());
+        prefs.putInt(PROP_TEXT_FONT + PROP_FONTSIZE, text_font.getSize());
+        prefs.putInt(PROP_TEXT_FONT + PROP_FONTSTYLE, text_font.getStyle());   
+    }
+    
+   public void setBackedgeColor(Color backedge_color) {
+        Color old = this.getBackedgeColor();        
+        this.backedge_color = backedge_color;
+        firePropertyChange(PROP_BACK_EDGE_COLOR, old, backedge_color);
+        getPreferences().putInt(PROP_BACK_EDGE_COLOR, backedge_color.getRGB());        
+    }
+
+    public void setBackgroundColor(Color bg_color) {
+        Color old = this.getBackgroundColor();
+        background_color = bg_color;
+        firePropertyChange(PROP_BACKGROUND_COLOR, old, bg_color );
+        getPreferences().putInt(PROP_BACKGROUND_COLOR, bg_color.getRGB());      
+    }
+
+    public void setBorderColor(Color border_color) {
+        Color old = getBorderColor();      
+        this.border_color = border_color;
+        firePropertyChange(PROP_BORDER_COLOR, old, border_color );
+        getPreferences().putInt(PROP_BORDER_COLOR, border_color.getRGB());       
+    }
+
+    public void setEdgeColor(Color edge_color) {
+        Color old = getEdgeColor();     
+        this.edge_color = edge_color;
+        firePropertyChange(PROP_EDGE_COLOR, old, edge_color);
+        getPreferences().putInt(PROP_EDGE_COLOR, edge_color.getRGB());      
+    }
+    
+    public void setNodeColor(Color node_color) {
+        Color old = getNodeColor();      
+        this.node_color = node_color;
+        firePropertyChange(PROP_NODE_COLOR, old, node_color);
+        getPreferences().putInt(PROP_NODE_COLOR, node_color.getRGB());
+        
+    }
+    
+    public void setSelectionColorForeground(Color selection_color) {
+         Color old = this.getSelectionColorForeground();   
+         this.selection_color_fg = selection_color;
+         firePropertyChange(PROP_SELECTION_COLOR_FG, old, selection_color);
+         getPreferences().putInt(PROP_SELECTION_COLOR_FG, selection_color.getRGB());       
+    }
+    
+    public void setSelectionColorBackground(Color selection_color) {
+         Color old = this.getSelectionColorBackground();   
+         this.selection_color_bg = selection_color;
+         firePropertyChange(PROP_SELECTION_COLOR_BG, old, selection_color);
+         getPreferences().putInt(PROP_SELECTION_COLOR_BG, selection_color.getRGB());       
+    }
+    
+    public void setTextColor(Color text_color) {
+         Color old = this.getTextColor();       
+         this.text_color = text_color;
+         firePropertyChange(PROP_TEXT_COLOR, old, text_color);
+         getPreferences().putInt(PROP_TEXT_COLOR, text_color.getRGB());     
+    }
+    
+    public void setExceptionEdgeColor(Color exceptionEdgeColor) {
+        Color old = this.getExceptionEdgeColor();  
+        this.exceptionEdgeColor = exceptionEdgeColor;
+        firePropertyChange(PROP_EXCEPTION_EDGE_COLOR, old, exceptionEdgeColor);
+        getPreferences().putInt(PROP_EXCEPTION_EDGE_COLOR, exceptionEdgeColor.getRGB());       
+    }
+
+   
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/preferences/CfgPreferencesDefaults.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,23 @@
+package at.ssw.visualizer.cfg.preferences;
+
+import java.awt.Color;
+import java.awt.Font;
+
+/**
+ * Default Configuration for options panel
+ * 
+ * @author Rumpfhuber Stefan
+ */
+public final class CfgPreferencesDefaults {    
+    public static final String DEFAULT_FLAGSTRING = "std(224,224,128);osr(224,224,0);ex(128,128,224);sr(128,224,128);llh(224,128,128);lle(224,192,192);plh(128,224,128);bb(160,0,0);ces(192,192,192)";
+    public static final Color DEFAUT_NODE_COLOR = new Color(208, 208, 208);
+    public static final Color DEFAULT_BACKGROUND_COLOR =  new Color(255, 255, 255);
+    public static final Color DEFAULT_BACKEDGE_COLOR = new Color(160, 0, 0);
+    public static final Color DEFAULT_EDGE_COLOR = new Color(0, 0, 0);
+    public static final Color DEFAULT_SELECTION_COLOR_FOREGROUND = Color.BLUE;
+    public static final Color DEFAULT_SELECTION_COLOR_BACKGROUND = Color.BLUE;
+    public static final Color DEFAULT_BORDER_COLOR = new Color(0, 0, 0);
+    public static final Color DEFAULT_EXCEPTIONEDGE_COLOR = new Color(0, 0, 160);
+    public static final Color DEFAULT_TEXT_COLOR = new Color(0, 0, 0);
+    public static final Font  DEFAULT_TEXT_FONT = new Font("Dialog", Font.PLAIN, 18);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/preferences/ColorChooserButton.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,94 @@
+package at.ssw.visualizer.cfg.preferences;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JColorChooser;
+
+/**
+ * A color selection button. It will preview the currently selected color as
+ * an icon. Clicking the button will bring up the JColorChooser dialog.
+ *
+ * @author Bernhard Stiftner
+ */
+public class ColorChooserButton extends JButton implements ActionListener {
+
+    public static final Dimension ICON_SIZE = new Dimension(24, 8);
+
+    Color color;
+    boolean colorChooserEnabled = true; // bring up dialog when clicked?
+
+
+    public ColorChooserButton() {
+        this(Color.black);
+    }
+
+    public ColorChooserButton(Color defaultColor) {
+        setIcon(new ColorBoxIcon());
+        addActionListener(this);
+        color = defaultColor;
+        Dimension size = new Dimension(ICON_SIZE);
+        size.width += getInsets().left + getInsets().right;
+        size.height += getInsets().top + getInsets().bottom;
+        setPreferredSize(size);
+    }
+
+    public void setColor(Color newColor) {
+        color = newColor;
+        repaint();
+    }
+
+    public Color getColor() {
+        return color;
+    }
+
+    public boolean isColorChooserEnabled() {
+        return colorChooserEnabled;
+    }
+
+    public void setColorChooserEnabled(boolean enabled) {
+        this.colorChooserEnabled = enabled;
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        if (!colorChooserEnabled) {
+            return;
+        }
+
+        Color c = JColorChooser.showDialog(this, "Choose color", color);
+        if (c != null) {
+            setColor(c);
+        }
+    }
+
+    class ColorBoxIcon implements Icon {
+
+        public int getIconWidth() {
+            return ICON_SIZE.width;
+        }
+
+        public int getIconHeight() {
+            return ICON_SIZE.height;
+        }
+
+        public void paintIcon(Component c, Graphics g, int x, int y) {
+            Color oldColor = g.getColor();
+            g.translate(x, y);
+
+            g.setColor(color);
+            g.fillRect(0, 0, ICON_SIZE.width, ICON_SIZE.height);
+
+            g.setColor(Color.black);
+            g.drawRect(0, 0, ICON_SIZE.width, ICON_SIZE.height);
+
+            g.translate(-x, -y);
+            g.setColor(oldColor);
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/preferences/FlagsEditorPanel.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,247 @@
+package at.ssw.visualizer.cfg.preferences;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.DefaultListModel;
+import javax.swing.JButton;
+import javax.swing.JColorChooser;
+import javax.swing.JComponent;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+/**
+ *
+ * @author Bernhard Stiftner
+ * @author Rumpfhuber Stefan
+ */
+public class FlagsEditorPanel extends JPanel implements ActionListener,
+        ListSelectionListener {
+
+    FlagListModel listModel;
+    JList list;
+    ColorChooserButton colorButton;
+    JButton newButton;
+    JButton removeButton;
+    JButton upButton;
+    JButton downButton;
+
+
+    /** Creates a new instance of FlagsEditorPanel */
+    public FlagsEditorPanel(String flagString) {
+        setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
+
+        listModel = new FlagListModel(flagString);
+        list = new JList(listModel);
+        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        list.addListSelectionListener(this);
+        add(new JScrollPane(list));
+
+        add(Box.createHorizontalStrut(3));
+
+        Box buttonBox = new Box(BoxLayout.Y_AXIS);
+        buttonBox.add(colorButton = new ColorChooserButton());
+        buttonBox.add(newButton = new JButton("New..."));
+        buttonBox.add(removeButton = new JButton("Remove"));
+        buttonBox.add(upButton = new JButton("Up"));
+        buttonBox.add(downButton = new JButton("Down"));
+        buttonBox.add(Box.createVerticalGlue());
+        add(buttonBox);
+        layoutButtonContainer(buttonBox);
+
+        colorButton.setColorChooserEnabled(false);
+        colorButton.addActionListener(this);
+        newButton.addActionListener(this);
+        removeButton.addActionListener(this);
+        upButton.addActionListener(this);
+        downButton.addActionListener(this);
+
+        selectionChanged(-1); // no selection
+    }
+
+    /**
+     * Ugly helper to make a nice layout for vertically aligned buttons.
+     */
+    private static void layoutButtonContainer(JComponent buttonContainer) {
+        int width = 0;
+        int height = 0;
+
+        for (int i=0; i<buttonContainer.getComponentCount(); i++) {
+            Component c = buttonContainer.getComponent(i);
+            if (c instanceof JButton) {
+                JButton b = (JButton)c;
+                if (width < b.getPreferredSize().width) {
+                    width = b.getPreferredSize().width;
+                }
+                if (height < b.getPreferredSize().height) {
+                    height = b.getPreferredSize().height;
+                }
+            }
+        }
+
+        Dimension commonButtonSize = new Dimension(width, height);
+
+        for (int i=0; i<buttonContainer.getComponentCount(); i++) {
+            Component c = buttonContainer.getComponent(i);
+            if (c instanceof JButton) {
+                JButton b = (JButton)c;
+                b.setMinimumSize(commonButtonSize);
+                b.setPreferredSize(commonButtonSize);
+                b.setMaximumSize(commonButtonSize);
+            }
+        }
+
+    }
+
+    public String getFlagString() {
+        return listModel.getFlagString();
+    }
+
+    public void setFlagString(String flagString) {
+        listModel.setFlagString(flagString);
+    }
+    
+    public void actionPerformed(ActionEvent e) {
+        Object source = e.getSource();
+        if (source == colorButton) {
+            changeColor();
+        } else if (source == newButton) {
+            String s = JOptionPane.showInputDialog(this,
+                    "Type in the flag which should fill the block with a specific color");
+            if (s == null) {
+                return;
+            }
+            s = s.replace('(', ' ');
+            s = s.replace(';', ' ');
+            int index = list.getSelectedIndex()+1;
+            listModel.insertElementAt(new FlagListItem(s, Color.WHITE), index);
+        } else if (source == removeButton) {
+            listModel.removeElementAt(list.getSelectedIndex());
+        } else if (source == upButton) {
+            int index = list.getSelectedIndex();
+            if (index == 0) {
+                return;
+            }
+            Object o = listModel.getElementAt(index);
+            listModel.removeElementAt(index);
+            listModel.insertElementAt(o, index-1);
+        } else if (source == downButton) {
+            int index = list.getSelectedIndex();
+            if (index >= listModel.size()-1) {
+                return;
+            }
+            Object o = listModel.getElementAt(index);
+            listModel.removeElementAt(index);
+            listModel.insertElementAt(o, index+1);  
+        }
+    }
+
+    public void valueChanged(ListSelectionEvent e) {
+        if (e.getValueIsAdjusting()) {
+            return; // another event will be fired soon
+        }
+        selectionChanged(list.getSelectedIndex());
+    }
+
+    protected void selectionChanged(int index) { //index is -1 if there is no selection           
+        colorButton.setEnabled(index >= 0);
+        removeButton.setEnabled(index >= 0);
+        upButton.setEnabled(index > 0);
+        downButton.setEnabled(index >= 0 && index < listModel.getSize()-1);
+
+        if (index >= 0) {
+            FlagListItem item = (FlagListItem)listModel.elementAt(index);
+            colorButton.setColor(item.getColor());
+            list.setSelectedIndex(index);
+        } else {
+            colorButton.setColor(getBackground());
+        }
+    }
+
+    protected void changeColor() {
+        int selectedIndex = list.getSelectedIndex();
+        FlagListItem item = (FlagListItem)listModel.elementAt(selectedIndex);
+        Color c = JColorChooser.showDialog(this, "Choose color", item.getColor());
+
+        if (c != null) {
+            item.setColor(c);
+            colorButton.setColor(c);
+        }
+    }
+
+    class FlagListModel extends DefaultListModel {
+
+        public FlagListModel(String flagString) {
+            if (flagString != null) {
+                setFlagString(flagString);
+            }
+        }
+
+        public String getFlagString() {
+            StringBuffer sb = new StringBuffer();
+            Enumeration e = elements();
+            while (e.hasMoreElements()) {
+                FlagListItem item = (FlagListItem)e.nextElement();
+                sb.append(item.getFlagString());
+                Color c = item.getColor();
+                sb.append("(").append(c.getRed()).append(",").append(c.getGreen()).append(",").append(c.getBlue()).append(")");
+                if (e.hasMoreElements()) {
+                    sb.append(";");
+                }
+            }
+            return sb.toString();
+        }
+
+        public void setFlagString(String flagString) {
+            clear();
+            StringTokenizer st = new StringTokenizer(flagString, ";");
+            while (st.hasMoreTokens()) {
+                String s = st.nextToken();
+                String flag = s.split("\\(")[0];
+                Color color = FlagsSetting.toColor(s);
+                addElement(new FlagListItem(flag, color));
+            }
+        }
+
+    }
+
+    class FlagListItem {
+
+        Color color;
+        String flagString;
+
+        public FlagListItem(String flagString, Color color) {
+            this.flagString = flagString;
+            this.color = color;
+        }
+
+        public Color getColor() {
+            return color;
+        }
+
+        public String getFlagString() {
+            return flagString;
+        }
+
+        public void setColor(Color c) {
+            color = c;
+        }
+
+        @Override
+        public String toString() {
+            return flagString;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/preferences/FlagsSetting.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,85 @@
+package at.ssw.visualizer.cfg.preferences;
+
+import java.awt.Color;
+import java.io.Serializable;
+import java.util.Hashtable;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class FlagsSetting implements Serializable {
+
+    private Hashtable<String, Color> flag2color;
+    private Hashtable<String, Integer> priority;
+    private String flagString;
+
+
+    public FlagsSetting(String flagString) {
+        this.flagString = flagString;
+        flag2color = new Hashtable<>();
+        priority = new Hashtable<>();
+        String[] flags = flagString.split(";");
+
+        int z = 0;
+        for(String s : flags) {
+            String flag = s.split("\\(")[0];
+            Color c = toColor(s);
+            flag2color.put(flag, c);
+            priority.put(flag, z);
+            z++;
+        }
+    }
+
+    public Color getColor(List<String> strings) {
+        int minPriority = Integer.MAX_VALUE;
+        Color result = null;
+
+        for(String s : strings) {
+            Color curColor = flag2color.get(s);
+            if(curColor != null) {
+                int curPriority = priority.get(s);
+                if(curPriority < minPriority) {
+                    minPriority = curPriority;
+                    result = curColor;
+                }
+            }
+        }
+
+        return result;
+    }
+
+    public static Color toColor(String s) {
+        String sArr[] = s.split("\\(");
+        String Color = sArr[1].substring(0, sArr[1].length() - 1);
+        String ColorArr[] = Color.split(",");
+        int r = Integer.parseInt(ColorArr[0]);
+        int g = Integer.parseInt(ColorArr[1]);
+        int b = Integer.parseInt(ColorArr[2]);
+        return new Color(r, g, b);
+    }
+
+    public String getFlagString() {
+        return flagString;
+    }
+      
+    @Override
+    public boolean equals(Object o) {
+        if(o==null) 
+            return false;
+        return this.toString().equals(o.toString());
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 7;
+        hash = 19 * hash + (this.flagString != null ? this.flagString.hashCode() : 0);
+        return hash;
+    }
+
+    @Override
+    public String toString(){
+        return "FlagSetting[" + flagString + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/preferences/FontChooserDialog.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,37 @@
+package at.ssw.visualizer.cfg.preferences;
+
+import java.awt.Font;
+import java.beans.PropertyEditor;
+import java.beans.PropertyEditorManager;
+import org.openide.DialogDescriptor;
+import org.openide.DialogDisplayer;
+
+/**
+ *
+ * @author Bernhard Stiftner
+ */
+public class FontChooserDialog {
+
+    /*
+     * Displays a font selection dialog.
+     * @return The selected font, or the initial font if the user chose
+     * to bail out
+     */
+    public static Font show(Font initialFont) {
+        PropertyEditor pe = PropertyEditorManager.findEditor(Font.class);
+        if (pe == null) {
+            throw new RuntimeException("Could not find font editor component.");
+        }
+        pe.setValue(initialFont);
+        DialogDescriptor dd = new DialogDescriptor(
+                pe.getCustomEditor(),
+                "Choose Font");
+        DialogDisplayer.getDefault().createDialog(dd).setVisible(true);
+        if (dd.getValue() == DialogDescriptor.OK_OPTION) {
+            Font f = (Font)pe.getValue();
+            return f;
+        }
+        return initialFont;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/visual/BezierWidget.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,345 @@
+package at.ssw.visualizer.cfg.visual;
+
+import org.netbeans.api.visual.widget.ConnectionWidget;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.CubicCurve2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.util.List;
+import org.netbeans.api.visual.anchor.AnchorShape;
+import org.netbeans.api.visual.graph.GraphScene;
+import org.netbeans.api.visual.widget.Scene;
+import org.netbeans.api.visual.widget.Widget;
+
+
+/**
+ *  In comparison to the default ConnectionWidget this class is able to connect 
+ *  Widgets with a curve instead of a straight line sequence. Between two control
+ *  points a curve is painted as cubic bezier curve the control points are 
+ *  calculated automaticaly they depend on the position of the prior- and the 
+ *  following control points.
+ *  In conjunction with a suitable router the connection will be a straight line 
+ *  or a curve depending on the amount and the position of the controlpoints. 
+ *  Controlpoints supplied by the router, are treated as curve intersection points.
+ *  For Reflexive edges the router doesn`t  need to supply controlpoints, they 
+ *  get painted by this class automatically. If the router supplys more as 2 
+ *  control points for a recursive edge the edge gets painted with the default
+ *  curve approximation algorithm.
+ */
+public class BezierWidget extends ConnectionWidget {
+    private static final double BEZIER_SCALE = 0.3;     
+    private static final double ENDPOINT_DEVIATION = 3;//curve endpoint approximation accuracy
+   
+    private GraphScene scene=null;
+ 
+    public BezierWidget(Scene scene) {
+        super(scene);          
+    }
+    
+    public BezierWidget(GraphScene scene) {
+        super(scene);   
+        this.scene=scene;        
+    }
+ 
+    
+    private boolean isReflexive(){
+        return getSourceAnchor().getRelatedWidget() == getTargetAnchor().getRelatedWidget();
+    }
+    
+    
+    @Override
+    protected Rectangle calculateClientArea() {              
+        Rectangle bounds = null;
+        if(this.getControlPoints().size()>0){           
+            for(Point p : this.getControlPoints()){
+              if(bounds==null)
+                  bounds = new Rectangle(p);
+              else
+                  bounds.add(p);
+            }
+            bounds.grow(5,5);         
+        }    
+        if(isReflexive()){
+            Widget related = this.getTargetAnchor().getRelatedWidget();
+            bounds = related.convertLocalToScene(related.getBounds());
+            bounds.grow(10, 10);
+        }
+        if(bounds==null)
+            bounds = super.calculateClientArea();
+           
+        return bounds;
+    }
+    
+ 
+    
+    //returns prefered location for an edge -1 for left and 1 for right
+    private int edgeBalance(Widget nodeWidget) {   
+        if(scene == null)
+            return 1;
+        
+        Point nodeLocation = nodeWidget.getLocation();
+        int left = 0, right = 0;
+
+        Object node = scene.findObject(nodeWidget);
+    
+        for(Object e : scene.findNodeEdges(node, true, true)) {//inputedges
+            ConnectionWidget cw = (ConnectionWidget) scene.findWidget(e);
+            
+            if(cw != this) {                
+                Widget targetNodeWidget = cw.getTargetAnchor().getRelatedWidget();
+
+                Point location;
+                if(targetNodeWidget == nodeWidget) {
+                    Widget sourceNodeWidget = cw.getSourceAnchor().getRelatedWidget();
+                    location = sourceNodeWidget.getLocation();
+                } else {
+                    location = targetNodeWidget.getLocation();
+                }
+
+                if(location.x < nodeLocation.x)
+                    left++;
+                else 
+                    right++;
+            }
+        }    
+        if(left < right)
+            return -1;
+        else
+            return 1;
+    } 
+    
+    
+    
+    
+    /**
+     * if the edge is reflexive its painted as a cyclic edge
+     * if there are 2 controlpoints the connection is painted as a straight line from the source to the targetanchor
+     * if there are more as 2 controlpoints the connection path between 2 control points is painted as bezier curve
+     */
+       
+    @Override
+    protected void paintWidget () {  
+
+        List<Point> contrPoints = this.getControlPoints();
+        int listSize = contrPoints.size();
+                
+        Graphics2D gr = getGraphics ();
+        
+        if (listSize <= 2) {
+            if(isReflexive()) { //special case for reflexive connection widgets    
+                Widget related = this.getTargetAnchor().getRelatedWidget();
+                int position = this.edgeBalance(related);
+                Rectangle bounds = related.convertLocalToScene(related.getBounds());
+                gr.setColor (getLineColor()); 
+                Point first = new Point();
+                Point last = new Point();
+                double centerX = bounds.getCenterX();
+                first.x = (int) (centerX + bounds.width / 4);          
+                first.y = bounds.y + bounds.height;
+                last.x = first.x;
+                last.y = bounds.y;
+
+                gr.setStroke(this.getStroke());
+
+                double cutDistance = this.getTargetAnchorShape().getCutDistance();
+                double anchorAngle = Math.PI/-3.0;
+                double cutX = Math.abs(Math.cos(anchorAngle)*cutDistance); 
+                double cutY = Math.abs(Math.sin(anchorAngle)*cutDistance);
+                int ydiff=first.y-last.y; 
+                int endy = -ydiff;
+                double height=bounds.getHeight();
+                double cy = height/4.0;
+                double cx=bounds.getWidth()/5.0;
+                double dcx = cx*2;
+                GeneralPath gp = new GeneralPath();
+                gp.moveTo(0, 0);
+                gp.quadTo(0, cy, cx, cy);
+                gp.quadTo(dcx, cy, dcx, -height/2.0);
+                gp.quadTo(dcx, endy - cy, cy, -(cy+ydiff));
+                gp.quadTo(cutX*1.5, endy - cy, cutX, endy-cutY);   
+
+                AffineTransform af = new AffineTransform();           
+                AnchorShape anchorShape = this.getTargetAnchorShape();           
+
+                if(position < 0) {
+                    first.x = (int) (centerX - bounds.width / 4);        
+                    af.translate(first.x, first.y);
+                    af.scale(-1.0, 1.0);
+                    last.x = first.x;
+                } else {
+                    af.translate(first.x, first.y);
+                }
+                Shape s = gp.createTransformedShape(af);  
+                gr.draw(s);
+
+                if (last != null) {
+                    AffineTransform previousTransform = gr.getTransform ();
+                    gr.translate (last.x, last.y);  
+
+                    if(position < 0)
+                        gr.rotate(Math.PI - anchorAngle);
+                    else                  
+                        gr.rotate (anchorAngle);
+
+                    anchorShape.paint (gr, false);
+                    gr.setTransform (previousTransform);
+                }                                      
+                   
+            } else {
+                super.paintWidget();
+            }
+            return;
+        }
+           
+        //bezier curve... 
+        GeneralPath curvePath = new GeneralPath();
+        Point lastControlPoint = null;
+        double lastControlPointRotation = 0.0;
+       
+        Point prev = null;                 
+        for (int i = 0; i < listSize - 1; i++) {
+            Point cur = contrPoints.get(i);
+            Point next = contrPoints.get(i + 1);
+            Point nextnext = null;
+            if (i < listSize - 2) {
+                nextnext = contrPoints.get(i + 2);
+            }     
+            
+            double len = cur.distance(next);                
+            double scale = len * BEZIER_SCALE;     
+            Point bezierFrom = null;//first ControlPoint         
+            Point bezierTo = null;//second ControlPoint
+            
+            if (prev == null) {
+                //first point 
+                curvePath.moveTo(cur.x, cur.y);//startpoint
+                bezierFrom = cur;              
+            } else {            
+                bezierFrom = new Point(next.x - prev.x, next.y - prev.y);
+                bezierFrom = scaleVector(bezierFrom, scale);
+                bezierFrom.translate(cur.x, cur.y); 
+            }
+       
+            if (nextnext == null) {//next== last point (curve to)               
+                lastControlPoint=next;  
+                bezierTo = next;//set 2nd intermediate point to endpoint              
+                GeneralPath lastseg = this.subdivide(cur, bezierFrom, bezierTo, next);
+                if(lastseg != null)
+                    curvePath.append(lastseg, true);
+                break;                
+            } else {
+                bezierTo = new Point(cur.x - nextnext.x, cur.y - nextnext.y);
+                bezierTo = scaleVector(bezierTo, scale);
+                bezierTo.translate(next.x, next.y); 
+            }
+          
+            curvePath.curveTo(
+                    bezierFrom.x, bezierFrom.y,//controlPoint1
+                    bezierTo.x, bezierTo.y,//controlPoint2
+                    next.x,next.y
+            );        
+            prev = cur;
+        }
+        Point2D cur = curvePath.getCurrentPoint();
+        Point next = lastControlPoint;
+        
+        lastControlPointRotation = //anchor anchorAngle 
+            Math.atan2 (cur.getY() - next.y, cur.getX() - next.x);
+                         
+        Color previousColor = gr.getColor();
+        gr.setColor (getLineColor());    
+        Stroke s = this.getStroke();
+        gr.setStroke(s);
+        gr.setColor(this.getLineColor());
+        gr.draw(curvePath);
+                      
+        AffineTransform previousTransform = gr.getTransform ();    
+        gr.translate (lastControlPoint.x, lastControlPoint.y);       
+        gr.rotate (lastControlPointRotation);
+        AnchorShape targetAnchorShape = this.getTargetAnchorShape();           
+        targetAnchorShape.paint (gr, false);
+        gr.setTransform (previousTransform);
+       
+        //paint ControlPoints if enabled
+        if (isPaintControlPoints()) {
+            int last = listSize - 1;
+            for (int index = 0; index <= last; index ++) {
+                Point point = contrPoints.get (index);
+                previousTransform = gr.getTransform ();
+                gr.translate (point.x, point.y);
+                if (index == 0  ||  index == last)
+                    getEndPointShape().paint (gr);
+                else
+                    getControlPointShape().paint (gr);
+                gr.setTransform (previousTransform);
+            }
+           
+        }
+        gr.setColor(previousColor);
+    }
+    
+    
+    
+    private GeneralPath subdivide (Point b0, Point b1, Point b2, Point b3) {            
+        double cutDistance = getTargetAnchorShape().getCutDistance();
+        double minDistance = cutDistance - ENDPOINT_DEVIATION;
+        /**
+         * if the cutDistance is valid the last segment of the curve
+         * gets reduced by subdivision until the distance of the endpoint(epDistance) 
+         * satisfys the condition (cutDistance > epDistance > (cutDistance - ENDPOINT-DEVIATION)
+         */
+        if(cutDistance > minDistance && minDistance > 0 ) {
+            GeneralPath path = new GeneralPath(); 
+            
+            path.moveTo(b0.x, b0.y);
+            
+            CubicCurve2D.Double left = new CubicCurve2D.Double(
+                    b0.x, b0.y, 
+                    b1.x, b1.y,
+                    b2.x, b2.y, 
+                    b3.x, b3.y);
+            
+            CubicCurve2D right=new CubicCurve2D.Double();
+            left.subdivide(left, right);   
+            double distance = b3.distance(left.getP2());
+            //if the distance is bigger as the cutDistance the left segment is added
+            //and the right segment is divided again
+            while(distance>cutDistance){                    
+                path.append(left, true);
+                right.subdivide(left, right);
+                distance = b3.distance(left.getP2());
+                //if the devision removed to much the left segment is divided
+                while(distance < minDistance) {                            
+                    //changes the distance to ~ (distance+distance/2)
+                    left.subdivide(left, right);
+                    distance = b3.distance(left.getP2());
+                }
+            }                  
+            //append the last segment with (minDistance < distance < cutDistance)
+            //actually we should check if the a division happend, but this is very unlikly
+            path.append(left, true);         
+            return path;
+        }
+        return null;
+    }
+    
+  
+   
+    
+       
+    private static Point scaleVector(Point vector, double len) {
+        double scale = Math.sqrt(vector.x * vector.x + vector.y * vector.y);
+        if(scale==0.0) return vector;
+        scale = len / scale;          
+        return new Point(
+                Math.round(vector.x * (float)scale), 
+                Math.round(vector.y * (float)scale));
+    }
+     
+}    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/visual/PolylineRouter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,360 @@
+package at.ssw.visualizer.cfg.visual;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.geom.Line2D;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import org.netbeans.api.visual.anchor.Anchor;
+import org.netbeans.api.visual.router.Router;
+import org.netbeans.api.visual.widget.ConnectionWidget;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ * Router Class with Collision Detection
+ * 
+ *
+ * The returned path is a straight line there is no node widget between the source and the target node,
+ * if there are nodewidgets in between it tries to find a path around those abstacles to avoid collisions.
+ * The algorithm for the search of this path is limited by a fixed number of iterations defined in 
+ * NUMER_OF_ITERATIONS to return a result in reasonable time. If the calculation exceeds this limit the 
+ * path returned contains at least 1 collision with a nodewidget.  
+ */
+
+public class PolylineRouter implements Router {
+    private static final float FACTOR = 0.70f;
+    
+    private static final int HEXPAND = 3;
+    private static final int VEXPAND = 3;
+    private static final int NUMBER_OF_ITERATIONS = 8;   
+    
+    WidgetCollisionCollector collector;
+    
+     
+    public PolylineRouter(WidgetCollisionCollector collector){
+        this.collector=collector;
+    }
+   
+  
+    public List<Point> routeConnection(final ConnectionWidget widget) {       
+        if(!widget.isVisible()) return Collections.<Point>emptyList();
+   
+        Anchor sourceAnchor = widget.getSourceAnchor();
+        Anchor targetAnchor = widget.getTargetAnchor();
+         
+        if(sourceAnchor == null || targetAnchor == null) 
+            return null;
+        
+        Point start = sourceAnchor.compute(widget.getSourceAnchorEntry()).getAnchorSceneLocation();
+        Point end =   targetAnchor.compute(widget.getTargetAnchorEntry()).getAnchorSceneLocation();
+        
+        Widget sourceWidget = sourceAnchor.getRelatedWidget();
+        Widget targetWidget = targetAnchor.getRelatedWidget();  
+        
+        
+        if(sourceWidget == targetWidget){//reflexive edges doesnt need any path      
+            return Collections.<Point>emptyList();
+        }
+           
+        List<Widget> nodeWidgets = new ArrayList<>();
+        
+        if(collector != null){
+            collector.collectCollisions(nodeWidgets);    
+            //source and target widget are not treatet as obstacle
+            nodeWidgets.remove(sourceWidget);
+            nodeWidgets.remove(targetWidget);
+        }
+                            
+        List<Point> controlPoints = optimize(nodeWidgets, widget, start, end); 
+              
+        //size==2 => straight line
+        //size==3 => ensures a collision between cp0 and cp2 therefore its not possible to simplify it
+        if(controlPoints.size() > 3)
+            controlPoints = simplify(nodeWidgets, controlPoints);
+        
+        return controlPoints;        
+    }   
+    
+    
+    private List<Point> simplify(Collection<Widget> nodeWidgets, List<Point> list) {        
+        List<Point> result = new ArrayList<>();
+        result.add( list.get(0) );//add startpoint
+        for (int i = 1; i < list.size(); i++) {
+            Point prev = list.get(i - 1);
+            for (int j = i; j < list.size(); j++) {
+                Point cur = list.get(j);
+                if (!intersects(nodeWidgets, prev, cur)) {
+                    i = j;
+                }               
+            }
+            result.add(list.get(i));
+        }      
+        return result;
+    }
+    
+    /**
+     * Computates the Anchorposition like the Rectangular anchor for a
+     * given widget as source/target and a controlpoint as opposit anchorposition
+     */
+     
+    private Point computateAnchorPosition(Widget relatedWidget, Point controlPoint) {
+        Rectangle bounds = relatedWidget.getBounds();
+        Point relatedLocation = relatedWidget.getLocation();//center of the widget
+       
+        if (bounds.isEmpty ()  || relatedLocation.equals (controlPoint))
+            return relatedLocation;
+
+        float dx = controlPoint.x - relatedLocation.x;
+        float dy = controlPoint.y - relatedLocation.y;
+
+        float ddx = Math.abs (dx) / (float) bounds.width;
+        float ddy = Math.abs (dy) / (float) bounds.height;
+
+        float scale = 0.5f / Math.max (ddx, ddy);
+
+        Point point = new Point (Math.round (relatedLocation.x + scale * dx), 
+                Math.round (relatedLocation.y + scale * dy));
+        return point;
+    }
+    
+   
+  
+    private List<Point> optimize(Collection<Widget> nodeWidgets, ConnectionWidget connWidget, Point start, Point end) {
+        
+        List<Point> list = new ArrayList<>();
+        list.add(start);
+        list.add(end);
+                           
+        boolean progress = true;
+        
+        for (int j = 0; progress && j < NUMBER_OF_ITERATIONS ; j++) {
+            progress = false;                  
+            List<Point> newList = new ArrayList<>();              
+            for (int i = 0; i < list.size() - 1 ; i++) {
+                Point cur = list.get(i);
+                Point next = list.get(i + 1);
+                newList.add(cur);
+                List<Point> intermediate = optimizeLine(nodeWidgets, cur, next);
+                if (intermediate != null && intermediate.size() > 0) { 
+                    progress = true;
+                    newList.addAll(intermediate);//insert new controlpoints between cur and next
+                } 
+            }            
+            newList.add(list.get(list.size()-1));//add endpoint of the polyline
+            list = newList;   
+            
+        }
+               
+        if(list.size() > 2) {          
+            Widget sourceNode = connWidget.getSourceAnchor().getRelatedWidget();
+            Widget targetNode = connWidget.getTargetAnchor().getRelatedWidget();
+            Rectangle sourceBounds = sourceNode.convertLocalToScene(sourceNode.getBounds());
+            Rectangle targetBounds = targetNode.convertLocalToScene(targetNode.getBounds());
+            sourceBounds.grow(HEXPAND, VEXPAND);
+            
+            /**
+             * add only points which are not intersecting the source and the target 
+             * widget bounds caused by invalid bad anchor positions. The first 
+             * and the last point is ignored cause the anchor is recalculated 
+             * anyway.
+             */
+            ArrayList<Point> tmp = new ArrayList<>();
+            int listSize=list.size();
+            tmp.add(list.get(0));
+            int i=0;
+            while(++i < listSize-1) {
+                Point p = list.get(i);
+                if(!sourceBounds.contains(p) || !targetBounds.contains(p))
+                    tmp.add(p);               
+            }
+           
+            tmp.add(list.get(i));
+            if(tmp.size() < 3)
+                return tmp;
+            
+            list=tmp;                    
+            //calculate a proper anchor position using the second/penultimate controlpoint for start/end
+            start = this.computateAnchorPosition(connWidget.getSourceAnchor().getRelatedWidget(), list.get(1));            
+            end = this.computateAnchorPosition(connWidget.getTargetAnchor().getRelatedWidget(), list.get(list.size()-2));            
+            list.set(0,start);           
+            list.set(list.size()-1, end);         
+        }          
+        return list;
+    }
+ 
+    
+    /**
+     *  trys to optimize a line from p1 to p2 to avoid collisions with node widgets
+     *  returns null if the line doesn`t intersect with any nodewidget
+     *  or a list with immediate points between p1 and p2 to avoid collisions
+     */
+    private List<Point> optimizeLine(Collection<Widget> nodeWidgets, Point p1, Point p2) {        
+        Line2D line = new Line2D.Double(p1, p2);
+                     
+        for(Widget w : nodeWidgets ) {            
+            if( w.isVisible() ) {                              
+                Rectangle r = w.convertLocalToScene(w.getBounds());             
+                r.grow(HEXPAND, VEXPAND);
+       
+                if (!line.intersects(r)) continue;
+                  
+                Point location = w.getLocation();                
+                int distx = (int) (r.width * FACTOR);
+                int disty = (int) (r.height * FACTOR);
+                
+                int minIntersects = Integer.MAX_VALUE;
+                int min = Integer.MAX_VALUE;
+                List<Point> minSol = null;
+                for (int i = -1; i <= 1; i++) {
+                    for (int j = -1; j <= 1; j++) {
+                        if (i != 0 || j != 0) {                           
+                            Point cur = new Point(location.x + i * distx, location.y + j * disty);
+                            List<Point> list1 = new ArrayList<>();
+                            list1.add(p1);
+                            list1.add(cur);
+                            list1.add(p2);                                                 
+                            int crossProd = Math.abs(crossProduct(p1, cur, p2));
+                            if (!intersects(w, list1)) {
+                                Line2D line1 = new Line2D.Float(p1, cur);
+                                Line2D line2 = new Line2D.Float(p2, cur);
+                                int curIntersects = this.countNodeIntersections(nodeWidgets, line1, line2);
+                                
+                                if (curIntersects < minIntersects
+                                        || (curIntersects == minIntersects && crossProd < min)) {
+                                    minIntersects = curIntersects;
+                                    min = crossProd;
+                                    minSol = new ArrayList<>();
+                                    minSol.add(cur);
+                                }
+                            }
+
+                            if (i == 0 || j == 0) {
+                                Point cur1, cur2;
+                                if (i == 0) {
+                                      cur1 = new Point(location.x + distx/2, location.y + j * disty);
+                                      cur2 = new Point(location.x - distx/2, location.y + j * disty);
+                                } else { // (j == 0) 
+                                    cur1 = new Point(location.x + i * distx, location.y + disty/2);
+                                    cur2 = new Point(location.x + i * distx, location.y - disty/2);
+                                }
+
+                                Point vec1 = new Point(p1.x - cur1.x, p1.y - cur1.y);
+                                int offset1 = vec1.x * vec1.x + vec1.y * vec1.y;
+
+                                Point vec2 = new Point(p1.x - cur2.x, p1.y - cur2.y);
+                                int offset2 = vec2.x * vec2.x + vec2.y * vec2.y;
+
+                                if (offset2 < offset1) {
+                                    Point tmp = cur1;
+                                    cur1 = cur2;
+                                    cur2 = tmp;
+                                }
+
+                                List<Point> list2 = new ArrayList<>();
+                                list2.add(p1);
+                                list2.add(cur1);
+                                list2.add(cur2);
+                                list2.add(p2);
+
+                                int cross1 = crossProduct(p1, cur1, cur2);
+                                int cross2 = crossProduct(cur1, cur2, p2);
+
+                                if (cross1 > 0) {
+                                    cross1 = 1;
+                                } else if (cross1 < 0) {
+                                    cross1 = -1;
+                                }
+                                
+                                if (cross2 > 0) {
+                                    cross2 = 1;
+                                } else if (cross2 < 0) {
+                                    cross2 = -1;
+                                }
+                                if ((cross1 == cross2 || cross1 == 0 || cross2 == 0) && !intersects(w, list2)) {                                 
+                                    Line2D line1 = new Line2D.Float(p1, cur1);
+                                    Line2D line2 = new Line2D.Float(cur1, cur2);
+                                    Line2D line3 = new Line2D.Float(p2, cur2);
+                                    int curIntersects = this.countNodeIntersections(nodeWidgets, line1, line2, line3);
+                                   
+                                    // This is a bit better
+                                    crossProd--;
+
+                                    if (curIntersects < minIntersects
+                                            || (curIntersects == minIntersects && crossProd < min)) {
+                                        minIntersects = curIntersects;
+                                        min = crossProd;
+                                        minSol = new ArrayList<>();
+                                        minSol.add(cur1);
+                                        minSol.add(cur2);                                       
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }           
+                if (minSol != null) {      
+                    return minSol;
+                } 
+            }
+        }
+        return null;
+    }
+    
+    
+   
+    private int countNodeIntersections(Collection<Widget> nodeWidgets, Line2D... lines){
+        int count=0;     
+        for(Widget nw : nodeWidgets){
+            if(nw.isVisible()) {
+                Rectangle bounds = nw.convertLocalToScene(nw.getBounds());
+                for( Line2D line : lines){
+                    if(line.intersects(bounds))
+                        count++;
+                }
+            }
+        }
+        return count;
+    }
+    
+    
+    private boolean intersects(Collection<Widget> nodeWidgets, Point start, Point end) {
+        List<Point> pointlist = new ArrayList<>();
+        pointlist.add(start);
+        pointlist.add(end);
+
+        for(Widget w : nodeWidgets){
+            if(w.isVisible() && intersects(w, pointlist)) {
+                return true;
+            }
+        }
+        return false;
+    }
+        
+    
+    private boolean intersects(Widget w, List<Point> list) {
+        Rectangle r = w.convertLocalToScene(w.getBounds());
+        r.grow(HEXPAND, VEXPAND);
+        return intersects(list, r);
+    }
+    
+    
+    private boolean intersects(List<Point> list, Rectangle rect){
+        for(int i=1; i < list.size(); i++) {
+            Point cur = list.get(i-1);
+            Point next = list.get(i);   
+            if(rect.intersectsLine(cur.x, cur.y, next.x, next.y))
+                return true;
+        }
+        return false;
+    }
+
+    
+    private int crossProduct(Point p1, Point p2, Point p3) {
+        Point off1 = new Point(p1.x - p2.x, p1.y - p2.y);
+        Point off2 = new Point(p3.x - p2.x, p3.y - p2.y);
+        return (off1.x * off2.y - off1.y * off2.x);
+    }
+        
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/visual/PolylineRouterV2.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,393 @@
+package at.ssw.visualizer.cfg.visual;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.geom.Line2D;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.netbeans.api.visual.anchor.Anchor;
+import org.netbeans.api.visual.router.Router;
+import org.netbeans.api.visual.widget.ConnectionWidget;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ * Router Class with Collision Detection
+ * 
+ *
+ * The returned path is a straight line there is no node widget between the source and the target node,
+ * if there are nodewidgets in between it tries to find a path around those abstacles to avoid collisions.
+ * The algorithm for the search of this path is limited by a fixed number of iterations defined in 
+ * NUMER_OF_ITERATIONS to return a result in reasonable time. If the calculation exceeds this limit the 
+ * path returned contains at least 1 collision with a nodewidget. 
+ * 
+ * This class intend to solve the same problem as the class PolyLineRouter but
+ * uses slightly different methods.
+ * + uses another algorithm for solving the collision.
+ * + the obstacle bounds are calulated in advance to avoid a recalculation.
+ * - there is no heuristic, the shortest path around the widget is choosen asap.
+ * 
+ * 
+ *  
+ */
+
+public class PolylineRouterV2 implements Router {    
+    private static final int HEXPAND = 3;
+    private static final int VEXPAND = 3;
+    private static final int NUMBER_OF_ITERATIONS = 8;   
+    
+    WidgetCollisionCollector collector;
+    
+     
+    public PolylineRouterV2(WidgetCollisionCollector collector){
+        this.collector=collector;
+    }
+   
+   
+    public List<Point> routeConnection(final ConnectionWidget widget) {       
+        if(!widget.isVisible()) return Collections.<Point>emptyList();
+   
+        Anchor sourceAnchor = widget.getSourceAnchor();
+        Anchor targetAnchor = widget.getTargetAnchor();
+         
+        if(sourceAnchor == null || targetAnchor == null) 
+            return null;
+        
+        Point start = sourceAnchor.compute(widget.getSourceAnchorEntry()).getAnchorSceneLocation();
+        Point end =   targetAnchor.compute(widget.getTargetAnchorEntry()).getAnchorSceneLocation();
+
+        Widget sourceWidget = sourceAnchor.getRelatedWidget();
+        Widget targetWidget = targetAnchor.getRelatedWidget(); 
+        
+               
+        if(sourceWidget == targetWidget){//reflexive edges doesnt need any path      
+            return Collections.<Point>emptyList();
+        }
+        
+        
+        Point srcCenter = this.getSceneLocation(sourceWidget);
+        Point tarCenter = this.getSceneLocation(targetWidget);
+        
+        List<Widget> widgetObstacles = new ArrayList<>();
+        
+        if(collector != null){
+            collector.collectCollisions(widgetObstacles);                    
+        }
+        
+        List<Rectangle> obstacles = new ArrayList<>(widgetObstacles.size());
+        this.collectObstacles(obstacles, widgetObstacles, widget);
+       
+                    
+        List<Point> controlPoints = optimize(obstacles, srcCenter, tarCenter);     
+//        size==2 => straight line
+//        size==3 => ensures a collision between cp0 and cp2 therefore its not possible to simplify it
+        if(controlPoints.size() > 3){
+            Point rstart = this.computateAnchorPosition(sourceWidget, controlPoints.get(1));            
+            Point rend  = this.computateAnchorPosition(targetWidget, controlPoints.get(controlPoints.size()-2)); 
+            controlPoints.set(0, rstart);           
+            controlPoints.set(controlPoints.size()-1, rend);       
+            controlPoints = simplify(obstacles, controlPoints);
+        } else if (controlPoints.size()>=2){
+                //use old points
+            controlPoints.set(0, start);           
+            controlPoints.set(controlPoints.size()-1, end);           
+        
+        }
+        return controlPoints;        
+    }  
+    
+    
+    private int collectObstacles(List<Rectangle> colrects, List<Widget> colwidgets , ConnectionWidget cw){        
+        int count=0;                        
+        Anchor sourceAnchor = cw.getSourceAnchor();
+        Anchor targetAnchor = cw.getTargetAnchor();
+        Widget sourceWidget = sourceAnchor.getRelatedWidget();
+        Widget targetWidget = targetAnchor.getRelatedWidget(); 
+        Point start = sourceAnchor.compute(cw.getSourceAnchorEntry()).getAnchorSceneLocation();
+        Point end =   targetAnchor.compute(cw.getTargetAnchorEntry()).getAnchorSceneLocation();
+                        
+        for(Widget w : colwidgets){
+            
+            if(w==sourceWidget || w == targetWidget) continue;
+           
+            Rectangle r = w.convertLocalToScene(w.getBounds());
+            r.grow(HEXPAND, VEXPAND);
+            if(r.intersectsLine(start.x,start.y,end.x,end.y))
+                count++;
+            colrects.add(r);
+        }
+        return count;
+    }
+    
+    
+    private Point center (Rectangle bounds) {
+        return new Point (bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
+    }
+
+    /**
+     * Returns the scene location of a related widget.
+     * bounds might be null if the widget was not added to the scene
+     * @return the scene location; null if no related widget is assigned
+     */
+    public Point getSceneLocation (Widget relatedWidget) {
+        if (relatedWidget != null) {
+            Rectangle bounds = relatedWidget.getBounds ();
+            if(bounds != null)
+                return center(relatedWidget.convertLocalToScene(bounds));           
+        }
+        return null;
+    }
+       
+    /**
+     * Computates the Anchorposition like the Rectangular anchor for a
+     * given widget as source/target and a controlpoint as opposit anchorposition
+     */
+     
+    private Point computateAnchorPosition(Widget relatedWidget, Point controlPoint) {
+        Rectangle bounds = relatedWidget.getBounds();
+        
+        //todo: fix, center of widget must be cacluated trough the bounds 
+        //since there are some wheird widgets where the location is not the center of the widget
+        Point relatedLocation = relatedWidget.getLocation();//center of the widget
+       
+        if (bounds.isEmpty ()  || relatedLocation.equals (controlPoint))
+            return relatedLocation;
+
+        float dx = controlPoint.x - relatedLocation.x;
+        float dy = controlPoint.y - relatedLocation.y;
+
+        float ddx = Math.abs (dx) / (float) bounds.width;
+        float ddy = Math.abs (dy) / (float) bounds.height;
+
+        float scale = 0.5f / Math.max (ddx, ddy);
+
+        Point point = new Point (Math.round (relatedLocation.x + scale * dx), 
+                Math.round (relatedLocation.y + scale * dy));
+        return point;
+    }
+    
+    private List<Point> simplify(List<Rectangle> obstacles, List<Point> list) {        
+        List<Point> result = new ArrayList<>(list.size());
+        result.add( list.get(0) );//add startpoint
+        for (int i = 1; i < list.size(); i++) {
+            Point prev = list.get(i - 1);
+            for (int j = i; j < list.size(); j++) {
+                Point cur = list.get(j);
+                if (!intersects(obstacles, prev, cur)) {
+                    i = j;
+                }               
+            }
+            result.add(list.get(i));
+        }      
+        return result;
+    }
+  
+    private List<Point> optimize(List<Rectangle> nodeWidgets, Point start, Point end) {
+        
+        List<Point> list = new ArrayList<>();
+        list.add(start);
+        list.add(end);
+                           
+        boolean progress = true;
+        
+        for (int j = 0; progress && j < NUMBER_OF_ITERATIONS ; j++) {
+            progress = false;                  
+            List<Point> newList = new ArrayList<>();      
+            for (int i = 0; i < list.size() - 1 ; i++) {
+                Point cur = list.get(i);
+                Point next = list.get(i + 1);
+                newList.add(cur);               
+                List<Point> intermediate = optimizeLine(nodeWidgets, cur, next);
+                if (intermediate != null && intermediate.size() > 0) { 
+                    progress = true;                  
+                    newList.addAll(intermediate);//insert new controlpoints between cur and next
+                } 
+            }           
+            newList.add(list.get(list.size()-1));//add endpoint of the polyline
+            list = newList;   
+            
+        }
+        
+        return list;
+    }
+ 
+  
+    /**
+     *  trys to optimize a line from p1 to p2 to avoid collisions with rectangles
+     *  returns null if the line doesn`t intersect with any nodewidget or
+     *  if the obstacles are overlapping
+     *  ----------------------------------------------------------------------
+     *  if the collision is solved it returns a list with immediate points 
+     *  between p1 and p2. The points are taken from hull points of and grown 
+     *  rectangle.
+     */
+    private List<Point> optimizeLine(List<Rectangle> obstacles, Point p1, Point p2) {        
+        Line2D line = new Line2D.Double(p1, p2);
+        boolean inbounds=false;
+        Rectangle ibr=null;
+        ArrayList<Point> sol = new ArrayList<>();
+        boolean leftIntersection;
+        boolean rightIntersection; 
+        boolean bottomIntersection; 
+        boolean topIntersection; 
+        Point interLeft=new Point();
+        Point interRight=new Point();
+        Point interBot=new Point();
+        Point interTop=new Point();
+        
+    
+        
+        for(Rectangle r : obstacles ) {                      
+            if (!line.intersects(r)) continue;
+            
+            int w=r.width+2;
+            int h=r.height+2;
+            Point topLeft = r.getLocation();
+            topLeft.x-=1;
+            topLeft.y-=1;
+            Point topRight = new Point(topLeft.x+w, topLeft.y);
+            Point bottomLeft = new Point(topLeft.x, topLeft.y+h);
+            Point bottomRight = new Point(topRight.x, bottomLeft.y);  
+            leftIntersection = findIntersectionPoint(p1, p2, topLeft, bottomLeft, interLeft);
+            rightIntersection = findIntersectionPoint(p1, p2, topRight, bottomRight, interRight);
+            bottomIntersection = findIntersectionPoint(p1, p2, bottomLeft, bottomRight, interBot);
+            topIntersection = findIntersectionPoint(p1, p2, topLeft, topRight, interTop);
+            
+            //Intersection points are not used yet. This could be actually a 
+            //good approach to avoid additional collisions because it would be
+            //still the same vector.
+
+            if(leftIntersection) {                      
+                if(topIntersection) {//left and top   
+                    sol.add(topLeft);                       
+                }                        
+                else if(bottomIntersection){//left and bottom
+                    sol.add(bottomLeft);                                   
+                }
+                else if(rightIntersection){//left and right
+                    double disttl = topLeft.distance(p1);
+                    double distbl = bottomLeft.distance(p1);
+                    if(disttl > distbl){
+                        //pass at the bottom
+                        double distbr = bottomRight.distance(p1);
+                        if(distbl < distbr){
+                            //from the left to the right
+                            sol.add(bottomLeft);
+                            sol.add(bottomRight);
+                        } else {
+                            //from the right to the left
+                            sol.add(bottomRight);
+                            sol.add(bottomLeft);
+                        }
+                    } else {
+                        //pass at the top
+                        double disttr = topRight.distance(p1);
+                        if(disttl < disttr){
+                            //from the left to the right
+                            sol.add(topLeft);
+                            sol.add(topRight);
+                        } else {
+                            //from the right to the left
+                            sol.add(topRight);
+                            sol.add(topLeft);
+                        }
+                    }                        
+                 } else {//only left => inside bounds 
+                    inbounds=true;                                  
+                 } 
+            } else if (rightIntersection) {                
+                if(topIntersection) {//right and top
+                    sol.add(topRight);
+                }
+                else if(bottomIntersection){//right and bottom
+                    sol.add(bottomRight);
+                } else { //only right => inside the bounds
+                    inbounds=true;                             
+                }                  
+            } else if (topIntersection && bottomIntersection) {//top and bottom
+                double disttop = interTop.distance(p1);
+                double distbot = interBot.distance(p1);
+                if(disttop < distbot ){
+                    //from the top to the bottom
+                    double distleft = interTop.distance(topLeft);
+                    double distright = interTop.distance(topRight);
+                    if(distleft < distright){
+                        //pass left
+                        sol.add(topLeft);
+                        sol.add(bottomLeft);
+                    } else {
+                        //pass right
+                        sol.add(topRight);
+                        sol.add(bottomRight);
+                    }   
+                } else {
+                    //from the bottom to the top
+                    double distleft = interBot.distance(bottomLeft);
+                    double distright = interBot.distance(bottomRight);
+                    if(distleft < distright){
+                        //pass left
+                        sol.add(bottomLeft);
+                        sol.add(topLeft);
+                    } else {
+                        //pass right
+                        sol.add(bottomRight);
+                        sol.add(topRight);
+                    }   
+                } 
+            } else {//only bottom or only top
+                inbounds=true;                 
+            } /* ENDIF */
+            
+            //breakpoint <-- collision detected
+            
+            if(sol.size()>0) {//solution found
+                assert(!inbounds);
+                return sol;
+            } else { //no solution found=> inbounds
+                assert(inbounds);
+                assert(sol.size()==0);
+                //handle collision or just skip it and search for the next collisionj               
+                ibr=r;
+                //jump out of the loop to able to interate over the obstacles
+                break;
+            } 
+        }/* end foreach obstacle */
+        
+        if(inbounds || ibr != null){
+            assert(inbounds);
+            assert(ibr!=null);        
+        }       
+        return null;//no collison found
+    }/* end optimizeLine */
+    
+ 
+  
+    //check intersection between line p0->p1 for a given set of obstacles
+    private static boolean intersects(List<Rectangle> obstacles, Point p0, Point p1) {
+        for(Rectangle r : obstacles){
+            if(r.intersectsLine(p0.x, p0.y, p1.x, p1.y))
+                return true;         
+        }
+        return false;
+    }
+    
+   
+    private boolean findIntersectionPoint(
+            Point p0, Point p1, Point p2, Point p3, Point pI) {
+        float q = (p0.y - p2.y)*(p3.x - p2.x) - (p0.x - p2.x)*(p3.y - p2.y);
+        float d = (p1.x - p0.x)*(p3.y - p2.y) - (p1.y - p0.y)*(p3.x - p2.x);
+        
+        //parallel ?
+        if(d==0) return false;
+          
+        float r = q / d;
+        q = (p0.y - p2.y)*(p1.x - p0.x) - (p0.x - p2.x)*(p1.y - p0.y);
+        
+        float s = q / d;
+        if(r<0 || r>1 || s<0 || s>1) return false;
+        
+        pI.x = p0.x + (int) (0.5f + r * (p1.x - p0.x));
+        pI.y = p0.y + (int) (0.5f + r * (p1.y - p0.y));
+        return true;
+    }    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/visual/SplineConnectionWidget.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,541 @@
+package at.ssw.visualizer.cfg.visual;
+
+import org.netbeans.api.visual.widget.ConnectionWidget;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.CubicCurve2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.List;
+import org.netbeans.api.visual.anchor.AnchorShape;
+import org.netbeans.api.visual.graph.GraphScene;
+import org.netbeans.api.visual.widget.Scene;
+import org.netbeans.api.visual.widget.Widget;
+
+
+/**
+ *  In comparison to the default ConnectionWidget this class is able to connect 
+ *  widgets with a curve instead of a straight line sequence. 
+ *  In conjunction with a suitable router the connection will be a straight line 
+ *  or a curve depending on the amount and the position of the controlpoints. 
+ *  Controlpoints supplied by the router, are treated as curve intersection points.
+ *  For Reflexive edges the router doesn`t necessarily need to supply 
+ *  any controlpoints, they get painted by this automatically, this can be 
+ *  excepted if the router supplys more as 2 control points for a self edge,
+ *  then the edge gets painted with the default curve interpolation algorithm.
+ *  The method used for drawing curves uses a piecewise cubic interpolation 
+ *  algorithm. Between two control points a curve is painted as cubic bezier 
+ *  curve the, inner bezier points are calculated automatically with FMILL 
+ *  tangents and a chord parametrization, this interpolant is also known as
+ *  cutmull-rom spline. The resulting spline fullfills c^1 continuity.
+ *  The the end points the interpolation algorithm uses the bessel end condition.
+ */
+
+public class SplineConnectionWidget extends ConnectionWidget {     
+   private static final double ENDPOINT_DEVIATION = 3;//curve endpoint approximation accuracy
+   private static final double HIT_DISTANCE_SQUARE = 4.0;//distance for intersection test
+    private GraphScene scene=null;
+    private Point2D [] bezierPoints = null;
+ 
+    public SplineConnectionWidget(Scene scene) {
+        super(scene);   
+        if(scene instanceof GraphScene)
+            this.scene=(GraphScene) scene;
+    }
+    
+    //check for self - edge
+    private boolean isReflexive(){
+        return getSourceAnchor().getRelatedWidget() == getTargetAnchor().getRelatedWidget();
+    }
+    
+    
+    @Override
+    protected Rectangle calculateClientArea() {              
+        
+        Rectangle bounds = null;
+
+        if(this.getControlPoints().size()>2){
+            bezierPoints = createBezierPoints(getControlPoints());
+        }
+        //minmax method - returns the smallest bounding rectangle  
+        //Curves and surfaces for CAGD (3rd ed.), p.54  
+        //exact calculation of the bounding min rect
+        if(bezierPoints != null) {
+            Rectangle2D bounds2D = null;
+            for (int i = 0; i < bezierPoints.length; i++) {
+                Point2D point = bezierPoints[i];
+                if(bounds2D==null)
+                    bounds2D = new Rectangle2D.Double(point.getX(),point.getY(),0,0);
+                else
+                    bounds2D.add(point);
+            }
+            bounds = bounds2D.getBounds();
+            bounds.grow(2, 2);
+            
+        } else if (getControlPoints().size()>0){
+            for(Point p : this.getControlPoints()){
+              if(bounds==null)
+                  bounds = new Rectangle(p);
+              else
+                  bounds.add(p);
+            }
+            bounds.grow(5,5);     
+            
+        } else if (isReflexive()) {
+            Widget related = this.getTargetAnchor().getRelatedWidget();
+            bounds = related.convertLocalToScene(related.getBounds());
+            bounds.grow(10, 10);
+        }
+        
+        if(bounds==null)
+            bounds = super.calculateClientArea();
+
+        return bounds;
+    }
+ 
+    
+    /**
+     * if the edge is reflexive its painted as a cyclic self edge, if there 
+     * are two controlpoints the connection is painted as a straight line from 
+     * the source to the targetanchor, if there are more as 2 controlpoints the 
+     * connection path between two control points is painted as cutmull rom 
+     * spline with bessel end tangents.
+     */
+    @Override
+    protected void paintWidget () {       
+        List<Point> contrPoints = this.getControlPoints();
+        int listSize = contrPoints.size();
+  
+        Graphics2D gr = getGraphics ();
+        
+        if (listSize <= 2) {
+            this.bezierPoints=null;//set bezier Points null for calulateClientArea()
+            if(isReflexive()) { //special case for reflexive connection widgets    
+                this.drawReflexive(gr);
+            } else {
+                super.paintWidget();
+            }         
+            return;
+        }
+      
+        //bezier curve... listSize > 2
+        GeneralPath curvePath = new GeneralPath();      
+        double lastControlPointRotation = 0.0;
+        
+        
+        Point2D [] bezPoints  = this.createBezierPoints(contrPoints);
+        curvePath.moveTo(bezPoints[0].getX(), bezPoints[0].getY());//b00
+        
+        //last segment is added by subdivision thats why its -5
+        for (int i = 1; i < bezPoints.length-5; i+=3) {          
+            curvePath.curveTo(
+                    bezPoints[i].getX(), bezPoints[i].getY(),//b1i
+                    bezPoints[i+1].getX(), bezPoints[i+1].getY(),//b2i
+                    bezPoints[i+2].getX(), bezPoints[i+2].getY());//b3i   
+           
+        }        
+   
+        GeneralPath lastseg = subdivide2D(
+                bezPoints[bezPoints.length-4], 
+                bezPoints[bezPoints.length-3],
+                bezPoints[bezPoints.length-2],
+                bezPoints[bezPoints.length-1]);
+        
+
+        if(lastseg != null)
+            curvePath.append(lastseg, true);
+                    
+        Point2D cur = curvePath.getCurrentPoint();
+        Point lastControlPoint = contrPoints.get(listSize-1);
+        
+        lastControlPointRotation = //anchor anchorAngle 
+            Math.atan2 (cur.getY() - lastControlPoint.y, cur.getX() - lastControlPoint.x);
+  
+        gr.setStroke(getStroke());
+        gr.setColor(getLineColor());
+        gr.draw(curvePath);
+   
+                      
+        AffineTransform previousTransform = gr.getTransform ();    
+        gr.translate (lastControlPoint.x, lastControlPoint.y);       
+        gr.rotate (lastControlPointRotation);
+        AnchorShape targetAnchorShape = this.getTargetAnchorShape();           
+        targetAnchorShape.paint (gr, false);
+        gr.setTransform (previousTransform);
+       
+        //paint ControlPoints if enabled
+        if (isPaintControlPoints()) {
+            int last = listSize - 1;
+            for (int index = 0; index <= last; index ++) {
+                Point point = contrPoints.get (index);
+                previousTransform = gr.getTransform ();
+                gr.translate (point.x, point.y);
+                if (index == 0  ||  index == last)
+                    getEndPointShape().paint (gr);
+                else
+                    getControlPointShape().paint (gr);
+                gr.setTransform (previousTransform);
+            }
+           
+        }   
+    }
+    
+    private void drawReflexive(Graphics2D gr){
+        Widget related = this.getTargetAnchor().getRelatedWidget();
+        int position = this.edgeBalance(related);
+        Rectangle bounds = related.convertLocalToScene(related.getBounds());
+        gr.setColor (getLineColor()); 
+        Point first = new Point();
+        Point last = new Point();
+        double centerX = bounds.getCenterX();
+        first.x = (int) (centerX + bounds.width / 4);          
+        first.y = bounds.y + bounds.height;
+        last.x = first.x;
+        last.y = bounds.y;
+
+        gr.setStroke(this.getStroke());
+
+        double cutDistance = this.getTargetAnchorShape().getCutDistance();
+        double anchorAngle = Math.PI/-3.0;
+        double cutX = Math.abs(Math.cos(anchorAngle)*cutDistance); 
+        double cutY = Math.abs(Math.sin(anchorAngle)*cutDistance);
+        int ydiff=first.y-last.y; 
+        int endy = -ydiff;
+        double height=bounds.getHeight();
+        double cy = height/4.0;
+        double cx=bounds.getWidth()/5.0;
+        double dcx = cx*2;
+        GeneralPath gp = new GeneralPath();
+        gp.moveTo(0, 0);
+        gp.quadTo(0, cy, cx, cy);
+        gp.quadTo(dcx, cy, dcx, -height/2.0);
+        gp.quadTo(dcx, endy - cy, cy, -(cy+ydiff));
+        gp.quadTo(cutX*1.5, endy - cy, cutX, endy-cutY);   
+
+        AffineTransform af = new AffineTransform();           
+        AnchorShape anchorShape = this.getTargetAnchorShape();           
+
+        if(position < 0) {
+            first.x = (int) (centerX - bounds.width / 4);        
+            af.translate(first.x, first.y);
+            af.scale(-1.0, 1.0);
+            last.x = first.x;
+        } else {
+            af.translate(first.x, first.y);
+        }
+        Shape s = gp.createTransformedShape(af);  
+        gr.draw(s);
+
+        if (last != null) {
+            AffineTransform previousTransform = gr.getTransform ();
+            gr.translate (last.x, last.y);  
+
+            if(position < 0)
+                gr.rotate(Math.PI - anchorAngle);
+            else                  
+                gr.rotate (anchorAngle);
+
+            anchorShape.paint (gr, false);
+            gr.setTransform (previousTransform);
+        }                                      
+    }
+     
+    //returns prefered location for an edge -1 for left and 1 for right
+    private int edgeBalance(Widget nodeWidget) {   
+        if(scene == null)
+            return 1;
+        
+        Point nodeLocation = nodeWidget.getLocation();
+        int left = 0, right = 0;
+
+        Object node = scene.findObject(nodeWidget);
+    
+        for(Object e : scene.findNodeEdges(node, true, true)) {//inputedges
+            ConnectionWidget cw = (ConnectionWidget) scene.findWidget(e);
+            
+            if(cw != this) {                
+                Widget targetNodeWidget = cw.getTargetAnchor().getRelatedWidget();
+
+                Point location;
+                if(targetNodeWidget == nodeWidget) {
+                    Widget sourceNodeWidget = cw.getSourceAnchor().getRelatedWidget();
+                    location = sourceNodeWidget.getLocation();
+                } else {
+                    location = targetNodeWidget.getLocation();
+                }
+
+                if(location.x < nodeLocation.x)
+                    left++;
+                else 
+                    right++;
+            }
+        }    
+        if(left < right)
+            return -1;
+        else
+            return 1;
+    } 
+    
+    
+     private Point2D[] createBezierPoints(List<Point> list){
+        if(list.size()<3) return null ;
+        
+        
+        int lastIdx = list.size()-1;
+        
+
+        //chord length parametrization
+        double[] uis = new double[list.size()];
+        uis[0]=0;
+        uis[1] = list.get(1).distance(list.get(0));
+        for (int i = 1; i < uis.length; i++) {
+            Point cur = list.get(i);
+            Point prev = list.get(i-1);     
+            uis[i]=uis[i-1]+ cur.distance(prev);          
+        }
+          
+            
+        for (int i = 1; i < uis.length; i++) {
+            uis[i] /= uis[lastIdx];
+            
+        }
+        double[] delta = new double[uis.length-1];     
+        for (int i = 0; i < delta.length; i++) {
+            double ui = uis[i];
+            double uin = uis[i+1];
+            delta[i] = uin-ui;
+        }
+       
+        
+        //FMILL tangent directions (chord length) 
+        Point2D[] tangents  = new Point2D[list.size()];
+ 
+        for (int i = 1; i < list.size()-1; i++) {
+            Point xBefore = list.get(i-1);
+            Point xAfter = list.get(i+1);
+            Point2D.Double tangent = new Point2D.Double (xAfter.x - xBefore.x, xAfter.y - xBefore.y);          
+            tangents[i] = tangent;
+        }
+        
+        
+        Point2D [] bezPoints = new Point2D[(list.size()-1)*2+list.size()];
+        //Catmull-Rom
+        for (int i = 1; i < list.size()-1; i++) {                
+            Point b3i = list.get(i);
+            Point2D b3ib = b3iBefore(b3i, delta[i-1], delta[i], tangents[i]);
+            Point2D b3ia = b3iAfter(b3i, delta[i-1], delta[i], tangents[i]);
+            bezPoints[3*i] = b3i;
+            bezPoints[3*i-1] = b3ib;
+            bezPoints[3*i+1] = b3ia;
+        }             
+        bezPoints[0] = list.get(0);
+        bezPoints[bezPoints.length-1] = list.get(list.size()-1);
+
+        Point p0 = list.get(0);
+        Point p1 = list.get(1);
+        Point p2 = list.get(2);
+        Point pL_2 = list.get(lastIdx-2);
+        Point pL_1 = list.get(lastIdx-1);
+        Point pL = list.get(lastIdx);
+       
+        Point2D m1 = besselTangent(delta[0], delta[1], p0, p1, p2);
+        Point2D m0 = besselEndTangent(p0, p1, delta[0], m1);
+        
+        Point2D mLb = besselTangent(delta[delta.length-2], delta[delta.length-1],
+                pL_2,pL_1, pL);
+        Point2D mL = besselEndTangent(pL_1, pL, delta[delta.length-1], mLb);
+        
+        Point2D scaleM0 = scale(normalize(m0), p0.distance(p1));//increase distx/distxl to make curve rounder at the end
+        Point2D scaleML = scale(normalize(mL), pL.distance(pL_1));
+         //Catmull-Rom for bessel points 
+        Point2D b30a = b3iAfter(p0, delta[0], delta[0],scaleM0);
+        Point2D b33b = b3iBefore(pL, delta[delta.length-1], delta[delta.length-1],scaleML);
+         
+        bezPoints[1] = b30a;
+        bezPoints[bezPoints.length-2] = b33b;
+
+        return bezPoints;
+    }
+    
+     
+
+    private static Point2D besselTangent(double delta_ib, double delta_i, Point2D p0, Point2D p1 , Point2D p2){
+        double alpha_i = delta_ib/(delta_ib+delta_i);
+        
+        double x = (1-alpha_i)/delta_ib * (p1.getX() - p0.getX())
+                + alpha_i/delta_i * (p2.getX()-p1.getX());
+        double y = (1-alpha_i)/delta_ib * (p1.getY() - p0.getY())
+                + alpha_i/delta_i * (p2.getY()-p1.getY());
+       
+        return new Point2D.Double(x,y);
+    }
+    
+    private static Point2D besselEndTangent(Point2D p0, Point2D p1, double delta_u, Point2D m){
+        double x = 2*((p1.getX()-p0.getX())/delta_u) - m.getX();
+        double y = 2*((p1.getY()-p0.getY())/delta_u) - m.getY();
+        return new Point2D.Double(x,y);
+    }
+    
+    private static Point2D b3iBefore(Point2D b3i, double delta_ib, double delta_i, Point2D li){    
+        double x = b3i.getX() - (delta_ib/(3*(delta_ib+delta_i)))*li.getX();
+        double y = b3i.getY() - (delta_ib/(3*(delta_ib+delta_i)))*li.getY();   
+        return new Point.Double(x,y);      
+    }
+    
+    private static Point2D b3iAfter(Point2D b3i, double delta_ib,double delta_i,Point2D li){
+        double x = b3i.getX() + (delta_i/(3*(delta_ib+delta_i)))*li.getX();
+        double y = b3i.getY() + (delta_i/(3*(delta_ib+delta_i)))*li.getY();
+        return new Point.Double(x,y);      
+    }
+    
+    
+    
+    
+    //returns length of vector v
+    private static double norm(Point2D v){
+        return Math.sqrt(v.getX()*v.getX()+v.getY()*v.getY());
+    }
+     
+    //returns unity vector of vector v
+    private static Point2D normalize(Point2D v){
+        double norm = norm(v);
+        if(norm==0) return new Point2D.Double(v.getX(), v.getY());
+        return new Point2D.Double(v.getX()/norm , v.getY()/norm);
+    }
+    
+    //scale vector to size of length
+    private static Point2D scale(Point2D v, double length){
+        Point2D tmp = normalize(v);
+        return new Point2D.Double(tmp.getX()*length, tmp.getY()*length);
+    }
+    
+
+    
+    private GeneralPath subdivide2D (Point2D b0, Point2D b1, Point2D b2, Point2D b3) {
+        //set 2nd intermediate point to endpoint
+        //we could actually use another "better" point if we like to have a smoother curve
+      
+        double cutDistance = getTargetAnchorShape().getCutDistance();
+        double minDistance = cutDistance - ENDPOINT_DEVIATION;
+        /**
+         * if the cutDistance is valid the last segment of the curve
+         * gets reduced by subdivision until the distance of the endpoint(epDistance) 
+         * satisfys the condition (cutDistance > epDistance > (cutDistance - ENDPOINT-DEVIATION)
+         */
+        if(cutDistance > minDistance && minDistance > 0 ) {
+            GeneralPath path = new GeneralPath(); 
+            
+            path.moveTo(b0.getX(), b0.getY());
+            
+            CubicCurve2D.Double curve = new CubicCurve2D.Double(
+                    b0.getX(), b0.getY(), 
+                    b1.getX(), b1.getY(),
+                    b2.getX(), b2.getY(), 
+                    b3.getX(), b3.getY());
+            
+            
+           
+            CubicCurve2D right=new CubicCurve2D.Double();
+            CubicCurve2D left=new CubicCurve2D.Double();
+            curve.subdivide(left, right);   
+            double distance = b3.distance(left.getP2());
+            //if the distance is bigger as the cutDistance the left segment is added
+            //and the right segment is divided again
+            while(distance>cutDistance){                    
+                path.append(left, true);             
+                right.subdivide(left, right);
+                distance = b3.distance(left.getP2());
+                //if the devision removed to much the left segment is divided
+                while(distance < minDistance) {                            
+                    //changes the distance to ~ (distance+distance/2)
+                    left.subdivide(left, right);
+                    distance = b3.distance(left.getP2());
+                }
+            }                  
+            //append the last segment with (minDistance < distance < cutDistance)
+            path.append(left, true);         
+            return path;
+        }
+        return null;
+    }
+    
+ 
+    /**
+     * Returns whether a specified local point pL is a part of the connection 
+     * widget. 
+     * First it make a rough bounds check
+     * for Line Segments => use Super call (ConnectionWidget.isHitAt(pL)). 
+     * for self-edges => its sufficent to return getBounds.contains(pL).
+     * for Splines => Interate over all Partitial segments of the curve and make 
+     * a minmax check with the bezier points. If pL is inside the minmax 
+     * rectangle of one segment the curve is constructed and subdivided until 
+     * the distance d between center point pC (of the bounding rectangle) 
+     * and pL is below HIT_DISTANCE_SQUARE, in this case it returns true.
+     * If no no minmax check was successful or the subdivision lead to an 
+     * rectangle witch doesn`t contain pL return false. 
+     * @param localLocation the local location
+     * @return true, if the location is a part of the connection widget
+     */
+    @Override
+    public boolean isHitAt(Point localLocation) {     
+        if(!isVisible()  || !getBounds ().contains (localLocation))
+            return false;
+          
+        List<Point> controlPoints = getControlPoints ();
+        if(controlPoints.size() <=2){
+            if(isReflexive()) return true;
+            return super.isHitAt(localLocation);
+        }    
+        
+        if(bezierPoints != null) {         
+            for (int i = 0; i < bezierPoints.length-1; i+=3) {          
+                 Point2D b0 =   bezierPoints[i];
+                 Point2D b1 =   bezierPoints[i+1];
+                 Point2D b2 =   bezierPoints[i+2];
+                 Point2D b3 =   bezierPoints[i+3];
+                 
+                 CubicCurve2D left = new CubicCurve2D.Double(
+                    b0.getX(), b0.getY(), 
+                    b1.getX(), b1.getY(),
+                    b2.getX(), b2.getY(), 
+                    b3.getX(), b3.getY());
+                 
+                 
+                 Rectangle2D bounds = left.getBounds2D();
+                 while(bounds.contains(localLocation)) {                                                     
+                    //calculate the center and use HIT_DISTANCE_SQUARE for a range check  
+                    Point2D test = new Point2D.Double(bounds.getCenterX(),bounds.getCenterY());
+                    if(test.distance(localLocation) < HIT_DISTANCE_SQUARE){                        
+                        return true;
+                    }
+
+                   
+                    CubicCurve2D  right = new CubicCurve2D.Double();                    
+                    left.subdivide(left, right);
+                    Rectangle2D lb2d = left.getBounds2D();
+                    Rectangle2D rb2d = right.getBounds2D();                    
+                    if( lb2d.contains(localLocation)){      
+                        bounds = lb2d;
+                    } else if (rb2d.contains(localLocation)) {                        
+                        left = right;
+                        bounds = rb2d;
+                    } else {                       
+                        return false;
+                    }
+                    
+                 }//end while               
+            }//end for              
+        }       
+        return false;      
+    }   
+  
+ 
+}
+
+
+
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/ControlFlowEditor/src/at/ssw/visualizer/cfg/visual/WidgetCollisionCollector.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,12 @@
+package at.ssw.visualizer.cfg.visual;
+
+import java.util.List;
+import org.netbeans.api.visual.widget.Widget;
+
+
+public interface WidgetCollisionCollector {
+    
+    //returns a list of widgets which should be handled as obstacles
+    void collectCollisions(List<Widget> collisions);
+      
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.data" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.data.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.data
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/data/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.data-impl" basedir="..">
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+        <condition>
+            <not>
+                <available file="${harness.dir}" type="dir"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=a403efd8
+build.xml.script.CRC32=b87f73ba
+build.xml.stylesheet.CRC32=79c3b980
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=a403efd8
+nbproject/build-impl.xml.script.CRC32=cc649146
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/nbproject/platform.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.javahelp,\
+    org.netbeans.modules.masterfs,\
+    org.netbeans.modules.options.keymap,\
+    org.netbeans.modules.sendopts,\
+    org.netbeans.modules.templates,\
+    org.openide.compat,\
+    org.openide.execution,\
+    org.openide.util.enumerations
+enabled.clusters=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
+src.dir=src
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+test.src.dir=test
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+            <suite-component/>
+            <module-dependencies/>
+            <test-dependencies>
+                <test-type>
+                    <name>unit</name>
+                    <test-dependency>
+                        <code-name-base>org.netbeans.libs.junit4</code-name-base>
+                        <compile-dependency/>
+                    </test-dependency>
+                    <test-dependency>
+                        <code-name-base>org.openide.util</code-name-base>
+                        <compile-dependency/>
+                    </test-dependency>
+                </test-type>
+            </test-dependencies>
+            <public-packages>
+                <package>at.ssw.visualizer.model.bc</package>
+                <package>at.ssw.visualizer.model.cfg</package>
+                <package>at.ssw.visualizer.model.interval</package>
+                <package>at.ssw.visualizer.model.nc</package>
+                <package>com.sun.hotspot.igv.data</package>
+                <package>com.sun.hotspot.igv.data.serialization</package>
+                <package>com.sun.hotspot.igv.data.services</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/model/bc/Bytecodes.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,33 @@
+package at.ssw.visualizer.model.bc;
+
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+
+/**
+ * This class holds the bytecode of a method and provides severel methods
+ * accessing the details.
+ *
+ * @author Alexander Reder
+ * @author Christian Wimmer
+ */
+public interface Bytecodes {
+    /**
+     * Back-link to the control flow graph where the bytecodes were loaded from.
+     */
+    public ControlFlowGraph getControlFlowGraph();
+
+    /**
+     * Called before the first call of getBytecodes() or getEpilogue(). Can be called multiple times.
+     */
+    public void parseBytecodes();
+    
+    /**
+     * The bytecodes of the method in the given bytecode range.
+     *
+     * @param   fromBCI starting BCI (including this bci)
+     * @param   toBCI   ending BCI (not including this bci)
+     * @return          string representation of the bytecodes
+     */
+    public String getBytecodes(int fromBCI, int toBCI);
+    
+    public String getEpilogue();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/model/cfg/BasicBlock.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,41 @@
+package at.ssw.visualizer.model.cfg;
+
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface BasicBlock {
+    public String getName();
+
+    public int getFromBci();
+
+    public int getToBci();
+
+    public List<? extends BasicBlock> getPredecessors();
+
+    public List<? extends BasicBlock> getSuccessors();
+
+    public List<? extends BasicBlock> getXhandlers();
+
+    public List<String> getFlags();
+
+    public BasicBlock getDominator();
+
+    public int getLoopIndex();
+
+    public int getLoopDepth();
+
+    public boolean hasState();
+
+    public List<State> getStates();
+
+    public boolean hasHir();
+
+    public List<IRInstruction> getHirInstructions();
+
+    public boolean hasLir();
+
+    public List<IRInstruction> getLirOperations();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/model/cfg/ControlFlowGraph.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,26 @@
+package at.ssw.visualizer.model.cfg;
+
+import at.ssw.visualizer.model.bc.Bytecodes;
+import at.ssw.visualizer.model.nc.NativeMethod;
+import com.sun.hotspot.igv.data.FolderElement;
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface ControlFlowGraph extends FolderElement {
+    public List<BasicBlock> getBasicBlocks();
+
+    public BasicBlock getBasicBlockByName(String name);
+
+    public Bytecodes getBytecodes();
+
+    public NativeMethod getNativeMethod();
+
+    public boolean hasState();
+
+    public boolean hasHir();
+
+    public boolean hasLir();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/model/cfg/IRInstruction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,19 @@
+package at.ssw.visualizer.model.cfg;
+
+import java.util.Collection;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface IRInstruction {
+    public static String HIR_NAME = "tid";
+    public static String HIR_TEXT = "instruction";
+    public static String HIR_OPERAND = "result";
+
+    public static String LIR_NUMBER = "nr";
+    public static String LIR_TEXT = "instruction";
+
+    public Collection<String> getNames();
+    public String getValue(String name);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/model/cfg/State.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,17 @@
+package at.ssw.visualizer.model.cfg;
+
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface State {
+    public String getKind();
+
+    public int getSize();
+
+    public String getMethod();
+
+    public List<StateEntry> getEntries();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/model/cfg/StateEntry.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,19 @@
+package at.ssw.visualizer.model.cfg;
+
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface StateEntry {
+    public int getIndex();
+
+    public String getName();
+
+    public boolean hasPhiOperands();
+
+    public List<String> getPhiOperands();
+
+    public String getOperand();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/model/interval/ChildInterval.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,29 @@
+package at.ssw.visualizer.model.interval;
+
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface ChildInterval {
+    public Interval getParent();
+
+    public String getRegNum();
+
+    public String getType();
+
+    public String getOperand();
+
+    public String getSpillState();
+
+    public ChildInterval getRegisterHint();
+
+    public List<Range> getRanges();
+
+    public List<UsePosition> getUsePositions();
+
+    public int getFrom();
+
+    public int getTo();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/model/interval/Interval.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,19 @@
+package at.ssw.visualizer.model.interval;
+
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface Interval {
+    public IntervalList getParent();
+
+    public List<ChildInterval> getChildren();
+
+    public String getRegNum();
+
+    public int getFrom();
+
+    public int getTo();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/model/interval/IntervalList.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,16 @@
+package at.ssw.visualizer.model.interval;
+
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface IntervalList {
+    public List<Interval> getIntervals();
+
+    public ControlFlowGraph getControlFlowGraph();
+
+    public int getNumLIROperations();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/model/interval/Range.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,11 @@
+package at.ssw.visualizer.model.interval;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface Range {
+    public int getFrom();
+
+    public int getTo();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/model/interval/UsePosition.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,11 @@
+package at.ssw.visualizer.model.interval;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface UsePosition {
+    public char getKind();
+
+    public int getPosition();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/model/nc/NativeMethod.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,15 @@
+package at.ssw.visualizer.model.nc;
+
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+
+/**
+ *
+ * @author Alexander Reder
+ */
+public interface NativeMethod {
+
+    public ControlFlowGraph getControlFlowGraph();
+    
+    public String getMethodText();
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/modelimpl/bc/BytecodesImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,166 @@
+package at.ssw.visualizer.modelimpl.bc;
+
+import at.ssw.visualizer.model.bc.Bytecodes;
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.modelimpl.cfg.BasicBlockImpl;
+import java.util.Arrays;
+
+/**
+ * This class holds the bytecode of a method and provides severel methods
+ * accessing the details.
+ *
+ * @author Christian Wimmer
+ */
+public class BytecodesImpl implements Bytecodes {
+    private ControlFlowGraph controlFlowGraph;
+    private String bytecodeString;
+
+    private String[] bytecodes;
+    private String epilogue;
+    
+
+    public BytecodesImpl(ControlFlowGraph controlFlowGraph, String bytecodeString) {
+        this.controlFlowGraph = controlFlowGraph;
+        this.bytecodeString = bytecodeString;
+    }
+    
+    public void parseBytecodes() {
+        String[] lines = bytecodeString.split("\n");
+
+        boolean inPrologue = true;
+        String[] result = new String[lines.length * 3];
+        int lastBci = -1;
+        int lnr = 0; 
+        for (; lnr < lines.length; lnr++) {
+            String line = lines[lnr];
+
+            line = line.trim();
+            if (line.startsWith("[")) {
+                int end = line.indexOf(']');
+                if (end != -1) {
+                    line = line.substring(end + 1, line.length());
+                }
+            }
+            
+            line = line.trim();
+            int space1 = line.indexOf(' ');
+            if (space1 <= 0) {
+                if (inPrologue) {
+                    continue;
+                } else {
+                    break;
+                }
+            }
+            String bciStr = line.substring(0, space1);
+            if (bciStr.endsWith(":")) {
+                bciStr = bciStr.substring(0, bciStr.length() - 1);
+            }
+
+            int bci;
+            try {
+                bci = Integer.parseInt(bciStr);
+            } catch (NumberFormatException ex) {
+                // Ignore invalid lines.
+                if (inPrologue) {
+                    continue;
+                } else {
+                    break;
+                }
+            }
+
+            String opcode = line.substring(space1 + 1);
+            String params = "";
+            int space2 = opcode.indexOf(' ');
+            if (space2 > 0) {
+                params = opcode.substring(space2 + 1).trim();
+                opcode = opcode.substring(0, space2);
+            }
+            String tail = "";
+            int space3 = params.indexOf('|');
+            if (space3 >= 0) {
+                tail = params.substring(space3);
+                params = params.substring(0, space3);
+            }
+
+//            if (!"ldc".equals(opcode) || !params.startsWith("\"")) {
+//                // Separate packages with "." instead of "/"
+//                params = params.replace('/', '.');
+//            }
+            
+            String printLine = bciStr + ":" + "    ".substring(Math.min(bciStr.length(), 3)) +
+                    opcode + "              ".substring(Math.min(opcode.length(), 13)) +
+                    params + "        ".substring(Math.min(params.length(), 8)) +
+                    tail;
+
+            
+            if (bci >= result.length) {
+                result = Arrays.copyOf(result, Math.max(bci + 1, result.length * 2));
+            }
+            result[bci] = printLine;
+            inPrologue = false;
+            lastBci = Math.max(lastBci, bci);
+        }
+
+        StringBuilder epilogueBuilder = new StringBuilder();
+        for (; lnr < lines.length; lnr++) {
+            epilogueBuilder.append(lines[lnr]).append("\n");
+        }
+        epilogue = epilogueBuilder.toString();
+        bytecodes = Arrays.copyOf(result, lastBci + 1);
+    
+        
+        BasicBlockImpl[] blocks = new BasicBlockImpl[bytecodes.length];
+        for (BasicBlock b : controlFlowGraph.getBasicBlocks()) {
+            if (b instanceof BasicBlockImpl) {
+                BasicBlockImpl block = (BasicBlockImpl) b;
+                if (block.getToBci() != -1) {
+                    // Do not override existing values.
+                    return;
+                }
+                if (block.getFromBci() >= 0 && block.getFromBci() < blocks.length) {
+                    blocks[block.getFromBci()] = block;
+                }
+            }
+        }
+        
+        int curToBci = -1;
+        for (int i = blocks.length - 1; i >= 0; i--) {
+            if (bytecodes[i] != null && curToBci == -1) {
+                curToBci = i;
+            }
+            if (blocks[i] != null) {
+                blocks[i].setToBci(curToBci);
+                curToBci = -1;
+            }
+        }
+    }
+    
+    public ControlFlowGraph getControlFlowGraph() {
+        return controlFlowGraph;
+    }
+
+    public String getBytecodes(int fromBCI, int toBCI) {
+        if (fromBCI < 0) {
+            return "";
+        }
+        toBCI = Math.min(toBCI, bytecodes.length);
+        StringBuilder sb = new StringBuilder();
+        for (int i = fromBCI; i < toBCI; i++) {
+            if (bytecodes[i] != null) {
+                sb.append(bytecodes[i]).append("\n");
+            }
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public String getEpilogue() {
+        return epilogue;
+    }
+
+    @Override
+    public String toString() {
+        return "Bytecodes " + getControlFlowGraph().getName();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/modelimpl/cfg/BasicBlockImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,143 @@
+package at.ssw.visualizer.modelimpl.cfg;
+
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.model.cfg.IRInstruction;
+import at.ssw.visualizer.model.cfg.State;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class BasicBlockImpl implements BasicBlock {
+
+    private ControlFlowGraph parent;
+    private String name;
+    private int fromBci;
+    private int toBci;
+    private BasicBlock[] predecessors;
+    private BasicBlock[] successors;
+    private BasicBlock[] xhandlers;
+    private String[] flags;
+    private BasicBlock dominator;
+    private int loopIndex;
+    private int loopDepth;
+    private int firstLirId;
+    private int lastLirId;
+    private State[] states;
+    private IRInstruction[] hirInstructions;
+    private IRInstruction[] lirOperations;
+
+    public void setValues(String name, int fromBci, int toBci, BasicBlock[] predecessors, BasicBlock[] successors, BasicBlock[] xhandlers, String[] flags, BasicBlock dominator, int loopIndex, int loopDepth, int firstLirId, int lastLirId, State[] states, IRInstruction[] hirInstructions, IRInstruction[] lirOperations) {
+        this.name = name;
+        this.fromBci = fromBci;
+        this.toBci = toBci;
+
+        this.predecessors = predecessors;
+        this.successors = successors;
+        this.xhandlers = xhandlers;
+
+        this.flags = flags;
+        this.dominator = dominator;
+        this.loopIndex = loopIndex;
+        this.loopDepth = loopDepth;
+        this.firstLirId = firstLirId;
+        this.lastLirId = lastLirId;
+
+        this.states = states;
+        this.hirInstructions = hirInstructions;
+        this.lirOperations = lirOperations;
+    }
+
+    public ControlFlowGraph getParent() {
+        return parent;
+    }
+
+    protected void setParent(ControlFlowGraph parent) {
+        this.parent = parent;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public int getFromBci() {
+        return fromBci;
+    }
+
+    public int getToBci() {
+        return toBci;
+    }
+
+    public void setToBci(int toBci) {
+        this.toBci = toBci;
+    }
+
+    public List<BasicBlock> getPredecessors() {
+        return Collections.unmodifiableList(Arrays.asList(predecessors));
+    }
+
+    public List<BasicBlock> getSuccessors() {
+        return Collections.unmodifiableList(Arrays.asList(successors));
+    }
+
+    public List<BasicBlock> getXhandlers() {
+        return Collections.unmodifiableList(Arrays.asList(xhandlers));
+    }
+
+    public List<String> getFlags() {
+        return Collections.unmodifiableList(Arrays.asList(flags));
+    }
+
+    public BasicBlock getDominator() {
+        return dominator;
+    }
+
+    public int getLoopIndex() {
+        return loopIndex;
+    }
+
+    public int getLoopDepth() {
+        return loopDepth;
+    }
+
+    public int getFirstLirId() {
+        return firstLirId;
+    }
+
+    public int getLastLirId() {
+        return lastLirId;
+    }
+
+    public boolean hasState() {
+        return states != null;
+    }
+
+    public List<State> getStates() {
+        return Collections.unmodifiableList(Arrays.asList(states));
+    }
+
+    public boolean hasHir() {
+        return hirInstructions != null;
+    }
+
+    public List<IRInstruction> getHirInstructions() {
+        return Collections.unmodifiableList(Arrays.asList(hirInstructions));
+    }
+
+    public boolean hasLir() {
+        return lirOperations != null;
+    }
+
+    public List<IRInstruction> getLirOperations() {
+        return Collections.unmodifiableList(Arrays.asList(lirOperations));
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/modelimpl/cfg/IRInstructionImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,40 @@
+package at.ssw.visualizer.modelimpl.cfg;
+
+import at.ssw.visualizer.model.cfg.IRInstruction;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+
+public class IRInstructionImpl implements IRInstruction {
+    private LinkedHashMap<String, String> data;
+
+    public IRInstructionImpl(LinkedHashMap<String, String> data) {
+        this.data = data;
+    }
+
+    public IRInstructionImpl(String pinned, int bci, int useCount, String name, String text, String operand) {
+        data = new LinkedHashMap<String, String>();
+        data.put("p", pinned);
+        data.put("bci", Integer.toString(bci));
+        data.put("use", Integer.toString(useCount));
+        data.put(HIR_NAME, name);
+        if (operand != null) {
+            data.put(HIR_OPERAND, operand);
+        }
+        data.put(HIR_TEXT, text);
+    }
+
+    public IRInstructionImpl(int number, String text) {
+        data = new LinkedHashMap<String, String>();
+        data.put(LIR_NUMBER, Integer.toString(number));
+        data.put(LIR_TEXT, text);
+    }
+
+    public Collection<String> getNames() {
+        return Collections.unmodifiableSet(data.keySet());
+    }
+
+    public String getValue(String name) {
+        return data.get(name);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/modelimpl/cfg/StateEntryImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,44 @@
+package at.ssw.visualizer.modelimpl.cfg;
+
+import at.ssw.visualizer.model.cfg.StateEntry;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class StateEntryImpl implements StateEntry {
+    private int index;
+    private String name;
+    private String[] phiOperands;
+    private String operand;
+
+    public StateEntryImpl(int index, String name, String[] phiOperands, String operand) {
+        this.index = index;
+        this.name = name;
+        this.phiOperands = phiOperands;
+        this.operand = operand;
+    }
+
+    public int getIndex() {
+        return index;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public boolean hasPhiOperands() {
+        return phiOperands != null;
+    }
+
+    public List<String> getPhiOperands() {
+        return Collections.unmodifiableList(Arrays.asList(phiOperands));
+    }
+
+    public String getOperand() {
+        return operand;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/modelimpl/cfg/StateImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,41 @@
+package at.ssw.visualizer.modelimpl.cfg;
+
+import at.ssw.visualizer.model.cfg.State;
+import at.ssw.visualizer.model.cfg.StateEntry;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class StateImpl implements State {
+    private String kind;
+    private int size;
+    private String method;
+    private StateEntry[] entries;
+
+    public StateImpl(String kind, int size, String method, StateEntryImpl[] entries) {
+        this.kind = kind;
+        this.size = size;
+        this.method = method;
+        this.entries = entries;
+    }
+
+    public String getKind() {
+        return kind;
+    }
+
+    public int getSize() {
+        return size;
+    }
+
+    public String getMethod() {
+        return method;
+    }
+
+    public List<StateEntry> getEntries() {
+        return Collections.unmodifiableList(Arrays.asList(entries));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/modelimpl/interval/ChildIntervalImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,118 @@
+package at.ssw.visualizer.modelimpl.interval;
+
+import at.ssw.visualizer.model.interval.ChildInterval;
+import at.ssw.visualizer.model.interval.Interval;
+import at.ssw.visualizer.model.interval.Range;
+import at.ssw.visualizer.model.interval.UsePosition;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class ChildIntervalImpl implements ChildInterval, Comparable<ChildIntervalImpl> {
+    private Interval parent;
+    private String regNum;
+    private String type;
+    private String operand;
+    private String spillState;
+    private ChildInterval registerHint;
+    private Range[] ranges;
+    private UsePosition[] usePositions;
+
+    public void setValues(String regNum, String type, String operand, String spillState, ChildInterval registerHint, Range[] ranges, UsePosition[] usePositions) {
+        this.regNum = regNum;
+        this.type = type;
+        this.operand = operand;
+        this.spillState = spillState;
+        this.registerHint = registerHint;
+        this.ranges = ranges;
+        this.usePositions = usePositions;
+    }
+    
+    public Interval getParent() {
+        return parent;
+    }
+
+    protected void setParent(IntervalImpl parent) {
+        this.parent = parent;
+    }
+
+    public String getRegNum() {
+        return regNum;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public String getOperand() {
+        return operand;
+    }
+
+    public String getSpillState() {
+        return spillState;
+    }
+
+    public ChildInterval getRegisterHint() {
+        return registerHint;
+    }
+
+    public List<Range> getRanges() {
+        return Collections.unmodifiableList(Arrays.asList(ranges));
+    }
+
+    public List<UsePosition> getUsePositions() {
+        return Collections.unmodifiableList(Arrays.asList(usePositions));
+    }
+
+
+    public int getFrom() {
+        return ranges[0].getFrom();
+    }
+
+    public int getTo() {
+        return ranges[ranges.length - 1].getTo();
+    }
+
+
+    public int compareTo(ChildIntervalImpl other) {
+        return getFrom() - other.getFrom();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder result = new StringBuilder();
+        result.append(regNum);
+        result.append(": ");
+        result.append(getType());
+        result.append(", ");
+        result.append(getOperand());
+        result.append(", ");
+        if (registerHint != null) {
+            result.append(registerHint.getRegNum());
+        } else {
+            result.append("null");
+        }
+
+        result.append("  ");
+        for (int i = 0; i < ranges.length; i++) {
+            if (i > 0) {
+                result.append(", ");
+            }
+            result.append(ranges[i]);
+        }
+
+        result.append("  ");
+        for (int i = 0; i < usePositions.length; i++) {
+            if (i > 0) {
+                result.append(", ");
+            }
+            result.append(usePositions[i]);
+        }
+
+        return result.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/modelimpl/interval/IntervalImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+package at.ssw.visualizer.modelimpl.interval;
+
+import at.ssw.visualizer.model.interval.ChildInterval;
+import at.ssw.visualizer.model.interval.Interval;
+import at.ssw.visualizer.model.interval.IntervalList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class IntervalImpl implements Interval {
+    private IntervalList parent;
+    private ChildInterval[] children;
+
+    public IntervalImpl(ChildIntervalImpl[] children) {
+        this.children = children;
+        for (ChildIntervalImpl child : children) {
+            child.setParent(this);
+        }
+    }
+
+    public IntervalList getParent() {
+        return parent;
+    }
+
+    protected void setParent(IntervalListImpl parent) {
+        this.parent = parent;
+    }
+
+    public List<ChildInterval> getChildren() {
+        return Collections.unmodifiableList(Arrays.asList(children));
+    }
+
+    public String getRegNum() {
+        return children[0].getRegNum();
+    }
+
+    public int getFrom() {
+        return children[0].getFrom();
+    }
+
+    public int getTo() {
+        return children[children.length - 1].getTo();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder result = new StringBuilder();
+        for (int i = 0; i < children.length; i++) {
+            if (i > 0) {
+                result.append("\n  ");
+            }
+            result.append(children[i]);
+        }
+        return result.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/modelimpl/interval/IntervalListImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+package at.ssw.visualizer.modelimpl.interval;
+
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.model.interval.Interval;
+import at.ssw.visualizer.model.interval.IntervalList;
+import com.sun.hotspot.igv.data.AbstractFolderElement;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class IntervalListImpl extends AbstractFolderElement implements IntervalList {
+    private Interval[] intervals;
+    private ControlFlowGraph controlFlowGraph;
+    private int numLIROperations;
+
+    public IntervalListImpl(String shortName, String name, IntervalImpl[] intervals, ControlFlowGraph controlFlowGraph) {
+        super(shortName, name);
+        this.intervals = intervals;
+        this.controlFlowGraph = controlFlowGraph;
+
+        for (IntervalImpl interval : intervals) {
+            interval.setParent(this);
+            numLIROperations = Math.max(numLIROperations, interval.getTo());
+        }
+//        for (BasicBlock basicBlock : controlFlowGraph.getBasicBlocks()) {
+//            numLIROperations = Math.max(numLIROperations, basicBlock.getLastLirId() + 2);
+//        }
+        // TODO(tw): Add number of LIR operations to output.
+    }
+
+
+    public List<Interval> getIntervals() {
+        return Collections.unmodifiableList(Arrays.asList(intervals));
+    }
+
+    public ControlFlowGraph getControlFlowGraph() {
+        return controlFlowGraph;
+    }
+
+    public int getNumLIROperations() {
+        return numLIROperations;
+    }
+
+
+    @Override
+    public String toString() {
+        return "    Intervals \"" + getName() + "\": " + intervals.length + " intervals\n";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/modelimpl/interval/RangeImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,36 @@
+package at.ssw.visualizer.modelimpl.interval;
+
+import at.ssw.visualizer.model.interval.Range;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class RangeImpl implements Range, Comparable<RangeImpl> {
+    private int from;
+    private int to;
+
+    public RangeImpl(int from, int to) {
+        this.from = from;
+        this.to = to;
+    }
+
+
+    public int getFrom() {
+        return from;
+    }
+
+    public int getTo() {
+        return to;
+    }
+
+
+    public int compareTo(RangeImpl other) {
+        return getFrom() - other.getFrom();
+    }
+
+    @Override
+    public String toString() {
+        return "[" + from + ", " + to + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/modelimpl/interval/UsePositionImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,36 @@
+package at.ssw.visualizer.modelimpl.interval;
+
+import at.ssw.visualizer.model.interval.UsePosition;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class UsePositionImpl implements UsePosition, Comparable<UsePositionImpl> {
+    private int position;
+    private char kind;
+
+    public UsePositionImpl(int position, char kind) {
+        this.position = position;
+        this.kind = kind;
+    }
+
+
+    public char getKind() {
+        return kind;
+    }
+
+    public int getPosition() {
+        return position;
+    }
+
+
+    public int compareTo(UsePositionImpl other) {
+        return getPosition() - other.getPosition();
+    }
+
+    @Override
+    public String toString() {
+        return position + "(" + kind + ")";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/at/ssw/visualizer/modelimpl/nc/NativeMethodImpl.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,28 @@
+package at.ssw.visualizer.modelimpl.nc;
+
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.model.nc.NativeMethod;
+
+/**
+ *
+ * @author Alexander Reder
+ */
+public class NativeMethodImpl implements NativeMethod {
+
+    private ControlFlowGraph controlFlowGraph;
+    private String methodText;
+    
+    public NativeMethodImpl(ControlFlowGraph controlFlowGraph, String methodText) {
+        this.controlFlowGraph = controlFlowGraph;
+        this.methodText = methodText;
+    }
+
+    public ControlFlowGraph getControlFlowGraph() {
+        return controlFlowGraph;
+    }
+    
+    public String getMethodText() {
+        return methodText;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/AbstractFolderElement.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.data;
+
+public class AbstractFolderElement implements FolderElement {
+    
+    private String name;
+    private String shortName;
+    private Folder parent;
+    
+    public AbstractFolderElement(String name, String shortName) {
+        this.name = name;
+        this.shortName = shortName;
+    }
+
+    public String getShortName() {
+        return shortName;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public Folder getParent() {
+        return parent;
+    }
+
+    @Override
+    public void setParent(Folder parent) {
+        this.parent = parent;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=Data
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/ChangedEvent.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * 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.sun.hotspot.igv.data;
+
+public class ChangedEvent<T> extends Event<ChangedListener<T>> {
+
+    private T object;
+
+    public ChangedEvent(T object) {
+        this.object = object;
+    }
+
+    @Override
+    protected void fire(ChangedListener<T> l) {
+        l.changed(object);
+    }
+
+    public void changeObject(T newObject) {
+        if (object != newObject) {
+            this.object = newObject;
+            fire();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/ChangedEventProvider.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1998, 2007, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.data;
+
+/**
+ * Provides a changed event object.
+ * @author Thomas Wuerthinger
+ * @param <T> Class for which the changed event fires.
+ */
+public interface ChangedEventProvider<T> {
+
+    /**
+     * Returns the changed event object. Should always return the same instance.
+     */
+    ChangedEvent<T> getChangedEvent();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/ChangedListener.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+/**
+ * Listens to changed events.
+ * @author Thomas Wuerthinger
+ * @param <T> Class for which the changed event fires.
+ */
+public interface ChangedListener<T> {
+
+    /**
+     * This method is called everytime a changed event is fired.
+     * @param source Object that has changed.
+     */
+    void changed(T source);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/ControllableChangedListener.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public abstract class ControllableChangedListener<T> implements ChangedListener<T>{
+
+	private boolean enabled;
+
+	
+	public ControllableChangedListener() {
+		enabled = true;
+	}
+
+	public boolean isEnabled() {
+		return enabled;
+	}
+
+	public void setEnabled(boolean b) {
+		enabled = b;
+	}
+
+    @Override
+	public void changed(T source) {
+		if(enabled) {
+			filteredChanged(source);
+		}
+	}
+
+	public abstract void filteredChanged(T source);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/Event.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public abstract class Event<L> {
+
+    private List<L> listener;
+    private boolean fireEvents;
+    private boolean eventWasFired;
+    
+    public Event() {
+        listener = new ArrayList<>();
+        fireEvents = true;
+    }
+
+    public void addListener(L l) {
+        listener.add(l);
+    }
+
+    public void addListenerAndFire(L l) {
+        addListener(l);
+        fire(l);
+    }
+
+    /**
+     * Remove listener
+     * @param l
+     */
+    public void removeListener(final L l) {
+        listener.remove(l);
+    }
+
+    public void fire() {
+        if(fireEvents) {
+            List<L> tmpList = new ArrayList<>(listener);
+            for (L l : tmpList) {
+                fire(l);
+            }
+        } else {
+            eventWasFired = true;
+        }
+    }
+
+    public void beginAtomic() {
+        assert fireEvents : "endAtomic has to be called before another beginAtomic may be called";
+        this.fireEvents = false;
+        this.eventWasFired = false;
+    }
+
+    public void endAtomic() {
+        assert !fireEvents : "beginAtomic has to be called first";
+        this.fireEvents = true;
+        if(eventWasFired) {
+            fire();
+        }
+    }
+    
+    protected abstract void fire(L l);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/Folder.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,34 @@
+/*
+ * 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.sun.hotspot.igv.data;
+
+import java.util.List;
+
+public interface Folder {
+    String getName();
+    List<? extends FolderElement> getElements();
+    void removeElement(FolderElement element);
+    void addElement(FolderElement group);
+    ChangedEvent<? extends Folder> getChangedEvent();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/FolderElement.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,31 @@
+/*
+ * 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.sun.hotspot.igv.data;
+
+public interface FolderElement {
+    
+    Folder getParent();
+    String getName();
+    void setParent(Folder parent);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class GraphDocument extends Properties.Entity implements ChangedEventProvider<GraphDocument>, Folder {
+
+    private List<FolderElement> elements;
+    private ChangedEvent<GraphDocument> changedEvent;
+
+    public GraphDocument() {
+        elements = new ArrayList<>();
+        changedEvent = new ChangedEvent<>(this);
+    }
+
+    public void clear() {
+        elements.clear();
+        getChangedEvent().fire();
+    }
+
+    @Override
+    public ChangedEvent<GraphDocument> getChangedEvent() {
+        return changedEvent;
+    }
+
+    public void addGraphDocument(GraphDocument document) {
+        for (FolderElement e : document.elements) {
+            e.setParent(this);
+            this.addElement(e);
+        }
+        document.clear();
+        getChangedEvent().fire();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append("GraphDocument: ").append(getProperties().toString()).append(" \n\n");
+        for (FolderElement g : getElements()) {
+            sb.append(g.toString());
+            sb.append("\n\n");
+        }
+
+        return sb.toString();
+    }
+
+    @Override
+    public List<? extends FolderElement> getElements() {
+        return elements;
+    }
+
+    @Override
+    public void removeElement(FolderElement element) {
+        if (elements.remove(element)) {
+            getChangedEvent().fire();
+        }
+    }
+
+    @Override
+    public void addElement(FolderElement element) {
+        elements.add(element);
+        element.setParent(this);
+        getChangedEvent().fire();
+    }
+
+    @Override
+    public String getName() {
+        return "root";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/Group.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import java.util.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Group extends Properties.Entity implements ChangedEventProvider<Group>, Folder, FolderElement {
+
+    private final List<FolderElement> elements;
+    private final List<InputGraph> graphs;
+
+    private InputMethod method;
+    private transient ChangedEvent<Group> changedEvent;
+    private Folder parent;
+
+    public Group(Folder parent) {
+        elements = new ArrayList<>();
+        graphs = new ArrayList<>();
+        changedEvent = new ChangedEvent<>(this);
+        this.parent = parent;
+
+        // Ensure that name and type are never null
+        getProperties().setProperty("name", "");
+        getProperties().setProperty("type", "");
+    }
+
+    public void fireChangedEvent() {
+        changedEvent.fire();
+    }
+
+    public void setMethod(InputMethod method) {
+        this.method = method;
+    }
+
+    public InputMethod getMethod() {
+        return method;
+    }
+
+    @Override
+    public ChangedEvent<Group> getChangedEvent() {
+        return changedEvent;
+    }
+
+    @Override
+    public List<FolderElement> getElements() {
+        return Collections.unmodifiableList(elements);
+    }
+
+    public int getGraphsCount() {
+        return elements.size();
+    }
+    
+    @Override
+    public void addElement(FolderElement element) {
+        elements.add(element);
+        if (element instanceof InputGraph) {
+            graphs.add((InputGraph) element);
+        } else {
+            
+        }
+        element.setParent(this);
+        changedEvent.fire();
+    }
+
+    public Set<Integer> getAllNodes() {
+        Set<Integer> result = new HashSet<>();
+        for (FolderElement e : elements) {
+            if (e instanceof InputGraph) {
+                InputGraph g = (InputGraph) e;
+                result.addAll(g.getNodesAsSet());
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Group ").append(getProperties()).append("\n");
+        for (FolderElement g : elements) {
+            sb.append(g.toString());
+            sb.append('\n');
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public String getName() {
+        return getProperties().get("name");
+    }
+
+    public String getType() {
+        return getProperties().get("type");
+        
+    }
+
+    InputGraph getPrev(InputGraph graph) {
+        InputGraph lastGraph = null;
+        for (FolderElement e : elements) {
+            if (e == graph) {
+                return lastGraph;
+            }
+            if (e instanceof InputGraph) {
+                lastGraph = (InputGraph) e;
+            }
+        }
+        return null;
+    }
+
+    InputGraph getNext(InputGraph graph) {
+        boolean found = false;
+        for (FolderElement e : elements) {
+            if (e == graph) {
+                found = true;
+            } else if (found && e instanceof InputGraph) {
+                return (InputGraph) e;
+            }
+        }
+        return null;
+    }
+
+    public InputGraph getLastGraph() {
+        InputGraph lastGraph = null;
+        for (FolderElement e : elements) {
+            if (e instanceof InputGraph) {
+                lastGraph = (InputGraph) e;
+            }
+        }
+        return lastGraph;
+    }
+
+    @Override
+    public Folder getParent() {
+         return parent;
+    }
+
+    @Override
+    public void removeElement(FolderElement element) {
+        if (elements.remove(element)) {
+            if (element instanceof InputGraph) {
+                graphs.remove((InputGraph) element);
+            }
+            changedEvent.fire();
+        }
+    }
+
+    public List<InputGraph> getGraphs() {
+        return graphs;
+    }
+
+    @Override
+    public void setParent(Folder parent) {
+        this.parent = parent;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/InputBlock.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.model.cfg.IRInstruction;
+import at.ssw.visualizer.model.cfg.State;
+import java.util.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputBlock implements BasicBlock {
+
+    private List<InputNode> nodes;
+    private String name;
+    private InputGraph graph;
+    private List<InputBlock> successors;
+    private List<InputBlock> predecessors;
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+
+        if (o == this) {
+            return true;
+        }
+
+        if (o == null || (!(o instanceof InputBlock))) {
+            return false;
+        }
+        
+        final InputBlock b = (InputBlock)o;
+        final boolean result = b.nodes.equals(nodes) && b.name.equals(name) && b.successors.size() == successors.size();
+        if (!result) {
+            return false;
+        }
+
+        final HashSet<String> s = new HashSet<>();
+        for (InputBlock succ : successors) {
+            s.add(succ.name);
+        }
+
+        for (InputBlock succ : b.successors) {
+            if (!s.contains(succ.name)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    InputBlock(InputGraph graph, String name) {
+        this.graph = graph;
+        this.name = name;
+        nodes = new ArrayList<>();
+        successors = new ArrayList<>();
+        predecessors = new ArrayList<>();
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public List<InputNode> getNodes() {
+        return Collections.unmodifiableList(nodes);
+    }
+
+    public void addNode(int id) {
+        InputNode n = graph.getNode(id);
+        assert n != null;
+        graph.setBlock(n, this);
+        final InputNode node = graph.getNode(id);
+        assert node != null;
+        assert !nodes.contains(node) : "duplicate : " + node;
+        nodes.add(node);
+    }
+
+    @Override
+    public List<InputBlock> getSuccessors() {
+        return Collections.unmodifiableList(successors);
+    }
+
+    @Override
+    public String toString() {
+        return "Block " + this.getName();
+    }
+
+    void addSuccessor(InputBlock b) {
+        if (!successors.contains(b)) {
+            successors.add(b);
+            b.predecessors.add(this);
+        }
+    }
+
+    @Override
+    public int getFromBci() {
+        // TODO(tw): Implement.
+        return -1;
+    }
+
+    @Override
+    public int getToBci() {
+        // TODO(tw): Implement.
+        return -1;
+    }
+
+    @Override
+    public List<InputBlock> getPredecessors() {
+        return Collections.unmodifiableList(predecessors);
+    }
+
+    @Override
+    public List<BasicBlock> getXhandlers() {
+        // TODO(tw): Implement.
+        return Collections.emptyList();
+    }
+
+    @Override
+    public List<String> getFlags() {
+        // TODO(tw): Implement.
+        return Collections.emptyList();
+    }
+
+    @Override
+    public BasicBlock getDominator() {
+        // TODO(tw): Implement.
+        return null;
+    }
+
+    @Override
+    public int getLoopIndex() {
+        // TODO(tw): Implement.
+        return -1;
+    }
+
+    @Override
+    public int getLoopDepth() {
+        // TODO(tw): Implement.
+        return -1;
+    }
+
+    @Override
+    public boolean hasState() {
+        // TODO(tw): Implement.
+        return false;
+    }
+
+    @Override
+    public List<State> getStates() {
+        // TODO(tw): Implement.
+        return Collections.emptyList();
+    }
+
+    @Override
+    public boolean hasHir() {
+        // TODO(tw): Implement.
+        return false;
+    }
+
+    @Override
+    public List<IRInstruction> getHirInstructions() {
+        // TODO(tw): Implement.
+        return Collections.emptyList();
+    }
+
+    @Override
+    public boolean hasLir() {
+        // TODO(tw): Implement.
+        return false;
+    }
+
+    @Override
+    public List<IRInstruction> getLirOperations() {
+        // TODO(tw): Implement.
+        return Collections.emptyList();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/InputBlockEdge.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputBlockEdge {
+
+    public enum State {
+        SAME,
+        NEW,
+        DELETED
+    }
+
+    private InputBlock from;
+    private InputBlock to;
+    private State state = State.SAME;
+
+    public InputBlockEdge(InputBlock from, InputBlock to) {
+        assert from != null;
+        assert to != null;
+        this.from = from;
+        this.to = to;
+    }
+
+    public InputBlock getFrom() {
+        return from;
+    }
+
+    public InputBlock getTo() {
+        return to;
+    }
+
+    public State getState() {
+        return state;
+    }
+
+    public void setState(State state) {
+        this.state = state;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj != null && obj instanceof InputBlockEdge) {
+            InputBlockEdge e = (InputBlockEdge) obj;
+            return e.from.equals(from) && e.to.equals(to);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = from.hashCode();
+        hash = 59 * hash + to.hashCode();
+        return hash;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/InputBytecode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputBytecode {
+
+    private int bci;
+    private String name;
+    private InputMethod inlined;
+
+    public InputBytecode(int bci, String name) {
+        this.bci = bci;
+        this.name = name;
+    }
+
+    public InputMethod getInlined() {
+        return inlined;
+    }
+
+    public void setInlined(InputMethod inlined) {
+        this.inlined = inlined;
+    }
+
+    public int getBci() {
+        return bci;
+    }
+
+    public String getName() {
+        return name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import java.util.Comparator;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputEdge {
+
+    public enum State {
+
+        SAME,
+        NEW,
+        DELETED
+    }
+    
+    public static final Comparator<InputEdge> OUTGOING_COMPARATOR = new Comparator<InputEdge>(){
+
+        @Override
+            public int compare(InputEdge o1, InputEdge o2) {
+                if(o1.getFromIndex() == o2.getFromIndex()) {
+                    return o1.getTo() - o2.getTo();
+                }
+                return o1.getFromIndex() - o2.getFromIndex();
+            }
+    };
+    
+    
+    public static final Comparator<InputEdge> INGOING_COMPARATOR = new Comparator<InputEdge>(){
+
+        @Override
+            public int compare(InputEdge o1, InputEdge o2) {
+                if(o1.getToIndex() == o2.getToIndex()) {
+                    return o1.getFrom() - o2.getFrom();
+                }
+                return o1.getToIndex() - o2.getToIndex();
+            }
+    };
+
+    private char toIndex;
+    private char fromIndex;
+    private int from;
+    private int to;
+    private State state;
+    private String label;
+
+    public InputEdge(char toIndex, int from, int to) {
+        this((char) 0, toIndex, from, to, null);
+    }
+
+    public InputEdge(char fromIndex, char toIndex, int from, int to) {
+        this(fromIndex, toIndex, from, to, null);
+    }
+
+    public InputEdge(char fromIndex, char toIndex, int from, int to, String label) {
+        this.toIndex = toIndex;
+        this.fromIndex = fromIndex;
+        this.from = from;
+        this.to = to;
+        this.state = State.SAME;
+        this.label = label;
+    }
+
+    public State getState() {
+        return state;
+    }
+
+    public void setState(State x) {
+        this.state = x;
+    }
+
+    public char getToIndex() {
+        return toIndex;
+    }
+    
+    public char getFromIndex() {
+        return fromIndex;
+    }
+
+    public String getName() {
+        return "in" + toIndex;
+    }
+
+    public int getFrom() {
+        return from;
+    }
+
+    public int getTo() {
+        return to;
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == null || !(o instanceof InputEdge)) {
+            return false;
+        }
+        InputEdge conn2 = (InputEdge) o;
+        return conn2.fromIndex == fromIndex && conn2.toIndex == toIndex && conn2.from == from && conn2.to == to;
+    }
+
+    @Override
+    public String toString() {
+        return "Edge from " + from + " to " + to + "(" + (int) fromIndex + ", " + (int) toIndex + ") ";
+    }
+
+    @Override
+    public int hashCode() {
+        return (from << 20 | to << 8 | toIndex << 4 | fromIndex);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import at.ssw.visualizer.model.bc.Bytecodes;
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.model.nc.NativeMethod;
+import java.util.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputGraph extends Properties.Entity implements FolderElement, ControlFlowGraph {
+
+    private Map<Integer, InputNode> nodes;
+    private Set<InputEdge> edges;
+    private Folder parent;
+    private Group parentGroup;
+    private Map<String, InputBlock> blocks;
+    private Set<InputBlockEdge> blockEdges;
+    private Map<Integer, InputBlock> nodeToBlock;
+
+    public InputGraph(String name) {
+        setName(name);
+        nodes = new LinkedHashMap<>();
+        edges = new LinkedHashSet<>();
+        blocks = new LinkedHashMap<>();
+        blockEdges = new LinkedHashSet<>();
+        nodeToBlock = new LinkedHashMap<>();
+    }
+    
+    @Override
+    public void setParent(Folder parent) {
+        this.parent = parent;
+        if (parent instanceof Group) {
+            assert this.parentGroup == null;
+            this.parentGroup = (Group) parent;
+        }
+    }
+
+    public InputBlockEdge addBlockEdge(InputBlock left, InputBlock right) {
+        InputBlockEdge edge = new InputBlockEdge(left, right);
+        blockEdges.add(edge);
+        left.addSuccessor(right);
+        return edge;
+    }
+    
+    public List<InputNode> findRootNodes() {
+        List<InputNode> result = new ArrayList<>();
+        Set<Integer> nonRoot = new HashSet<>();
+        for(InputEdge curEdges : getEdges()) {
+            nonRoot.add(curEdges.getTo());
+        }
+        
+        for(InputNode node : getNodes()) {
+            if(!nonRoot.contains(node.getId())) {
+                result.add(node);
+            }
+        }
+        
+        return result;
+    }
+    
+    public Map<InputNode, List<InputEdge>> findAllOutgoingEdges() {
+        
+        Map<InputNode, List<InputEdge>> result = new HashMap<>(getNodes().size());
+        for(InputNode n : this.getNodes()) {
+            result.put(n, new ArrayList<InputEdge>());
+        }
+        
+        for(InputEdge e : this.edges) {
+            int from = e.getFrom();
+            InputNode fromNode = this.getNode(from);
+            List<InputEdge> fromList = result.get(fromNode);
+            assert fromList != null;
+            fromList.add(e);
+        }
+        
+        for(InputNode n : this.getNodes()) {
+            List<InputEdge> list = result.get(n);
+            Collections.sort(list, InputEdge.OUTGOING_COMPARATOR);
+        }
+        
+        return result;
+    }
+    
+    public Map<InputNode, List<InputEdge>> findAllIngoingEdges() {
+        
+        Map<InputNode, List<InputEdge>> result = new HashMap<>(getNodes().size());
+        for(InputNode n : this.getNodes()) {
+            result.put(n, new ArrayList<InputEdge>());
+        }
+        
+        for(InputEdge e : this.edges) {
+            int to = e.getTo();
+            InputNode toNode = this.getNode(to);
+            List<InputEdge> toList = result.get(toNode);
+            assert toList != null;
+            toList.add(e);
+        }
+        
+        for(InputNode n : this.getNodes()) {
+            List<InputEdge> list = result.get(n);
+            Collections.sort(list, InputEdge.INGOING_COMPARATOR);
+        }
+        
+        return result;
+    }
+    
+    public List<InputEdge> findOutgoingEdges(InputNode n) {
+        List<InputEdge> result = new ArrayList<>();
+        
+        for(InputEdge e : this.edges) {
+            if(e.getFrom() == n.getId()) {
+                result.add(e);
+            }
+        }
+        
+        Collections.sort(result, InputEdge.OUTGOING_COMPARATOR);
+        
+        return result;
+    }
+
+    public void clearBlocks() {
+        blocks.clear();
+        nodeToBlock.clear();
+    }
+    
+    public void setEdge(int fromIndex, int toIndex, int from, int to) {
+        assert fromIndex == ((char)fromIndex) : "Downcast must be safe";
+        assert toIndex == ((char)toIndex) : "Downcast must be safe";
+        
+        InputEdge edge = new InputEdge((char)fromIndex, (char)toIndex, from, to);
+        if(!this.getEdges().contains(edge)) {
+            this.addEdge(edge);
+        }
+    }
+
+    public void ensureNodesInBlocks() {
+        InputBlock noBlock = null;
+        Set<InputNode> scheduledNodes = new HashSet<>();
+
+        for (InputBlock b : getBlocks()) {
+            for (InputNode n : b.getNodes()) {
+                assert !scheduledNodes.contains(n);
+                scheduledNodes.add(n);
+            }
+        }
+
+        for (InputNode n : this.getNodes()) {
+            assert nodes.get(n.getId()) == n;
+            if (!scheduledNodes.contains(n)) {
+                if (noBlock == null) {
+                    noBlock = this.addBlock("(no block)");
+                }
+                noBlock.addNode(n.getId());
+            }
+            assert this.getBlock(n) != null;
+        }
+    }
+
+    public void setBlock(InputNode node, InputBlock block) {
+        nodeToBlock.put(node.getId(), block);
+    }
+
+    public InputBlock getBlock(int nodeId) {
+        return nodeToBlock.get(nodeId);
+    }
+
+    public InputBlock getBlock(InputNode node) {
+        assert nodes.containsKey(node.getId());
+        assert nodes.get(node.getId()).equals(node);
+        return getBlock(node.getId());
+    }
+
+    public InputGraph getNext() {
+        return parentGroup.getNext(this);
+    }
+
+    public InputGraph getPrev() {
+        return parentGroup.getPrev(this);
+    }
+
+    private void setName(String name) {
+        this.getProperties().setProperty("name", name);
+    }
+
+    @Override
+    public String getName() {
+        return getProperties().get("name");
+    }
+
+    public Collection<InputNode> getNodes() {
+        return Collections.unmodifiableCollection(nodes.values());
+    }
+
+    public Set<Integer> getNodesAsSet() {
+        return Collections.unmodifiableSet(nodes.keySet());
+    }
+
+    public Collection<InputBlock> getBlocks() {
+        return Collections.unmodifiableCollection(blocks.values());
+    }
+
+    public void addNode(InputNode node) {
+        nodes.put(node.getId(), node);
+    }
+
+    public InputNode getNode(int id) {
+        return nodes.get(id);
+    }
+
+    public InputNode removeNode(int index) {
+        return nodes.remove(index);
+    }
+
+    public Collection<InputEdge> getEdges() {
+        return Collections.unmodifiableSet(edges);
+    }
+
+    public void removeEdge(InputEdge c) {
+        boolean removed = edges.remove(c);
+        assert removed;
+    }
+
+    public void addEdge(InputEdge c) {
+        // Be tolerant with duplicated edges.
+        if (!edges.contains(c)) {
+            edges.add(c);
+        }
+    }
+
+    public Group getGroup() {
+        return parentGroup;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Graph ").append(getName()).append(" ").append(getProperties().toString()).append("\n");
+        for (InputNode n : nodes.values()) {
+            sb.append(n.toString());
+            sb.append("\n");
+        }
+
+        for (InputEdge c : edges) {
+            sb.append(c.toString());
+            sb.append("\n");
+        }
+
+        for (InputBlock b : getBlocks()) {
+            sb.append(b.toString());
+            sb.append("\n");
+        }
+
+        return sb.toString();
+    }
+
+    public InputBlock addBlock(String name) {
+        final InputBlock b = new InputBlock(this, name);
+        blocks.put(b.getName(), b);
+        return b;
+    }
+
+    public InputBlock getBlock(String s) {
+        return blocks.get(s);
+    }
+
+    public Collection<InputBlockEdge> getBlockEdges() {
+        return Collections.unmodifiableSet(blockEdges);
+    }
+
+    @Override
+    public Folder getParent() {
+        return parent;
+    }
+
+    @Override
+    public List<BasicBlock> getBasicBlocks() {
+        return new ArrayList<BasicBlock>(blocks.values());
+    }
+
+    @Override
+    public BasicBlock getBasicBlockByName(String name) {
+        return blocks.get(name);
+    }
+
+    @Override
+    public Bytecodes getBytecodes() {
+        // TODO(tw): no bytecodes
+        return null;
+    }
+
+    @Override
+    public NativeMethod getNativeMethod() {
+        // TODO(tw): No native method.
+        return null;
+    }
+
+    @Override
+    public boolean hasState() {
+        // TODO(tw): implement
+        return false;
+    }
+
+    @Override
+    public boolean hasHir() {
+        // TODO(tw): Implement
+        return false;
+    }
+
+    @Override
+    public boolean hasLir() {
+        // TODO(tw): Implement
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputMethod extends Properties.Entity {
+
+    private String name;
+    private int bci;
+    private String shortName;
+    private List<InputMethod> inlined;
+    private InputMethod parentMethod;
+    private Group group;
+    private List<InputBytecode> bytecodes;
+
+    @Override
+    public int hashCode() {
+        int result = name.hashCode();
+        result = result * 31 + bci;
+        result = result * 31 + shortName.hashCode();
+        result = result * 31 + inlined.hashCode();
+        result = result * 31 + bytecodes.hashCode();
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == null || (!(o instanceof InputMethod))) {
+            return false;
+        }
+
+        final InputMethod im = (InputMethod)o;
+        return name.equals(im.name) && bci == im.bci && shortName.equals(im.shortName) &&
+               inlined.equals(im.inlined) && bytecodes.equals(im.bytecodes);
+    }
+
+
+
+    /** Creates a new instance of InputMethod */
+    public InputMethod(Group parent, String name, String shortName, int bci) {
+        this.group = parent;
+        this.name = name;
+        this.bci = bci;
+        this.shortName = shortName;
+        inlined = new ArrayList<>();
+        bytecodes = new ArrayList<>();
+    }
+
+    public List<InputBytecode> getBytecodes() {
+        return Collections.unmodifiableList(bytecodes);
+    }
+
+    public List<InputMethod> getInlined() {
+        return Collections.unmodifiableList(inlined);
+    }
+
+    public void addInlined(InputMethod m) {
+
+        // assert bci unique
+        for (InputMethod m2 : inlined) {
+            assert m2.getBci() != m.getBci();
+        }
+
+        inlined.add(m);
+        assert m.parentMethod == null;
+        m.parentMethod = this;
+
+        for (InputBytecode bc : bytecodes) {
+            if (bc.getBci() == m.getBci()) {
+                bc.setInlined(m);
+            }
+        }
+    }
+
+    public Group getGroup() {
+        return group;
+    }
+
+    public String getShortName() {
+        return shortName;
+    }
+
+    public void setBytecodes(String text) {
+
+        String[] strings = text.split("\n");
+        int oldNumber = -1;
+        for (String s : strings) {
+
+            if (s.length() > 0 && Character.isDigit(s.charAt(0))) {
+                s = s.trim();
+                int spaceIndex = s.indexOf(' ');
+                String numberString = s.substring(0, spaceIndex);
+                String tmpName = s.substring(spaceIndex + 1, s.length());
+
+                int number = -1;
+                number = Integer.parseInt(numberString);
+
+                // assert correct order of bytecodes
+                assert number > oldNumber;
+
+                InputBytecode bc = new InputBytecode(number, tmpName);
+                bytecodes.add(bc);
+
+                for (InputMethod m : inlined) {
+                    if (m.getBci() == number) {
+                        bc.setInlined(m);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public int getBci() {
+        return bci;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/InputNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import java.util.Comparator;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputNode extends Properties.Entity {
+
+    private int id;
+
+    public static final Comparator<InputNode> COMPARATOR = new Comparator<InputNode>() {
+        @Override
+        public int compare(InputNode o1, InputNode o2) {
+            return o1.getId() - o2.getId();
+        }
+    };
+
+    public static Comparator<InputNode> getPropertyComparator(final String propertyName) {
+        return new Comparator<InputNode>() {
+
+            @Override
+            public int compare(InputNode o1, InputNode o2) {
+
+                int i1 = 0;
+                try {
+                    i1 = Integer.parseInt(o1.getProperties().get(propertyName));
+                } catch(NumberFormatException e) {
+                }
+
+                int i2 = 0;
+                try {
+                    i2 = Integer.parseInt(o2.getProperties().get(propertyName));
+                } catch(NumberFormatException e) {
+                }
+
+                return i1 - i2;
+            }
+        };
+    }
+
+    public InputNode(InputNode n) {
+        super(n);
+        setId(n.id);
+    }
+
+    public InputNode(int id) {
+        setId(id);
+    }
+
+    public void setId(int id) {
+        this.id = id;
+        getProperties().setProperty("id", "" + id);
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof InputNode)) {
+            return false;
+        }
+        InputNode n = (InputNode) o;
+        return n.id == id;
+    }
+
+    @Override
+    public int hashCode() {
+        return id * 13;
+    }
+
+    @Override
+    public String toString() {
+        return "Node " + id + " " + getProperties().toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/Pair.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Pair<L, R> {
+
+    private L l;
+    private R r;
+
+    public Pair() {
+    }
+
+    public Pair(L l, R r) {
+        this.l = l;
+        this.r = r;
+    }
+
+    public L getLeft() {
+        return l;
+    }
+
+    public void setLeft(L l) {
+        this.l = l;
+    }
+
+    public R getRight() {
+        return r;
+    }
+
+    public void setRight(R r) {
+        this.r = r;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == null || !(o instanceof Pair)) {
+            return false;
+        }
+        Pair<?,?> obj = (Pair<?,?>) o;
+        boolean b1 = (l == obj.l);
+        if (l != null) {
+            b1 = l.equals(obj.l);
+        }
+
+        boolean b2 = (r == obj.r);
+        if (r != null) {
+            b2 = r.equals(obj.r);
+        }
+        
+        return b1 && b2;
+    }
+
+    @Override
+    public int hashCode() {
+        return ((l == null) ? 0 : l.hashCode()) * 71 + ((r == null) ? 0 : r.hashCode());
+    }
+
+    @Override
+    public String toString() {
+        return "[" + l + "/" + r + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/Properties.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import java.io.Serializable;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Properties implements Serializable, Iterable<Property> {
+
+    public static final long serialVersionUID = 1L;
+    private String[] map = new String[4];
+
+    public Properties() {
+    }
+
+    @Override
+    public boolean equals(java.lang.Object o) {
+        if (!(o instanceof Properties)) {
+            return false;
+        }
+
+        Properties p = (Properties) o;
+
+        for (Property prop : this) {
+            String value = p.get(prop.getName());
+            if (value == null || !value.equals(prop.getValue())) {
+                return false;
+            }
+        }
+
+        for (Property prop : p) {
+            String value = this.get(prop.getName());
+            if (value == null || !value.equals(prop.getValue())) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 5;
+
+        if (map != null) {
+            for (int i = 0; i < this.map.length; i++) {
+                if (map[i] == null) {
+                    i++;
+                } else {
+                    hash = hash * 83 + map[i].hashCode();
+                }
+            }
+        }
+        return hash;
+    }
+
+    public Properties(String name, String value) {
+        this();
+        this.setProperty(name, value);
+    }
+
+    public Properties(String name, String value, String name1, String value1) {
+        this(name, value);
+        this.setProperty(name1, value1);
+    }
+
+    public Properties(String name, String value, String name1, String value1, String name2, String value2) {
+        this(name, value, name1, value1);
+        this.setProperty(name2, value2);
+    }
+
+    public Properties(Properties p) {
+        map = new String[p.map.length];
+        System.arraycopy(p.map, 0, map, 0, p.map.length);
+    }
+
+    public static class Entity implements Provider {
+
+        private Properties properties;
+
+        public Entity() {
+            properties = new Properties();
+        }
+
+        public Entity(Properties.Entity object) {
+            properties = new Properties(object.getProperties());
+        }
+
+        @Override
+        public Properties getProperties() {
+            return properties;
+        }
+    }
+
+    public interface PropertyMatcher {
+
+        String getName();
+
+        boolean match(String value);
+    }
+
+    public static class InvertPropertyMatcher implements PropertyMatcher {
+
+        private PropertyMatcher matcher;
+
+        public InvertPropertyMatcher(PropertyMatcher matcher) {
+            this.matcher = matcher;
+        }
+
+        @Override
+        public String getName() {
+            return matcher.getName();
+        }
+
+        @Override
+        public boolean match(String p) {
+            if (p == null) {
+                return false;
+            }
+            return !matcher.match(p);
+        }
+    }
+
+    public static class StringPropertyMatcher implements PropertyMatcher {
+
+        private String name;
+        private String value;
+
+        public StringPropertyMatcher(String name, String value) {
+            if (name == null) {
+                throw new IllegalArgumentException("Property name must not be null!");
+            }
+            if (value == null) {
+                throw new IllegalArgumentException("Property value must not be null!");
+            }
+            this.name = name;
+            this.value = value;
+        }
+
+        @Override
+        public String getName() {
+            return name;
+        }
+
+        @Override
+        public boolean match(String p) {
+            if (p == null) {
+                throw new IllegalArgumentException("Property value must not be null!");
+            }
+            return p.equals(value);
+        }
+    }
+
+    public static class RegexpPropertyMatcher implements PropertyMatcher {
+
+        private String name;
+        private Pattern valuePattern;
+        
+        public RegexpPropertyMatcher(String name, String value) {
+            this(name, value, 0);
+        }
+
+        public RegexpPropertyMatcher(String name, String value, int flags) {
+
+            if (name == null) {
+                throw new IllegalArgumentException("Property name must not be null!");
+            }
+
+            if (value == null) {
+                throw new IllegalArgumentException("Property value pattern must not be null!");
+            }
+
+            this.name = name;
+
+            try {
+                valuePattern = Pattern.compile(value, flags);
+            } catch (PatternSyntaxException e) {
+                throw new IllegalArgumentException("Bad pattern: " + value);
+            }
+        }
+
+        @Override
+        public String getName() {
+            return name;
+        }
+
+        @Override
+        public boolean match(String p) {
+            if (p == null) {
+                throw new IllegalArgumentException("Property value must not be null!");
+            }
+            Matcher m = valuePattern.matcher(p);
+            return m.matches();
+        }
+    }
+
+    public Property selectSingle(PropertyMatcher matcher) {
+
+        final String name = matcher.getName();
+        String value = null;
+        for (int i = 0; i < map.length; i += 2) {
+            if (map[i] != null && name.equals(map[i])) {
+                value = map[i + 1];
+                break;
+            }
+        }
+        if (value != null && matcher.match(value)) {
+            return new Property(name, value);
+        } else {
+            return null;
+        }
+    }
+
+    public interface Provider {
+
+        public Properties getProperties();
+    }
+
+    @Override
+    public String toString() {
+        List<String[]> pairs = new ArrayList<>();
+        for (int i = 0; i < map.length; i += 2) {
+            if (map[i + 1] != null) {
+                pairs.add(new String[]{map[i], map[i + 1]});
+            }
+        }
+
+        Collections.sort(pairs, new Comparator<String[]>() {
+            @Override
+            public int compare(String[] o1, String[] o2) {
+                assert o1.length == 2;
+                assert o2.length == 2;
+                return o1[0].compareTo(o2[0]);
+            }
+        });
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("[");
+        boolean first = true;
+        for (String[] p : pairs) {
+            if (first) {
+                first = false;
+            } else {
+                sb.append(", ");
+            }
+            sb.append(p[0] + "=" + p[1]);
+        }
+        return sb.append("]").toString();
+    }
+
+    public static class PropertySelector<T extends Properties.Provider> {
+
+        private Collection<T> objects;
+
+        public PropertySelector(Collection<T> objects) {
+            this.objects = objects;
+        }
+
+        public T selectSingle(PropertyMatcher matcher) {
+
+            for (T t : objects) {
+                Property p = t.getProperties().selectSingle(matcher);
+                if (p != null) {
+                    return t;
+                }
+            }
+
+            return null;
+        }
+
+        public List<T> selectMultiple(PropertyMatcher matcher) {
+            List<T> result = new ArrayList<>();
+
+            for (T t : objects) {
+                Property p = t.getProperties().selectSingle(matcher);
+                if (p != null) {
+                    result.add(t);
+                }
+            }
+
+            return result;
+        }
+    }
+
+    public String get(String key) {
+        for (int i = 0; i < map.length; i += 2) {
+            if (map[i] != null && map[i].equals(key)) {
+                return map[i + 1];
+            }
+        }
+        return null;
+    }
+
+    public void setProperty(String name, String value) {
+
+        for (int i = 0; i < map.length; i += 2) {
+            if (map[i] != null && map[i].equals(name)) {
+                String p = map[i + 1];
+                if (value == null) {
+                    // remove this property
+                    map[i] = null;
+                    map[i + 1] = null;
+                } else {
+                    map[i + 1] = value;
+                }
+                return;
+            }
+        }
+        if (value == null) {
+            return;
+        }
+        for (int i = 0; i < map.length; i += 2) {
+            if (map[i] == null) {
+                map[i] = name;
+                map[i + 1] = value;
+                return;
+            }
+        }
+        String[] newMap = new String[map.length + 4];
+        System.arraycopy(map, 0, newMap, 0, map.length);
+        newMap[map.length] = name;
+        newMap[map.length + 1] = value;
+        map = newMap;
+    }
+
+    public void add(Properties properties) {
+        for (Property p : properties) {
+            setProperty(p.getName(), p.getValue());
+        }
+    }
+
+    private class PropertiesIterator implements Iterator<Property> {
+
+        int index;
+
+        @Override
+        public boolean hasNext() {
+            while (index < map.length && map[index + 1] == null) {
+                index += 2;
+            }
+            return index < map.length;
+        }
+
+        @Override
+        public Property next() {
+            if (index < map.length) {
+                index += 2;
+                return new Property(map[index - 2], map[index - 1]);
+            }
+            return null;
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+    }
+
+    @Override
+    public Iterator<Property> iterator() {
+        return new PropertiesIterator();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/Property.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import java.io.Serializable;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Property implements Serializable {
+
+    public static final long serialVersionUID = 1L;
+    private String name;
+    private String value;
+
+    Property(String name, String value) {
+        this.name = name;
+        this.value = value;
+
+        if (value == null) {
+            throw new IllegalArgumentException("Property value must not be null!");
+        }
+
+        if (name == null) {
+            throw new IllegalArgumentException("Property name must not be null!");
+        }
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    @Override
+    public String toString() {
+        return name + "=" + value;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof Property)) {
+            return false;
+        }
+        Property p2 = (Property) o;
+        return name.equals(p2.name) && value.equals(p2.value);
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode() * 13 + value.hashCode();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/Source.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import java.util.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Source {
+
+    private List<InputNode> sourceNodes;
+    private Set<Integer> set;
+
+    public Source() {
+        sourceNodes = new ArrayList<>(1);
+        set = new LinkedHashSet<>(1);
+    }
+
+    public List<InputNode> getSourceNodes() {
+        return Collections.unmodifiableList(sourceNodes);
+    }
+
+    public Set<Integer> getSourceNodesAsSet() {
+        return Collections.unmodifiableSet(set);
+    }
+
+    public void addSourceNode(InputNode n) {
+        if (!set.contains(n.getId())) {
+            sourceNodes.add(n);
+            set.add(n.getId());
+        }
+    }
+
+    public interface Provider {
+
+        public Source getSource();
+    }
+
+    public void addSourceNodes(Source s) {
+        for (InputNode n : s.getSourceNodes()) {
+            addSourceNode(n);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/serialization/Parser.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,542 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data.serialization;
+
+import com.sun.hotspot.igv.data.*;
+import com.sun.hotspot.igv.data.serialization.XMLParser.ElementHandler;
+import com.sun.hotspot.igv.data.serialization.XMLParser.HandoverElementHandler;
+import com.sun.hotspot.igv.data.serialization.XMLParser.ParseMonitor;
+import com.sun.hotspot.igv.data.serialization.XMLParser.TopElementHandler;
+import com.sun.hotspot.igv.data.services.GroupCallback;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import javax.swing.SwingUtilities;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.SchemaFactory;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Parser {
+
+    public static final String INDENT = "  ";
+    public static final String TOP_ELEMENT = "graphDocument";
+    public static final String GROUP_ELEMENT = "group";
+    public static final String GRAPH_ELEMENT = "graph";
+    public static final String ROOT_ELEMENT = "graphDocument";
+    public static final String PROPERTIES_ELEMENT = "properties";
+    public static final String EDGES_ELEMENT = "edges";
+    public static final String PROPERTY_ELEMENT = "p";
+    public static final String EDGE_ELEMENT = "edge";
+    public static final String NODE_ELEMENT = "node";
+    public static final String NODES_ELEMENT = "nodes";
+    public static final String REMOVE_EDGE_ELEMENT = "removeEdge";
+    public static final String REMOVE_NODE_ELEMENT = "removeNode";
+    public static final String METHOD_NAME_PROPERTY = "name";
+    public static final String GROUP_NAME_PROPERTY = "name";
+    public static final String METHOD_IS_PUBLIC_PROPERTY = "public";
+    public static final String METHOD_IS_STATIC_PROPERTY = "static";
+    public static final String TRUE_VALUE = "true";
+    public static final String NODE_NAME_PROPERTY = "name";
+    public static final String EDGE_NAME_PROPERTY = "name";
+    public static final String NODE_ID_PROPERTY = "id";
+    public static final String FROM_PROPERTY = "from";
+    public static final String TO_PROPERTY = "to";
+    public static final String PROPERTY_NAME_PROPERTY = "name";
+    public static final String GRAPH_NAME_PROPERTY = "name";
+    public static final String FROM_INDEX_PROPERTY = "fromIndex";
+    public static final String TO_INDEX_PROPERTY = "toIndex";
+    public static final String TO_INDEX_ALT_PROPERTY = "index";
+    public static final String LABEL_PROPERTY = "label";
+    public static final String METHOD_ELEMENT = "method";
+    public static final String INLINE_ELEMENT = "inline";
+    public static final String BYTECODES_ELEMENT = "bytecodes";
+    public static final String METHOD_BCI_PROPERTY = "bci";
+    public static final String METHOD_SHORT_NAME_PROPERTY = "shortName";
+    public static final String CONTROL_FLOW_ELEMENT = "controlFlow";
+    public static final String BLOCK_NAME_PROPERTY = "name";
+    public static final String BLOCK_ELEMENT = "block";
+    public static final String SUCCESSORS_ELEMENT = "successors";
+    public static final String SUCCESSOR_ELEMENT = "successor";
+    public static final String ASSEMBLY_ELEMENT = "assembly";
+    public static final String DIFFERENCE_PROPERTY = "difference";
+    private TopElementHandler<GraphDocument> xmlDocument = new TopElementHandler<>();
+    private Map<Group, Boolean> differenceEncoding = new HashMap<>();
+    private Map<Group, InputGraph> lastParsedGraph = new HashMap<>();
+    private GroupCallback groupCallback;
+    private HashMap<String, Integer> idCache = new HashMap<>();
+    private ArrayList<Pair<String, String>> blockConnections = new ArrayList<>();
+    private int maxId = 0;
+    private GraphDocument graphDocument;
+
+    private int lookupID(String i) {
+        try {
+            return Integer.parseInt(i);
+        } catch (NumberFormatException nfe) {
+            // ignore
+        }
+        Integer id = idCache.get(i);
+        if (id == null) {
+            id = maxId++;
+            idCache.put(i, id);
+        }
+        return id.intValue();
+    }
+
+    // <graphDocument>
+    private ElementHandler<GraphDocument, Object> topHandler = new ElementHandler<GraphDocument, Object>(TOP_ELEMENT) {
+
+        @Override
+        protected GraphDocument start() throws SAXException {
+            graphDocument = new GraphDocument();
+            return graphDocument;
+        }
+    };
+    // <group>
+    private ElementHandler<Group, Folder> groupHandler = new XMLParser.ElementHandler<Group, Folder>(GROUP_ELEMENT) {
+
+        @Override
+        protected Group start() throws SAXException {
+            final Group group = new Group(this.getParentObject());
+
+            String differenceProperty = this.readAttribute(DIFFERENCE_PROPERTY);
+            Parser.this.differenceEncoding.put(group, (differenceProperty != null && (differenceProperty.equals("1") || differenceProperty.equals("true"))));
+
+            ParseMonitor monitor = getMonitor();
+            if (monitor != null) {
+                monitor.setState(group.getName());
+            }
+
+            final Folder parent = getParentObject();
+            if (groupCallback == null || parent instanceof Group) {
+                SwingUtilities.invokeLater(new Runnable(){
+                    @Override
+                    public void run() {
+                        parent.addElement(group);
+                    }
+                });
+            }
+
+            return group;
+        }
+
+        @Override
+        protected void end(String text) throws SAXException {
+        }
+    };
+    // <method>
+    private ElementHandler<InputMethod, Group> methodHandler = new XMLParser.ElementHandler<InputMethod, Group>(METHOD_ELEMENT) {
+
+        @Override
+        protected InputMethod start() throws SAXException {
+
+            InputMethod method = parseMethod(this, getParentObject());
+            getParentObject().setMethod(method);
+            return method;
+        }
+    };
+
+    private InputMethod parseMethod(XMLParser.ElementHandler<?,?> handler, Group group) throws SAXException {
+        String s = handler.readRequiredAttribute(METHOD_BCI_PROPERTY);
+        int bci = 0;
+        try {
+            bci = Integer.parseInt(s);
+        } catch (NumberFormatException e) {
+            throw new SAXException(e);
+        }
+        InputMethod method = new InputMethod(group, handler.readRequiredAttribute(METHOD_NAME_PROPERTY), handler.readRequiredAttribute(METHOD_SHORT_NAME_PROPERTY), bci);
+        return method;
+    }
+    // <bytecodes>
+    private HandoverElementHandler<InputMethod> bytecodesHandler = new XMLParser.HandoverElementHandler<InputMethod>(BYTECODES_ELEMENT, true) {
+
+        @Override
+        protected void end(String text) throws SAXException {
+            getParentObject().setBytecodes(text);
+        }
+    };
+    // <inlined>
+    private HandoverElementHandler<InputMethod> inlinedHandler = new XMLParser.HandoverElementHandler<>(INLINE_ELEMENT);
+    // <inlined><method>
+    private ElementHandler<InputMethod, InputMethod> inlinedMethodHandler = new XMLParser.ElementHandler<InputMethod, InputMethod>(METHOD_ELEMENT) {
+
+        @Override
+        protected InputMethod start() throws SAXException {
+            InputMethod method = parseMethod(this, getParentObject().getGroup());
+            getParentObject().addInlined(method);
+            return method;
+        }
+    };
+    // <graph>
+    private ElementHandler<InputGraph, Group> graphHandler = new XMLParser.ElementHandler<InputGraph, Group>(GRAPH_ELEMENT) {
+
+        @Override
+        protected InputGraph start() throws SAXException {
+            String name = readAttribute(GRAPH_NAME_PROPERTY);
+            InputGraph curGraph = new InputGraph(name);
+            if (differenceEncoding.get(getParentObject())) {
+                InputGraph previous = lastParsedGraph.get(getParentObject());
+                lastParsedGraph.put(getParentObject(), curGraph);
+                if (previous != null) {
+                    for (InputNode n : previous.getNodes()) {
+                        curGraph.addNode(n);
+                    }
+                    for (InputEdge e : previous.getEdges()) {
+                        curGraph.addEdge(e);
+                    }
+                }
+            }
+            return curGraph;
+        }
+
+        @Override
+        protected void end(String text) throws SAXException {
+            // NOTE: Some graphs intentionally don't provide blocks. Instead
+            //       they later generate the blocks from other information such
+            //       as node properties (example: ServerCompilerScheduler).
+            //       Thus, we shouldn't assign nodes that don't belong to any
+            //       block to some artificial block below unless blocks are
+            //       defined and nodes are assigned to them.
+
+            final InputGraph graph = getObject();
+            final Group parent = getParentObject();
+            if (graph.getBlocks().size() > 0) {
+                boolean blocksContainNodes = false;
+                for (InputBlock b : graph.getBlocks()) {
+                    if (b.getNodes().size() > 0) {
+                        blocksContainNodes = true;
+                        break;
+                    }
+                }
+
+                if (!blocksContainNodes) {
+                    graph.clearBlocks();
+                    blockConnections.clear();
+                } else {
+                    // Blocks and their nodes defined: add other nodes to an
+                    //  artificial "no block" block
+                    InputBlock noBlock = null;
+                    for (InputNode n : graph.getNodes()) {
+                        if (graph.getBlock(n) == null) {
+                            if (noBlock == null) {
+                                noBlock = graph.addBlock("(no block)");
+                            }
+
+                            noBlock.addNode(n.getId());
+                        }
+
+                        assert graph.getBlock(n) != null;
+                    }
+                }
+            }
+
+            // Resolve block successors
+            for (Pair<String, String> p : blockConnections) {
+                final InputBlock left = graph.getBlock(p.getLeft());
+                assert left != null;
+                final InputBlock right = graph.getBlock(p.getRight());
+                assert right != null;
+                graph.addBlockEdge(left, right);
+            }
+            blockConnections.clear();
+
+            SwingUtilities.invokeLater(new Runnable(){
+
+                @Override
+                public void run() {
+                    // Add to group
+                    parent.addElement(graph);
+                }
+            });
+        }
+    };
+    // <nodes>
+    private HandoverElementHandler<InputGraph> nodesHandler = new HandoverElementHandler<>(NODES_ELEMENT);
+    // <controlFlow>
+    private HandoverElementHandler<InputGraph> controlFlowHandler = new HandoverElementHandler<>(CONTROL_FLOW_ELEMENT);
+    // <block>
+    private ElementHandler<InputBlock, InputGraph> blockHandler = new ElementHandler<InputBlock, InputGraph>(BLOCK_ELEMENT) {
+
+        @Override
+        protected InputBlock start() throws SAXException {
+            InputGraph graph = getParentObject();
+            String name = readRequiredAttribute(BLOCK_NAME_PROPERTY);
+            InputBlock b = graph.addBlock(name);
+            for (InputNode n : b.getNodes()) {
+                assert graph.getBlock(n).equals(b);
+            }
+            return b;
+        }
+    };
+    // <nodes>
+    private HandoverElementHandler<InputBlock> blockNodesHandler = new HandoverElementHandler<>(NODES_ELEMENT);
+    // <node>
+    private ElementHandler<InputBlock, InputBlock> blockNodeHandler = new ElementHandler<InputBlock, InputBlock>(NODE_ELEMENT) {
+
+        @Override
+        protected InputBlock start() throws SAXException {
+            String s = readRequiredAttribute(NODE_ID_PROPERTY);
+
+            int id = 0;
+            try {
+                id = lookupID(s);
+            } catch (NumberFormatException e) {
+                throw new SAXException(e);
+            }
+            getParentObject().addNode(id);
+            return getParentObject();
+        }
+    };
+    // <successors>
+    private HandoverElementHandler<InputBlock> successorsHandler = new HandoverElementHandler<>(SUCCESSORS_ELEMENT);
+    // <successor>
+    private ElementHandler<InputBlock, InputBlock> successorHandler = new ElementHandler<InputBlock, InputBlock>(SUCCESSOR_ELEMENT) {
+
+        @Override
+        protected InputBlock start() throws SAXException {
+            String name = readRequiredAttribute(BLOCK_NAME_PROPERTY);
+            blockConnections.add(new Pair<>(getParentObject().getName(), name));
+            return getParentObject();
+        }
+    };
+    // <node>
+    private ElementHandler<InputNode, InputGraph> nodeHandler = new ElementHandler<InputNode, InputGraph>(NODE_ELEMENT) {
+
+        @Override
+        protected InputNode start() throws SAXException {
+            String s = readRequiredAttribute(NODE_ID_PROPERTY);
+            int id = 0;
+            try {
+                id = lookupID(s);
+            } catch (NumberFormatException e) {
+                throw new SAXException(e);
+            }
+            InputNode node = new InputNode(id);
+            getParentObject().addNode(node);
+            return node;
+        }
+    };
+    // <removeNode>
+    private ElementHandler<InputNode, InputGraph> removeNodeHandler = new ElementHandler<InputNode, InputGraph>(REMOVE_NODE_ELEMENT) {
+
+        @Override
+        protected InputNode start() throws SAXException {
+            String s = readRequiredAttribute(NODE_ID_PROPERTY);
+            int id = 0;
+            try {
+                id = lookupID(s);
+            } catch (NumberFormatException e) {
+                throw new SAXException(e);
+            }
+            return getParentObject().removeNode(id);
+        }
+    };
+    // <graph>
+    private HandoverElementHandler<InputGraph> edgesHandler = new HandoverElementHandler<>(EDGES_ELEMENT);
+
+    // Local class for edge elements
+    private class EdgeElementHandler extends ElementHandler<InputEdge, InputGraph> {
+
+        public EdgeElementHandler(String name) {
+            super(name);
+        }
+
+        @Override
+        protected InputEdge start() throws SAXException {
+            int fromIndex = 0;
+            int toIndex = 0;
+            int from = -1;
+            int to = -1;
+            String label = null;
+
+            try {
+                String fromIndexString = readAttribute(FROM_INDEX_PROPERTY);
+                if (fromIndexString != null) {
+                    fromIndex = Integer.parseInt(fromIndexString);
+                }
+
+                String toIndexString = readAttribute(TO_INDEX_PROPERTY);
+                if (toIndexString == null) {
+                    toIndexString = readAttribute(TO_INDEX_ALT_PROPERTY);
+                }
+                if (toIndexString != null) {
+                    toIndex = Integer.parseInt(toIndexString);
+                }
+
+                label = readAttribute(LABEL_PROPERTY);
+
+                from = lookupID(readRequiredAttribute(FROM_PROPERTY));
+                to = lookupID(readRequiredAttribute(TO_PROPERTY));
+            } catch (NumberFormatException e) {
+                throw new SAXException(e);
+            }
+
+            InputEdge conn = new InputEdge((char) fromIndex, (char) toIndex, from, to, label);
+            return start(conn);
+        }
+
+        protected InputEdge start(InputEdge conn) throws SAXException {
+            return conn;
+        }
+    }
+    // <edge>
+    private EdgeElementHandler edgeHandler = new EdgeElementHandler(EDGE_ELEMENT) {
+
+        @Override
+        protected InputEdge start(InputEdge conn) throws SAXException {
+            getParentObject().addEdge(conn);
+            return conn;
+        }
+    };
+    // <removeEdge>
+    private EdgeElementHandler removeEdgeHandler = new EdgeElementHandler(REMOVE_EDGE_ELEMENT) {
+
+        @Override
+        protected InputEdge start(InputEdge conn) throws SAXException {
+            getParentObject().removeEdge(conn);
+            return conn;
+        }
+    };
+    // <properties>
+    private HandoverElementHandler<Properties.Provider> propertiesHandler = new HandoverElementHandler<>(PROPERTIES_ELEMENT);
+    // <properties>
+    private HandoverElementHandler<Group> groupPropertiesHandler = new HandoverElementHandler<Group>(PROPERTIES_ELEMENT) {
+
+        @Override
+        public void end(String text) throws SAXException {
+            if (groupCallback != null && getParentObject().getParent() instanceof GraphDocument) {
+                final Group group = getParentObject();
+                SwingUtilities.invokeLater(new Runnable() {
+                    @Override
+                    public void run() {
+                        groupCallback.started(group);
+                    }
+                });
+            }
+        }
+    };
+    // <property>
+    private ElementHandler<String, Properties.Provider> propertyHandler = new XMLParser.ElementHandler<String, Properties.Provider>(PROPERTY_ELEMENT, true) {
+
+        @Override
+        public String start() throws SAXException {
+            return readRequiredAttribute(PROPERTY_NAME_PROPERTY);
+         }
+
+        @Override
+        public void end(String text) {
+            getParentObject().getProperties().setProperty(getObject(), text.trim());
+        }
+    };
+
+    public Parser() {
+        this(null);
+    }
+
+    public Parser(GroupCallback groupCallback) {
+
+        this.groupCallback = groupCallback;
+
+        // Initialize dependencies
+        xmlDocument.addChild(topHandler);
+        topHandler.addChild(groupHandler);
+
+        groupHandler.addChild(methodHandler);
+        groupHandler.addChild(graphHandler);
+        groupHandler.addChild(groupHandler);
+
+        methodHandler.addChild(inlinedHandler);
+        methodHandler.addChild(bytecodesHandler);
+
+        inlinedHandler.addChild(inlinedMethodHandler);
+        inlinedMethodHandler.addChild(bytecodesHandler);
+        inlinedMethodHandler.addChild(inlinedHandler);
+
+        graphHandler.addChild(nodesHandler);
+        graphHandler.addChild(edgesHandler);
+        graphHandler.addChild(controlFlowHandler);
+
+        controlFlowHandler.addChild(blockHandler);
+
+        blockHandler.addChild(successorsHandler);
+        successorsHandler.addChild(successorHandler);
+        blockHandler.addChild(blockNodesHandler);
+        blockNodesHandler.addChild(blockNodeHandler);
+
+        nodesHandler.addChild(nodeHandler);
+        nodesHandler.addChild(removeNodeHandler);
+        edgesHandler.addChild(edgeHandler);
+        edgesHandler.addChild(removeEdgeHandler);
+
+        methodHandler.addChild(propertiesHandler);
+        inlinedMethodHandler.addChild(propertiesHandler);
+        topHandler.addChild(propertiesHandler);
+        groupHandler.addChild(groupPropertiesHandler);
+        graphHandler.addChild(propertiesHandler);
+        nodeHandler.addChild(propertiesHandler);
+        propertiesHandler.addChild(propertyHandler);
+        groupPropertiesHandler.addChild(propertyHandler);
+    }
+
+    // Returns a new GraphDocument object deserialized from an XML input source.
+    public GraphDocument parse(InputSource source, XMLParser.ParseMonitor monitor) throws SAXException {
+        XMLReader reader = createReader();
+
+        reader.setContentHandler(new XMLParser(xmlDocument, monitor));
+        try {
+            reader.parse(source);
+        } catch (IOException ex) {
+            throw new SAXException(ex);
+        }
+
+        return graphDocument;
+    }
+
+    private XMLReader createReader() throws SAXException {
+        try {
+            SAXParserFactory pfactory = SAXParserFactory.newInstance();
+            pfactory.setValidating(false);
+            pfactory.setNamespaceAware(true);
+
+            // Enable schema validation
+            SchemaFactory sfactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
+            InputStream stream = Parser.class.getResourceAsStream("graphdocument.xsd");
+            pfactory.setSchema(sfactory.newSchema(new Source[]{new StreamSource(stream)}));
+
+            return pfactory.newSAXParser().getXMLReader();
+        } catch (ParserConfigurationException ex) {
+            throw new SAXException(ex);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/serialization/Printer.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data.serialization;
+
+import com.sun.hotspot.igv.data.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Printer {
+
+    private InputStream in;
+
+    public Printer() {
+        this(null);
+    }
+
+    public Printer(InputStream inputStream) {
+        this.in = inputStream;
+    }
+
+    public void export(Writer writer, GraphDocument document) {
+
+        XMLWriter xmlWriter = new XMLWriter(writer);
+
+        try {
+            export(xmlWriter, document);
+        } catch (IOException ex) {
+        }
+    }
+
+    private void export(XMLWriter xmlWriter, GraphDocument document) throws IOException {
+        xmlWriter.startTag(Parser.ROOT_ELEMENT);
+        xmlWriter.writeProperties(document.getProperties());
+        for (FolderElement e : document.getElements()) {
+            if (e instanceof Group) {
+                export(xmlWriter, (Group) e);
+            } else if (e instanceof InputGraph) {
+                export(xmlWriter, (InputGraph)e, null, false);
+            }
+        }
+
+        xmlWriter.endTag();
+        xmlWriter.flush();
+    }
+
+    private void export(XMLWriter writer, Group g) throws IOException {
+        Properties attributes = new Properties();
+        attributes.setProperty("difference", Boolean.toString(true));
+        writer.startTag(Parser.GROUP_ELEMENT, attributes);
+        writer.writeProperties(g.getProperties());
+
+        boolean shouldExport = true;
+        if (in != null) {
+            char c = (char) in.read();
+            if (c != 'y') {
+                shouldExport = false;
+            }
+        }
+
+        if (shouldExport) {
+            if (g.getMethod() != null) {
+                export(writer, g.getMethod());
+            }
+
+            InputGraph previous = null;
+            for (FolderElement e : g.getElements()) {
+                if (e instanceof InputGraph) {
+                    InputGraph graph = (InputGraph) e;
+                    export(writer, graph, previous, true);
+                    previous = graph;
+                } else if (e instanceof Group) {
+                    export(writer, (Group) e);
+                }
+            }
+        }
+
+        writer.endTag();
+    }
+
+    public void export(XMLWriter writer, InputGraph graph, InputGraph previous, boolean difference) throws IOException {
+
+        writer.startTag(Parser.GRAPH_ELEMENT);
+        writer.writeProperties(graph.getProperties());
+        writer.startTag(Parser.NODES_ELEMENT);
+
+        Set<InputNode> removed = new HashSet<>();
+        Set<InputNode> equal = new HashSet<>();
+
+        if (previous != null) {
+            for (InputNode n : previous.getNodes()) {
+                int id = n.getId();
+                InputNode n2 = graph.getNode(id);
+                if (n2 == null) {
+                    removed.add(n);
+                } else if (n.equals(n2)) {
+                    equal.add(n);
+                }
+            }
+        }
+
+        if (difference) {
+            for (InputNode n : removed) {
+                writer.simpleTag(Parser.REMOVE_NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, Integer.toString(n.getId())));
+            }
+        }
+
+        for (InputNode n : graph.getNodes()) {
+            if (!difference || !equal.contains(n)) {
+                writer.startTag(Parser.NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, Integer.toString(n.getId())));
+                writer.writeProperties(n.getProperties());
+                writer.endTag();
+            }
+        }
+
+        writer.endTag();
+
+        writer.startTag(Parser.EDGES_ELEMENT);
+        Set<InputEdge> removedEdges = new HashSet<>();
+        Set<InputEdge> equalEdges = new HashSet<>();
+
+        if (previous != null) {
+            for (InputEdge e : previous.getEdges()) {
+                if (graph.getEdges().contains(e)) {
+                    equalEdges.add(e);
+                } else {
+                    removedEdges.add(e);
+                }
+            }
+        }
+
+        if (difference) {
+            for (InputEdge e : removedEdges) {
+                writer.simpleTag(Parser.REMOVE_EDGE_ELEMENT, createProperties(e));
+            }
+        }
+
+        for (InputEdge e : graph.getEdges()) {
+            if (!difference || !equalEdges.contains(e)) {
+                if (!equalEdges.contains(e)) {
+                    writer.simpleTag(Parser.EDGE_ELEMENT, createProperties(e));
+                }
+            }
+        }
+
+        writer.endTag();
+
+        writer.startTag(Parser.CONTROL_FLOW_ELEMENT);
+        for (InputBlock b : graph.getBlocks()) {
+            writer.startTag(Parser.BLOCK_ELEMENT, new Properties(Parser.BLOCK_NAME_PROPERTY, b.getName()));
+            
+            if (b.getSuccessors().size() > 0) {
+                writer.startTag(Parser.SUCCESSORS_ELEMENT);
+                for (InputBlock s : b.getSuccessors()) {
+                    writer.simpleTag(Parser.SUCCESSOR_ELEMENT, new Properties(Parser.BLOCK_NAME_PROPERTY, s.getName()));
+                }
+                writer.endTag();
+            }
+
+            if (b.getNodes().size() > 0) {
+            writer.startTag(Parser.NODES_ELEMENT);
+                for (InputNode n : b.getNodes()) {
+                    writer.simpleTag(Parser.NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, n.getId() + ""));
+                }
+                writer.endTag();
+            }
+            
+            writer.endTag();
+        }
+
+        writer.endTag();
+        writer.endTag();
+    }
+
+    private void export(XMLWriter w, InputMethod method) throws IOException {
+
+        w.startTag(Parser.METHOD_ELEMENT, new Properties(Parser.METHOD_BCI_PROPERTY, method.getBci() + "", Parser.METHOD_NAME_PROPERTY, method.getName(), Parser.METHOD_SHORT_NAME_PROPERTY, method.getShortName()));
+
+        w.writeProperties(method.getProperties());
+
+        if (method.getInlined().size() > 0) {
+            w.startTag(Parser.INLINE_ELEMENT);
+            for (InputMethod m : method.getInlined()) {
+                export(w, m);
+            }
+            w.endTag();
+        }
+
+        w.startTag(Parser.BYTECODES_ELEMENT);
+
+        StringBuilder b = new StringBuilder();
+        b.append("<![CDATA[\n");
+        for (InputBytecode code : method.getBytecodes()) {
+            b.append(code.getBci());
+            b.append(" ");
+            b.append(code.getName());
+            b.append("\n");
+        }
+        
+        b.append("]]>");
+        w.write(b.toString());
+        w.endTag();
+        w.endTag();
+    }
+
+    private Properties createProperties(InputEdge edge) {
+        Properties p = new Properties();
+        if (edge.getToIndex() != 0) {
+            p.setProperty(Parser.TO_INDEX_PROPERTY, Integer.toString(edge.getToIndex()));
+        }
+        if (edge.getFromIndex() != 0) {
+            p.setProperty(Parser.FROM_INDEX_PROPERTY, Integer.toString(edge.getFromIndex()));
+        }
+        p.setProperty(Parser.TO_PROPERTY, Integer.toString(edge.getTo()));
+        p.setProperty(Parser.FROM_PROPERTY, Integer.toString(edge.getFrom()));
+        return p;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLParser.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data.serialization;
+
+import com.sun.hotspot.igv.data.Properties;
+import java.util.HashMap;
+import java.util.Stack;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class XMLParser implements ContentHandler {
+
+    public static interface ParseMonitor {
+
+        public void setProgress(double d);
+
+        public void setState(String state);
+    }
+
+    public static class MissingAttributeException extends SAXException {
+
+        private String name;
+
+        public MissingAttributeException(String name) {
+            super("Missing attribute \"" + name + "\"");
+            this.name = name;
+        }
+
+        public String getAttributeName() {
+            return this.getMessage();
+        }
+    }
+
+    public static class HandoverElementHandler<P> extends ElementHandler<P, P> {
+
+        @Override
+        protected P start() throws SAXException {
+            return getParentObject();
+        }
+
+        public HandoverElementHandler(String name) {
+            super(name);
+        }
+
+        public HandoverElementHandler(String name, boolean needsText) {
+            super(name, needsText);
+        }
+    }
+
+    public static class TopElementHandler<P> extends ElementHandler<P, Object> {
+
+        public TopElementHandler() {
+            super(null);
+        }
+    }
+
+    public static class ElementHandler<T, P> {
+
+        private String name;
+        private Stack<T> object = new Stack<>();
+        private Attributes attr;
+        private StringBuilder currentText;
+        private ParseMonitor monitor;
+        private HashMap<String, ElementHandler<?, ? super T>> hashtable;
+        private boolean needsText;
+        private Stack<ElementHandler<P, ?>> parentElement = new Stack<>();
+        private Stack<P> parentObject = new Stack<>();
+
+        public ElementHandler(String name) {
+            this(name, false);
+        }
+
+        public ElementHandler<P, ?> getParentElement() {
+            return parentElement.peek();
+        }
+
+        public P getParentObject() {
+            return parentObject.peek();
+        }
+
+        protected boolean needsText() {
+            return needsText;
+        }
+
+        public ElementHandler(String name, boolean needsText) {
+            this.hashtable = new HashMap<>();
+            this.name = name;
+            this.needsText = needsText;
+        }
+
+        public ParseMonitor getMonitor() {
+            return monitor;
+        }
+
+        public ElementHandler<?, ? super T> getChild(String name) {
+            return hashtable.get(name);
+        }
+
+        public void addChild(ElementHandler<?, ? super T> handler) {
+            assert handler != null;
+            hashtable.put(handler.getName(), handler);
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public T getObject() {
+            return object.size() == 0 ? null : object.peek();
+        }
+
+        public String readAttribute(String name) {
+            return attr.getValue(name);
+        }
+
+        public String readRequiredAttribute(String name) throws SAXException {
+            String s = readAttribute(name);
+            if (s == null) {
+                throw new MissingAttributeException(name);
+            }
+            return s;
+        }
+
+        public void processAttributesAsProperties(Properties p) {
+            int length = attr.getLength();
+            for (int i = 0; i < length; i++) {
+                String val = attr.getValue(i);
+                String localName = attr.getLocalName(i);
+                p.setProperty(val, localName);
+            }
+        }
+
+        public void startElement(ElementHandler<P, ?> parentElement, Attributes attr, ParseMonitor monitor) throws SAXException {
+            this.currentText = new StringBuilder();
+            this.attr = attr;
+            this.monitor = monitor;
+            this.parentElement.push(parentElement);
+            parentObject.push(parentElement.getObject());
+            object.push(start());
+        }
+
+        protected T start() throws SAXException {
+            return null;
+        }
+
+        protected void end(String text) throws SAXException {
+
+        }
+
+        public void endElement() throws SAXException {
+            end(currentText.toString());
+            object.pop();
+            parentElement.pop();
+            parentObject.pop();
+        }
+
+        protected void text(char[] c, int start, int length) {
+            assert currentText != null;
+            currentText.append(c, start, length);
+        }
+    }
+    private Stack<ElementHandler> stack;
+    private ParseMonitor monitor;
+
+    public XMLParser(TopElementHandler rootHandler, ParseMonitor monitor) {
+        this.stack = new Stack<>();
+        this.monitor = monitor;
+        this.stack.push(rootHandler);
+    }
+
+    @Override
+    public void setDocumentLocator(Locator locator) {
+        if (monitor != null) {
+            monitor.setState("Starting parsing");
+        }
+    }
+
+    @Override
+    public void startDocument() throws SAXException {
+    }
+
+    @Override
+    public void endDocument() throws SAXException {
+    }
+
+    @Override
+    public void startPrefixMapping(String prefix, String uri) throws SAXException {
+    }
+
+    @Override
+    public void endPrefixMapping(String prefix) throws SAXException {
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+        assert !stack.isEmpty();
+
+        ElementHandler parent = stack.peek();
+        if (parent != null) {
+            ElementHandler child = parent.getChild(qName);
+            if (child != null) {
+                child.startElement(parent, atts, monitor);
+                stack.push(child);
+                return;
+            }
+        }
+
+        stack.push(null);
+    }
+
+    @Override
+    public void endElement(String uri, String localName, String qName) throws SAXException {
+        ElementHandler handler = stack.pop();
+        if (handler != null) {
+            handler.endElement();
+        }
+    }
+
+    @Override
+    public void characters(char[] ch, int start, int length) throws SAXException {
+
+        assert !stack.isEmpty();
+
+
+        ElementHandler top = stack.peek();
+        if (top != null && top.needsText()) {
+            top.text(ch, start, length);
+        }
+    }
+
+    @Override
+    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
+    }
+
+    @Override
+    public void processingInstruction(String target, String data) throws SAXException {
+    }
+
+    @Override
+    public void skippedEntity(String name) throws SAXException {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLWriter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 1998, 2008, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.data.serialization;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Property;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Stack;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class XMLWriter extends Writer {
+
+    private Writer inner;
+    private Stack<String> elementStack;
+
+    public XMLWriter(Writer inner) {
+        this.inner = inner;
+        elementStack = new Stack<>();
+    }
+
+    @Override
+    public void write(char[] arr) throws IOException {
+        write(arr, 0, arr.length);
+    }
+
+    @Override
+    public void write(char[] cbuf, int off, int len) throws IOException {
+        for (int i = off; i < off + len; i++) {
+            char c = cbuf[i];
+            if (c == '>') {
+                inner.write("&gt;");
+            } else if (c == '<') {
+                inner.write("&lt;");
+            } else if (c == '&') {
+                inner.write("&amp;");
+            } else {
+                inner.write(c);
+            }
+        }
+    }
+
+    @Override
+    public void flush() throws IOException {
+        inner.flush();
+    }
+
+    @Override
+    public void close() throws IOException {
+        inner.close();
+    }
+
+    public void endTag() throws IOException {
+        inner.write("</" + elementStack.pop() + ">\n");
+    }
+
+    public void startTag(String name) throws IOException {
+        inner.write("<" + name + ">\n");
+        elementStack.push(name);
+    }
+
+    public void simpleTag(String name) throws IOException {
+        inner.write("<" + name + "/>\n");
+    }
+
+    public void startTag(String name, Properties attributes) throws IOException {
+        inner.write("<" + name);
+        elementStack.push(name);
+
+        for (Property p : attributes) {
+            inner.write(" " + p.getName() + "=\"");
+            write(p.getValue().toCharArray());
+            inner.write("\"");
+        }
+
+        inner.write(">\n");
+    }
+
+    public void simpleTag(String name, Properties attributes) throws IOException {
+        inner.write("<" + name);
+
+        for (Property p : attributes) {
+            inner.write(" " + p.getName() + "=\"");
+            write(p.getValue().toCharArray());
+            inner.write("\"");
+        }
+
+        inner.write("/>\n");
+    }
+
+    public void writeProperties(Properties props) throws IOException {
+        if (props.iterator().hasNext() == false) {
+            return;
+        }
+
+        startTag(Parser.PROPERTIES_ELEMENT);
+
+        for (Property p : props) {
+            startTag(Parser.PROPERTY_ELEMENT, new Properties(Parser.PROPERTY_NAME_PROPERTY, p.getName()));
+            this.write(p.getValue().toCharArray());
+            endTag();
+        }
+
+        endTag();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/serialization/graphdocument.xsd	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+    
+    <xsd:element name="graphDocument">
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element name="properties" type="propertiesType" minOccurs="0" maxOccurs="1" />
+                <xsd:element name="group" type="groupType" minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+        </xsd:complexType>
+    </xsd:element>
+
+    <xsd:complexType name="groupType">
+        <xsd:sequence>
+            <xsd:element name="properties" type="propertiesType" minOccurs="0" maxOccurs="1" />
+            <xsd:element name="assembly" type="assemblyType" minOccurs="0" maxOccurs="1" />
+            <xsd:element name="method" type="methodType" minOccurs="0" maxOccurs="1" />
+            <xsd:element name="graph" type="graphType" minOccurs="0" maxOccurs="unbounded" />
+        </xsd:sequence>
+        <xsd:attribute name="difference" use="optional" />
+    </xsd:complexType>
+    
+    <xsd:complexType name="propertiesType">
+        <xsd:sequence>
+            <xsd:element name="p" minOccurs="0" maxOccurs="unbounded">
+                <xsd:complexType>
+                    <xsd:simpleContent>
+                        <xsd:extension base="xsd:string">
+                            <xsd:attribute name="name" use="required" />
+                        </xsd:extension>
+                    </xsd:simpleContent>
+                </xsd:complexType>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    
+    <xsd:simpleType name="assemblyType">
+        <xsd:restriction base="xsd:string" />
+    </xsd:simpleType>
+    
+    <xsd:complexType name="methodType">
+        <xsd:all>
+            <xsd:element name="properties" type="propertiesType" minOccurs="0" maxOccurs="1" />
+            <xsd:element name="bytecodes" minOccurs="0" maxOccurs="1">
+                <xsd:simpleType>
+                    <xsd:restriction base="xsd:string" />
+                </xsd:simpleType>
+            </xsd:element>
+            <xsd:element name="inlined" minOccurs="0" maxOccurs="1">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="method" type="methodType" minOccurs="0" maxOccurs="unbounded" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+        </xsd:all>
+        <xsd:attribute name="bci" type="xsd:int" use="required" />
+        <xsd:attribute name="shortName" type="xsd:string" use="required" />
+        <xsd:attribute name="name" type="xsd:string" use="required" />
+    </xsd:complexType>
+    
+    <xsd:complexType name="graphType">
+        <xsd:sequence>
+            <xsd:element name="properties" type="propertiesType" minOccurs="0" maxOccurs="1" />
+            
+            <xsd:element name="nodes" minOccurs="0" maxOccurs="1">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:choice minOccurs="0" maxOccurs="unbounded">
+                            <xsd:element name="node" type="nodeType" />
+                            <xsd:element name="removeNode" type="nodeRefType" />
+                        </xsd:choice>
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            
+            <xsd:element name="edges" minOccurs="0" maxOccurs="1">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:choice minOccurs="0" maxOccurs="unbounded">
+                            <xsd:element name="edge" type="edgeType" />
+                            <xsd:element name="removeEdge" type="edgeType" />
+                        </xsd:choice>
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            
+            <xsd:element name="controlFlow" type="controlFlowType" minOccurs="0" maxOccurs="1" />
+        </xsd:sequence>
+        
+        <xsd:attribute name="name" use="optional" />
+    </xsd:complexType>
+    
+    <xsd:complexType name="nodeType">
+        <xsd:sequence>
+            <xsd:element name="properties" type="propertiesType" minOccurs="0" maxOccurs="1" />
+        </xsd:sequence>
+        <xsd:attribute name="id" type="xsd:int" use="required" />
+    </xsd:complexType>
+    
+    <xsd:complexType name="nodeRefType">
+        <xsd:attribute name="id" type="xsd:int" use="required" />
+    </xsd:complexType>
+    
+    <xsd:complexType name="edgeType">
+        <xsd:attribute name="from" type="xsd:int" use="required" />
+        <xsd:attribute name="to" type="xsd:int" use="required" />
+        <xsd:attribute name="label" type="xsd:string" use="optional" />
+        <xsd:attribute name="fromIndex" type="xsd:int" use="optional" />
+        
+        <!-- These are aliases and should be mutually exclusive -->
+        <xsd:attribute name="toIndex" type="xsd:int" use="optional" />
+        <xsd:attribute name="index" type="xsd:int" use="optional" />
+    </xsd:complexType>
+    
+    <xsd:complexType name="controlFlowType">
+        <xsd:sequence>
+            <xsd:element name="block" type="blockType" minOccurs="0" maxOccurs="unbounded" />
+        </xsd:sequence>
+    </xsd:complexType>
+    
+    <xsd:complexType name="blockType">
+        <xsd:all>
+            <xsd:element name="successors" minOccurs="0" maxOccurs="1">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="successor" minOccurs="0" maxOccurs="unbounded">
+                            <xsd:complexType>
+                                <xsd:attribute name="name" type="xsd:string" use="required" />
+                            </xsd:complexType>
+                        </xsd:element>
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="nodes" minOccurs="0" maxOccurs="1">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="node" type="nodeRefType" minOccurs="0" maxOccurs="unbounded" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>    
+        </xsd:all>
+        
+        <xsd:attribute name="name" type="xsd:string" use="required" />
+    </xsd:complexType>
+</xsd:schema>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/services/GraphViewer.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data.services;
+
+import com.sun.hotspot.igv.data.InputGraph;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface GraphViewer {
+
+    public void view(InputGraph graph);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/services/GroupCallback.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 1998, 2007, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.data.services;
+
+import com.sun.hotspot.igv.data.Group;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface GroupCallback {
+
+    public void started(Group g);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/services/InputGraphProvider.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 1998, 2007, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.data.services;
+
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.InputNode;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface InputGraphProvider {
+
+    InputGraph getGraph();
+
+    void setSelectedNodes(Set<InputNode> nodes);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/src/com/sun/hotspot/igv/data/services/Scheduler.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1998, 2007, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.data.services;
+
+import com.sun.hotspot.igv.data.InputBlock;
+import com.sun.hotspot.igv.data.InputGraph;
+import java.util.Collection;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface Scheduler {
+
+    public Collection<InputBlock> schedule(InputGraph graph);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/test/unit/src/com/sun/hotspot/igv/data/ChangedEventTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ChangedEventTest {
+
+    public ChangedEventTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of addListener method, of class Event.
+     */
+    @Test
+    public void testBase() {
+
+        ChangedEvent<Integer> e = new ChangedEvent<>(5);
+        final int[] fireCount = new int[1];
+
+        e.addListener(new ChangedListener<Integer>() {
+            @Override
+            public void changed(Integer s) {
+                assertEquals(s.intValue(), 5);
+                fireCount[0]++;
+            }
+        });
+
+        e.fire();
+        assertEquals(1, fireCount[0]);
+
+        e.fire();
+        assertEquals(2, fireCount[0]);
+
+        e.beginAtomic();
+
+        e.fire();
+        assertEquals(2, fireCount[0]);
+
+        e.fire();
+        assertEquals(2, fireCount[0]);
+
+        e.fire();
+        assertEquals(2, fireCount[0]);
+
+        e.endAtomic();
+        assertEquals(3, fireCount[0]);
+
+    }
+
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/test/unit/src/com/sun/hotspot/igv/data/ControllableChangedListenerTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import static org.junit.Assert.*;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ControllableChangedListenerTest {
+
+    public ControllableChangedListenerTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of isEnabled method, of class ControllableChangedListener.
+     */
+    @Test
+    public void testBase() {
+
+        final boolean[] hasFired = new boolean[1];
+        final boolean[] shouldFire = new boolean[1];
+        final Integer[] valueToFire = new Integer[1];
+        ControllableChangedListener<Integer> l = new ControllableChangedListener<Integer>() {
+
+            @Override
+            public void filteredChanged(Integer value) {
+                assertTrue(shouldFire[0]);
+                assertEquals(valueToFire[0], value);
+                hasFired[0] = true;
+            }
+        };
+
+        shouldFire[0] = true;
+        valueToFire[0] = 1;
+        hasFired[0] = false;
+        l.changed(1);
+        assertTrue(hasFired[0]);
+
+        shouldFire[0] = false;
+        hasFired[0] = false;
+        l.setEnabled(false);
+        l.changed(1);
+        assertFalse(hasFired[0]);
+
+        shouldFire[0] = true;
+        valueToFire[0] = 1;
+        hasFired[0] = false;
+        l.setEnabled(true);
+        l.changed(1);
+        assertTrue(hasFired[0]);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/test/unit/src/com/sun/hotspot/igv/data/GroupTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import static org.junit.Assert.assertEquals;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class GroupTest {
+
+    public GroupTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getAllNodes method, of class Group.
+     */
+    @Test
+    public void testGetAllNodes() {
+        final Group g = new Group(null);
+        final InputGraph graph1 = new InputGraph("1");
+        final InputGraph graph2 = new InputGraph("2");
+        g.addElement(graph1);
+        g.addElement(graph2);
+        graph1.addNode(new InputNode(1));
+        graph1.addNode(new InputNode(2));
+        graph2.addNode(new InputNode(2));
+        graph2.addNode(new InputNode(3));
+        assertEquals(g.getAllNodes(), new HashSet(Arrays.asList(1, 2, 3)));
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/test/unit/src/com/sun/hotspot/igv/data/InputGraphTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.data;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputGraphTest {
+
+    /**
+     *    1
+     *   / \
+     *  2   3
+     *   \  |  5
+     *    \ | /
+     *      4
+     */
+    private static InputGraph referenceGraph;
+
+    private static InputGraph emptyGraph;
+
+    private static final InputNode N1 = new InputNode(1);
+    private static final InputNode N2 = new InputNode(2);
+    private static final InputNode N3 = new InputNode(3);
+    private static final InputNode N4 = new InputNode(4);
+    private static final InputNode N5 = new InputNode(5);
+    private static final InputEdge E12 = new InputEdge((char)0, 1, 2);
+    private static final InputEdge E13 = new InputEdge((char)0, 1, 3);
+    private static final InputEdge E24 = new InputEdge((char)0, 2, 4);
+    private static final InputEdge E34 = new InputEdge((char)0, 3, 4);
+    private static final InputEdge E54 = new InputEdge((char)0, 5, 4);
+
+    public InputGraphTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        Group group = new Group(null);
+
+        emptyGraph = new InputGraph("emptyGraph");
+        group.addElement(emptyGraph);
+        
+        referenceGraph = new InputGraph("referenceGraph");
+        group.addElement(referenceGraph);
+        referenceGraph.addNode(N1);
+        referenceGraph.addNode(N2);
+        referenceGraph.addNode(N3);
+        referenceGraph.addNode(N4);
+        referenceGraph.addNode(N5);
+
+        referenceGraph.addEdge(E12);
+        referenceGraph.addEdge(E13);
+        referenceGraph.addEdge(E24);
+        referenceGraph.addEdge(E34);
+        referenceGraph.addEdge(E54);
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of equals method, of class InputGraph.
+     */
+    @Test
+    public void testEquals() {
+
+        Group parentA = new Group(null);
+        InputGraph a = new InputGraph("graph");
+        parentA.addElement(a);
+
+        Group parentB = new Group(null);
+        InputGraph b = new InputGraph("graph");
+        parentB.addElement(b);
+
+        InputGraph c = new InputGraph("graph");
+        parentB.addElement(b);
+
+        Util.assertGraphEquals(a, b);
+        Util.assertGraphEquals(b, c);
+
+        a.addNode(new InputNode(1));
+        Util.assertGraphNotEquals(a, b);
+
+        b.addNode(new InputNode(1));
+        Util.assertGraphEquals(a, b);
+    }
+
+    /**
+     * Test of findRootNodes method, of class InputGraph.
+     */
+    @Test
+    public void testFindRootNodes() {
+        assertTrue(emptyGraph.findRootNodes().isEmpty());
+
+        List<InputNode> result = referenceGraph.findRootNodes();
+        assertTrue(result.size() == 2);
+        assertTrue(result.contains(N1));
+        assertTrue(result.contains(N5));
+    }
+
+    /**
+     * Test of findAllOutgoingEdges method, of class InputGraph.
+     */
+    @Test
+    public void testFindAllOutgoingEdges() {
+        assertTrue(emptyGraph.findAllOutgoingEdges().isEmpty());
+
+        Map<InputNode, List<InputEdge>> result = referenceGraph.findAllOutgoingEdges();
+        assertTrue(result.size() == 5);
+        assertEquals(result.get(N1), Arrays.asList(E12, E13));
+        assertEquals(result.get(N2), Arrays.asList(E24));
+        assertEquals(result.get(N3), Arrays.asList(E34));
+        assertEquals(result.get(N4), Arrays.asList());
+        assertEquals(result.get(N5), Arrays.asList(E54));
+    }
+
+    /**
+     * Test of findAllIngoingEdges method, of class InputGraph.
+     */
+    @Test
+    public void testFindAllIngoingEdges() {
+        assertTrue(emptyGraph.findAllIngoingEdges().isEmpty());
+
+        Map<InputNode, List<InputEdge>> result = referenceGraph.findAllIngoingEdges();
+        assertTrue(result.size() == 5);
+        assertEquals(result.get(N1), Arrays.asList());
+        assertEquals(result.get(N2), Arrays.asList(E12));
+        assertEquals(result.get(N3), Arrays.asList(E13));
+        assertEquals(result.get(N4), Arrays.asList(E24, E34, E54));
+        assertEquals(result.get(N5), Arrays.asList());
+    }
+
+    /**
+     * Test of findOutgoingEdges method, of class InputGraph.
+     */
+    @Test
+    public void testFindOutgoingEdges() {
+        assertTrue(emptyGraph.findOutgoingEdges(new InputNode(1)).isEmpty());
+
+        assertEquals(referenceGraph.findOutgoingEdges(N1), Arrays.asList(E12, E13));
+        assertEquals(referenceGraph.findOutgoingEdges(N2), Arrays.asList(E24));
+        assertEquals(referenceGraph.findOutgoingEdges(N3), Arrays.asList(E34));
+        assertEquals(referenceGraph.findOutgoingEdges(N4), Arrays.asList());
+        assertEquals(referenceGraph.findOutgoingEdges(N5), Arrays.asList(E54));
+    }
+
+    /**
+     * Test of getNext method, of class InputGraph.
+     */
+    @Test
+    public void testGetNextPrev() {
+        final Group group = new Group(null);
+
+        final InputGraph a = new InputGraph("a");
+
+        final InputGraph b = new InputGraph("b");
+
+        final InputGraph c = new InputGraph("c");
+        group.addElement(a);
+        group.addElement(b);
+        group.addElement(c);
+
+        assertEquals(null, a.getPrev());
+        assertEquals(b, a.getNext());
+
+        assertEquals(a, b.getPrev());
+        assertEquals(c, b.getNext());
+
+        assertEquals(b, c.getPrev());
+        assertEquals(null, c.getNext());
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/test/unit/src/com/sun/hotspot/igv/data/InputMethodTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,93 @@
+/*
+ * 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.sun.hotspot.igv.data;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas
+ */
+public class InputMethodTest {
+
+    public InputMethodTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+
+    /**
+     * Test of getBytecodes method, of class InputMethod.
+     */
+    @Test
+    public void testGetSetBytecodes() {
+
+        final String input = "0 iload_0\n" +
+                             "1 iconst_1\n" +
+                             "2 if_icmpne 7\n" +
+                             "5 iconst_1\n" +
+                             "6 ireturn\n" +
+                             "7 iconst_0\n" +
+                             "8 ireturn";
+
+        final Group g = new Group(null);
+        InputMethod m = new InputMethod(g, "name", "shortName", -1);
+        m.setBytecodes(input);
+
+        assertThat(m.getBytecodes().size(), is(7));
+
+        assertThat(m.getBytecodes().get(0).getBci(), is(0));
+        assertThat(m.getBytecodes().get(1).getBci(), is(1));
+        assertThat(m.getBytecodes().get(2).getBci(), is(2));
+        assertThat(m.getBytecodes().get(3).getBci(), is(5));
+
+        assertThat(m.getBytecodes().get(0).getName(), is("iload_0"));
+        assertThat(m.getBytecodes().get(1).getName(), is("iconst_1"));
+        assertThat(m.getBytecodes().get(2).getName(), is("if_icmpne 7"));
+        assertThat(m.getBytecodes().get(6).getName(), is("ireturn"));
+
+        assertThat(m.getBytecodes().get(2).getInlined(), nullValue());
+        assertThat(m.getBytecodes().get(6).getInlined(), nullValue());
+    }
+
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/test/unit/src/com/sun/hotspot/igv/data/PairTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1998, 2007, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.data;
+
+import static org.junit.Assert.*;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class PairTest {
+
+    public PairTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getLeft method, of class Pair.
+     */
+    @Test
+    public void testBase() {
+        Pair p = new Pair();
+        assertTrue(p.getLeft() == null);
+        assertTrue(p.getRight() == null);
+        assertEquals("[null/null]", p.toString());
+        assertFalse(p.equals(null));
+
+        Pair<Integer, Integer> p2 = new Pair(1, 2);
+        assertTrue(p2.getLeft().intValue() == 1);
+        assertTrue(p2.getRight().intValue() == 2);
+        assertFalse(p.equals(p2));
+        assertFalse(p2.equals(p));
+        assertFalse(p.hashCode() == p2.hashCode());
+        assertEquals("[1/2]", p2.toString());
+
+        Pair p3 = new Pair(1, 2);
+        assertTrue(p2.equals(p3));
+        assertTrue(p2.hashCode() == p3.hashCode());
+
+        p2.setLeft(2);
+        assertFalse(p2.equals(p3));
+        assertTrue(p2.getLeft().intValue() == 2);
+        assertTrue(p2.getRight().intValue() == 2);
+        assertFalse(p2.hashCode() == p3.hashCode());
+        assertEquals("[2/2]", p2.toString());
+
+        p2.setRight(1);
+        assertFalse(p2.equals(p3));
+        assertTrue(p2.getLeft().intValue() == 2);
+        assertTrue(p2.getRight().intValue() == 1);
+        assertFalse(p2.hashCode() == p3.hashCode());
+        assertEquals("[2/1]", p2.toString());
+
+        p3.setLeft(2);
+        p3.setRight(1);
+        assertTrue(p2.hashCode() == p3.hashCode());
+        assertTrue(p2.equals(p3));
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/test/unit/src/com/sun/hotspot/igv/data/PropertiesTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,401 @@
+/*
+ * Copyright (c) 1998, 2007, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.data;
+
+import com.sun.hotspot.igv.data.Properties.InvertPropertyMatcher;
+import com.sun.hotspot.igv.data.Properties.PropertyMatcher;
+import com.sun.hotspot.igv.data.Properties.PropertySelector;
+import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher;
+import com.sun.hotspot.igv.data.Properties.StringPropertyMatcher;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import junit.framework.TestCase;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class PropertiesTest extends TestCase {
+
+
+    
+    public PropertiesTest(String testName) {
+        super(testName);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * Test of equals method, of class Properties.
+     */
+    public void testEquals() {
+        Properties a = new Properties();
+        assertFalse(a.equals(null));
+        assertTrue(a.equals(a));
+        
+        Properties b = new Properties();
+        assertTrue(a.equals(b));
+        assertTrue(a.hashCode() == b.hashCode());
+
+        a.setProperty("p1", "1");
+        assertFalse(a.equals(b));
+        assertFalse(b.equals(a));
+        assertFalse(a.hashCode() == b.hashCode());
+
+        b.setProperty("p1", "1");
+        assertTrue(a.equals(b));
+        assertTrue(a.hashCode() == b.hashCode());
+
+        Properties c = new Properties(a);
+        assertTrue(c.equals(a));
+        assertTrue(c.equals(b));
+
+        c.setProperty("p1", "2");
+        assertFalse(c.equals(b));
+        assertFalse(c.hashCode() == b.hashCode());
+        assertFalse(c.equals(a));
+        assertFalse(c.hashCode() == a.hashCode());
+
+        a.setProperty("p2", "2");
+        Properties d = new Properties();
+        d.setProperty("p2", "2");
+        d.setProperty("p1", "1");
+        assertTrue(d.equals(a));
+    }
+
+    /**
+     * Test of selectSingle method, of class Properties.
+     */
+    public void testSelectSingle() {
+        
+        final boolean[] called = new boolean[1];
+        final String v = "2";
+        final String n = "p2";
+        
+        PropertyMatcher matcher = new PropertyMatcher() {
+
+            @Override
+            public String getName() {
+                assertFalse(called[0]);
+                called[0] = true;
+                return n;
+            }
+
+            @Override
+            public boolean match(String value) {
+                assertTrue(v.equals(value));
+                return true;
+            }
+        };
+
+        Properties instance = new Properties();
+        instance.setProperty("p1", "1");
+        instance.setProperty(n, v);
+        instance.setProperty("p3", "3");
+        Property result = instance.selectSingle(matcher);
+        assertEquals(result, new Property(n, v));
+
+
+        called[0] = false;
+        PropertyMatcher matcher2 = new PropertyMatcher() {
+
+            @Override
+            public String getName() {
+                assertFalse(called[0]);
+                called[0] = true;
+                return n;
+            }
+
+            @Override
+            public boolean match(String value) {
+                return false;
+            }
+        };
+
+
+        Property result2 = instance.selectSingle(matcher2);
+        assertTrue(result2 == null);
+    }
+
+    /**
+     * Test of get method, of class Properties.
+     */
+    public void testGet() {
+        Properties instance = new Properties();
+        instance.setProperty("p1", "1");
+        assertEquals("1", instance.get("p1"));
+        assertEquals(null, instance.get("p2"));
+    }
+
+    /**
+     * Test of getProperties method, of class Properties.
+     */
+    public void testIterator() {
+        Properties instance = new Properties();
+        instance.setProperty("p1", "1");
+        instance.setProperty("p2", "2");
+        Iterator<Property> result = instance.iterator();
+        assertTrue(result.hasNext());
+        assertEquals(new Property("p1", "1"), result.next());
+        assertTrue(result.hasNext());
+        assertEquals(new Property("p2", "2"), result.next());
+        assertFalse(result.hasNext());
+        assertTrue(result.next() == null);
+
+        try {
+            result.remove();
+            fail();
+        } catch(UnsupportedOperationException e) {}
+    }
+
+    /**
+     * Test of add method, of class Properties.
+     */
+    public void testAdd() {
+        Properties a = new Properties();
+        a.setProperty("p1", "1");
+        a.setProperty("p2", "2");
+
+        Properties b = new Properties();
+        b.setProperty("p1", "1");
+
+        Properties c = new Properties();
+        c.setProperty("p2", "2");
+
+        assertFalse(a.equals(b));
+        b.add(c);
+
+        assertTrue(a.equals(b));
+        
+        b.setProperty("p3", null);
+        assertTrue(a.equals(b));
+    
+        Properties empty = new Properties();
+        b.add(empty);
+        assertTrue(a.equals(b));
+        
+        empty.add(b);
+        assertTrue(a.equals(empty));
+    }
+
+
+    /**
+     * Test the multiple argument constructors.
+     */
+    public void testConstructors() {
+        Properties a = new Properties("p1", "1", "p2", "2", "p3", "3");
+        Properties b = new Properties("p1", "1", "p2", "2");
+        Properties c = new Properties("p1", "1");
+
+        assertTrue(a.get("p3").equals("3"));
+        assertTrue(b.get("p2").equals("2"));
+        assertTrue(b.get("p1").equals("1"));
+
+        b.setProperty("p3", "3");
+        c.setProperty("p2", "2");
+        c.setProperty("p3", "3");
+
+        assertTrue(a.equals(b));
+        assertTrue(a.equals(c));
+    }
+
+    /**
+     * Test Entity class
+     */
+    public void testEntity() {
+
+        Properties p = new Properties();
+
+        Properties.Entity entity = new Properties.Entity();
+        assertEquals(entity.getProperties(), p);
+
+        entity.getProperties().setProperty("p1", "1");
+        Properties.Entity entity2 = new Properties.Entity(entity);
+        assertEquals(entity.getProperties(), entity2.getProperties());
+    }
+
+    /**
+     * Test property selector
+     */
+    public void testPropertySelector() {
+        final Collection<Properties.Entity> c = new ArrayList<>();
+
+        final Properties.Entity e1 = new Properties.Entity();
+        e1.getProperties().setProperty("p1", "1");
+        e1.getProperties().setProperty("p2", "2");
+        c.add(e1);
+
+        final Properties.Entity e2 = new Properties.Entity();
+        e2.getProperties().setProperty("p2", "2");
+        e2.getProperties().setProperty("p1", "1");
+        e2.getProperties().setProperty("p3", "3");
+        c.add(e2);
+
+        final Properties.Entity e3 = new Properties.Entity();
+        e3.getProperties().setProperty("p3", "3");
+        e3.getProperties().setProperty("p4", "4");
+        c.add(e3);
+
+        final PropertySelector<Properties.Entity> sel = new PropertySelector<>(c);
+
+        final StringPropertyMatcher matcher1 = new StringPropertyMatcher("p2", "2");
+        assertTrue(sel.selectMultiple(matcher1).size() == 2);
+        assertTrue(sel.selectMultiple(matcher1).contains(e1));
+        assertTrue(sel.selectMultiple(matcher1).contains(e2));
+        assertTrue(sel.selectSingle(matcher1).equals(e1) || sel.selectSingle(matcher1).equals(e2));
+
+        final StringPropertyMatcher matcher2 = new StringPropertyMatcher("p3", "3");
+        assertTrue(sel.selectMultiple(matcher2).size() == 2);
+        assertTrue(sel.selectMultiple(matcher2).contains(e2));
+        assertTrue(sel.selectMultiple(matcher2).contains(e3));
+        assertTrue(sel.selectSingle(matcher2).equals(e2) || sel.selectSingle(matcher2).equals(e3));
+
+        final StringPropertyMatcher matcher3 = new StringPropertyMatcher("p4", "4");
+        assertTrue(sel.selectMultiple(matcher3).size() == 1);
+        assertTrue(sel.selectMultiple(matcher3).contains(e3));
+        assertTrue(sel.selectSingle(matcher3).equals(e3));
+
+        final StringPropertyMatcher matcher4 = new StringPropertyMatcher("p5", "5");
+        assertTrue(sel.selectMultiple(matcher4).size() == 0);
+        assertTrue(sel.selectSingle(matcher4) == null);
+    }
+
+    public void testRemoveProperty() {
+        final Properties p = new Properties();
+        p.setProperty("p1", "1");
+        p.setProperty("p2", "2");
+
+        assertTrue(p.get("p1").equals("1"));
+        assertTrue(p.get("p2").equals("2"));
+
+        p.setProperty("p1", null);
+        assertTrue(p.get("p1") == null);
+        assertTrue(p.get("p2").equals("2"));
+
+        p.setProperty("p2", null);
+        assertTrue(p.get("p1") == null);
+        assertTrue(p.get("p2") == null);
+
+        p.setProperty("p3", "3");
+        assertTrue(p.get("p1") == null);
+        assertTrue(p.get("p2") == null);
+        assertTrue(p.get("p3").equals("3"));
+    }
+
+    /**
+     * Test property matchers
+     */
+    public void testPropertyMatchers() {
+        final StringPropertyMatcher matcher = new StringPropertyMatcher("p1", "1");
+        assertTrue(matcher.getName().equals("p1"));
+        assertTrue(matcher.match("1"));
+        assertFalse(matcher.match("2"));
+        try {
+            matcher.match(null);
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new StringPropertyMatcher(null, "**");
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new StringPropertyMatcher("p1", null);
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        final RegexpPropertyMatcher matcher2 = new RegexpPropertyMatcher("p1", "C.*");
+        assertTrue(matcher2.getName().equals("p1"));
+        assertTrue(matcher2.match("C"));
+        assertTrue(matcher2.match("Casdf"));
+        assertFalse(matcher2.match(" C"));
+        assertFalse(matcher2.match("c"));
+        assertFalse(matcher2.match("asdfC"));
+        
+        try {
+            matcher2.match(null);
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new RegexpPropertyMatcher("p1", "**");
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new RegexpPropertyMatcher(null, "1");
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new RegexpPropertyMatcher("p1", null);
+            fail();
+        } catch(IllegalArgumentException e) {}
+        
+        final InvertPropertyMatcher matcher3 = new InvertPropertyMatcher(matcher);
+        assertTrue(matcher3.getName().equals("p1"));
+        assertFalse(matcher3.match("1"));
+        assertTrue(matcher3.match("2"));
+        assertFalse(matcher3.match(null));
+    }
+
+    public void testToString() {
+        Properties p = new Properties();
+        assertEquals(p.toString(), "[]");
+
+        p.setProperty("p1", "1");
+        assertEquals(p.toString(), "[p1=1]");
+
+        Properties p2 = new Properties();
+        p2.setProperty("p1", "1");
+        p2.setProperty("p2", "2");
+        assertEquals(p2.toString(), "[p1=1, p2=2]");
+
+        Properties p3 = new Properties();
+        p3.setProperty("p2", "2");
+        p3.setProperty("p1", "1");
+        assertEquals(p3.toString(), "[p1=1, p2=2]");
+        
+        p3.setProperty("p0", "0");
+        assertEquals(p3.toString(), "[p0=0, p1=1, p2=2]");
+
+        p2.setProperty("p1", null);
+        assertEquals(p2.toString(), "[p2=2]");
+
+        p2.setProperty("p2", null);
+        assertEquals(p2.toString(), "[]");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/test/unit/src/com/sun/hotspot/igv/data/PropertyTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1998, 2007, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.data;
+
+import static org.junit.Assert.*;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class PropertyTest {
+
+    public PropertyTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getName method, of class Property.
+     */
+    @Test
+    public void testGetNameAndValue() {
+        final Property p = new Property("name", "value");
+        assertEquals(p.getName(), "name");
+        assertEquals(p.getValue(), "value");
+
+        try {
+            new Property(null, "value");
+            fail();
+        } catch(IllegalArgumentException e) {
+        }
+
+
+        try {
+            new Property("name", null);
+            fail();
+        } catch(IllegalArgumentException e) {
+        }
+    }
+
+    /**
+     * Test of toString method, of class Property.
+     */
+    @Test
+    public void testToString() {
+        final Property p = new Property("name", "value");
+        assertEquals(p.toString(), "name=value");
+    }
+
+    /**
+     * Test of equals method, of class Property.
+     */
+    @Test
+    public void testEquals() {
+        final Property p = new Property("name", "value");
+        final Object o = new Object();
+        assertFalse(p.equals(o));
+        assertFalse(p.equals(null));
+        assertTrue(p.equals(p));
+
+        final Property p2 = new Property("name", "value1");
+        assertFalse(p.equals(p2));
+        assertTrue(p.hashCode() != p2.hashCode());
+
+        final Property p3 = new Property("name2", "value");
+        assertFalse(p.equals(p3));
+        assertTrue(p.hashCode() != p3.hashCode());
+        assertTrue(p2.hashCode() != p3.hashCode());
+
+        final Property p4 = new Property("name", "value");
+        assertEquals(p, p4);
+        assertEquals(p.hashCode(), p4.hashCode());
+    
+        final Property p5 = new Property("value", "name");
+        assertFalse(p.equals(p5));
+        assertTrue(p.hashCode() != p5.hashCode());
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/test/unit/src/com/sun/hotspot/igv/data/SourceTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * 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.sun.hotspot.igv.data;
+
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import static org.junit.Assert.assertEquals;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas
+ */
+public class SourceTest {
+
+    public SourceTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getSourceNodes method, of class Source.
+     */
+    @Test
+    public void testBase() {
+        final Source s = new Source();
+
+        final InputNode N1 = new InputNode(1);
+        final InputNode N2 = new InputNode(2);
+
+        s.addSourceNode(N1);
+        assertEquals(s.getSourceNodes(), Arrays.asList(N1));
+        assertEquals(s.getSourceNodesAsSet(), new LinkedHashSet<>(Arrays.asList(1)));
+
+        s.addSourceNode(N2);
+        assertEquals(s.getSourceNodes(), Arrays.asList(N1, N2));
+        assertEquals(s.getSourceNodesAsSet(), new LinkedHashSet<>(Arrays.asList(1, 2)));
+
+        s.addSourceNode(N1);
+        assertEquals(s.getSourceNodes(), Arrays.asList(N1, N2));
+        assertEquals(s.getSourceNodesAsSet(), new LinkedHashSet<>(Arrays.asList(1, 2)));
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/test/unit/src/com/sun/hotspot/igv/data/Util.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 1998, 2007, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.data;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Util {
+
+    public static void assertGraphDocumentNotEquals(GraphDocument a, GraphDocument b) {
+        try {
+            assertGraphDocumentEquals(a, b);
+        } catch(AssertionError e) {
+            return;
+        }
+
+        fail("Graphs documents are equal!");
+    }
+
+    public static void assertGraphDocumentEquals(GraphDocument a, GraphDocument b) {
+
+        if (a.getElements().size() != b.getElements().size()) {
+            fail();
+        }
+
+        int z = 0;
+        for (FolderElement e : b.getElements()) {
+
+            if (e instanceof Group) {
+                Group g = (Group) e;
+                Group thisG = (Group) a.getElements().get(z);
+                assertGroupEquals(thisG, g);
+            z++;
+            }
+        }
+    }
+
+    public static void assertGroupNotEquals(Group a, Group b) {
+        try {
+            assertGroupEquals(a, b);
+        } catch(AssertionError e) {
+            return;
+        }
+
+        fail("Groups are equal!");
+    }
+
+    public static void assertGroupEquals(Group a, Group b) {
+
+        if (a.getGraphsCount() != b.getGraphsCount()) {
+            fail();
+        }
+
+        int z = 0;
+        for (InputGraph graph : a.getGraphs()) {
+            InputGraph otherGraph = b.getGraphs().get(z);
+            assertGraphEquals(graph, otherGraph);
+            z++;
+        }
+
+        if (a.getMethod() == null || b.getMethod() == null) {
+            if (a.getMethod() != b.getMethod()) {
+                fail();
+            }
+        } else {
+            if (!a.getMethod().equals(b.getMethod())) {
+                fail();
+            }
+        }
+    }
+
+    public static void assertGraphNotEquals(InputGraph a, InputGraph b) {
+        try {
+            assertGraphEquals(a, b);
+        } catch(AssertionError e) {
+            return;
+        }
+
+        fail("Graphs are equal!");
+    }
+
+    public static void assertGraphEquals(InputGraph a, InputGraph b) {
+        
+        if(!a.getNodesAsSet().equals(b.getNodesAsSet())) {
+            fail();
+        }
+        
+        if (!a.getEdges().equals(b.getEdges())) {
+            fail();
+        }
+        
+        if (a.getBlocks().equals(b.getBlocks())) {
+            fail();
+        }
+
+        for (InputNode n : a.getNodes()) {
+            assertEquals(a.getBlock(n), b.getBlock(n));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Data/test/unit/src/com/sun/hotspot/igv/data/serialization/ParserTest.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 1998, 2007, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.data.serialization;
+
+import com.sun.hotspot.igv.data.*;
+import java.io.CharArrayWriter;
+import java.io.StringReader;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import org.junit.*;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ParserTest {
+
+    public ParserTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    private void test(GraphDocument document) {
+        final Printer printer = new Printer();
+        final CharArrayWriter writer = new CharArrayWriter();
+        printer.export(writer, document);
+        test(document, writer.toString());
+    }
+
+    private void test(GraphDocument document, String xmlString) {
+        
+        StringReader sr = new StringReader(xmlString);
+        InputSource is = new InputSource(sr);
+
+        try {
+            Parser parser = new Parser();
+            final GraphDocument parsedDocument = parser.parse(is, null);
+            Util.assertGraphDocumentEquals(document, parsedDocument);
+        } catch (SAXException ex) {
+            fail(ex.toString());
+        }
+    }
+
+    private void testBoth(GraphDocument document, String xmlString) {
+        test(document);
+        test(document, xmlString);
+    }
+
+    /**
+     * Test of graph document serialization
+     */
+    @Test
+    public void testSerialization() {
+        final GraphDocument doc = new GraphDocument();
+
+        test(doc);
+
+        final Group group1 = new Group(doc);
+        doc.addElement(group1);
+        test(doc);
+
+        final Group group2 = new Group(doc);
+        doc.addElement(group2);
+        test(doc);
+
+        final InputGraph graph = new InputGraph("");
+        group1.addElement(graph);
+        test(doc);
+
+        graph.addNode(new InputNode(0));
+        test(doc);
+
+        graph.addNode(new InputNode(1));
+        test(doc);
+
+        graph.addNode(new InputNode(2));
+        test(doc);
+
+        graph.addNode(new InputNode(3));
+        test(doc);
+
+        graph.addEdge(new InputEdge((char)0, (char)0, 0, 1));
+        test(doc);
+
+        graph.addEdge(new InputEdge((char)1, (char)1, 0, 1));
+        test(doc);
+
+        graph.addEdge(new InputEdge((char)0, (char)0, 1, 2));
+        test(doc);
+        
+        graph.addEdge(new InputEdge((char)0, (char)0, 2, 3));
+        test(doc);
+
+        group1.setMethod(new InputMethod(group1, "testMethod", "tM", 1));
+        test(doc);
+
+        final InputBlock b1 = graph.addBlock("1");
+        b1.addNode(0);
+        b1.addNode(1);
+
+        final InputBlock b2 = graph.addBlock("2");
+        b2.addNode(2);
+        b2.addNode(3);
+        test(doc);
+
+        final GraphDocument document2 = new GraphDocument();
+        doc.addGraphDocument(document2);
+        test(doc);
+        assertTrue(doc.getElements().size() == 2);
+
+        final Group group3 = new Group(document2);
+        document2.addElement(group3);
+        doc.addGraphDocument(document2);
+        assertTrue(doc.getElements().size() == 3);
+        assertTrue(document2.getElements().size() == 0);
+
+        doc.clear();
+        test(doc);
+        Util.assertGraphDocumentEquals(doc, new GraphDocument());
+    }
+
+	@Test
+	public void testSimpleExport() {
+		GraphDocument document = new GraphDocument();
+		Group g = new Group(document);
+		document.addElement(g);
+        
+		InputGraph graph = new InputGraph("TestGraph");
+                g.addElement(graph);
+		graph.getProperties().setProperty("testName", "testValue");
+
+		InputNode n1 = new InputNode(0);
+		InputNode n2 = new InputNode(1);
+		InputEdge e1 = new InputEdge((char)0, 0, 1);
+		InputEdge e2 = new InputEdge((char)1, 0, 1);
+		graph.addNode(n1);
+		graph.addNode(n2);
+		graph.addEdge(e1);
+		graph.addEdge(e2);
+        
+        test(document);
+	}
+
+	@Test
+	public void testComplexExport() {
+
+		GraphDocument document = new GraphDocument();
+		Group g = new Group(document);
+		document.addElement(g);
+
+		InputGraph graph = new InputGraph("TestGraph");
+                g.addElement(graph);
+		graph.getProperties().setProperty("testName", "testValue");
+
+		InputNode n1 = new InputNode(0);
+		InputNode n2 = new InputNode(1);
+		InputEdge e1 = new InputEdge((char)0, 0, 0);
+		InputEdge e2 = new InputEdge((char)1, 1, 1);
+		graph.addNode(n1);
+		graph.addNode(n2);
+		graph.addEdge(e1);
+		graph.addEdge(e2);
+
+		InputGraph graph2 = new InputGraph("TestGraph2");
+                g.addElement(graph2);
+		graph2.addNode(n1);
+		InputNode n3 = new InputNode(2);
+		graph2.addNode(n3);
+		InputEdge e3 = new InputEdge((char)0, 0, 2);
+		graph2.addEdge(e3);
+
+        test(document);
+	}
+
+
+    /**
+     * Test of parse method, of class Parser.
+     */
+    @Test
+    public void testParse() {
+        testBoth(new GraphDocument(), "<graphDocument></graphDocument>");
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Difference/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.difference" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.difference.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Difference/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.difference
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/difference/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Difference/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.difference-impl" basedir="..">
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+        <condition>
+            <not>
+                <available file="${harness.dir}" type="dir"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Difference/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=1657ecfe
+build.xml.script.CRC32=03909051
+build.xml.stylesheet.CRC32=79c3b980
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=1657ecfe
+nbproject/build-impl.xml.script.CRC32=2208e770
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Difference/nbproject/platform.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.javahelp,\
+    org.netbeans.modules.masterfs,\
+    org.netbeans.modules.options.keymap,\
+    org.netbeans.modules.sendopts,\
+    org.netbeans.modules.templates,\
+    org.openide.compat,\
+    org.openide.execution,\
+    org.openide.util.enumerations
+enabled.clusters=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Difference/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Difference/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.difference</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.sun.hotspot.igv.difference</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Difference/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Difference/src/com/sun/hotspot/igv/difference/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=Difference
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 1998, 2008, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.difference;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.*;
+import com.sun.hotspot.igv.data.services.Scheduler;
+import java.util.*;
+import org.openide.util.Lookup;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Difference {
+
+    public static final String PROPERTY_STATE = "state";
+    public static final String VALUE_NEW = "new";
+    public static final String VALUE_CHANGED = "changed";
+    public static final String VALUE_SAME = "same";
+    public static final String VALUE_DELETED = "deleted";
+    public static final String OLD_PREFIX = "OLD_";
+    public static final String MAIN_PROPERTY = "name";
+    public static final double LIMIT = 100.0;
+    public static final String[] IGNORE_PROPERTIES = new String[]{"idx", "debug_idx"};
+
+    public static InputGraph createDiffGraph(InputGraph a, InputGraph b) {
+        if (a.getGroup() == b.getGroup()) {
+            return createDiffSameGroup(a, b);
+        } else {
+            return createDiff(a, b);
+        }
+    }
+
+    private static InputGraph createDiffSameGroup(InputGraph a, InputGraph b) {
+        Map<Integer, InputNode> keyMapB = new HashMap<>(b.getNodes().size());
+        for (InputNode n : b.getNodes()) {
+            Integer key = n.getId();
+            assert !keyMapB.containsKey(key);
+            keyMapB.put(key, n);
+        }
+
+        Set<NodePair> pairs = new HashSet<>();
+
+        for (InputNode n : a.getNodes()) {
+            Integer key = n.getId();
+
+
+            if (keyMapB.containsKey(key)) {
+                InputNode nB = keyMapB.get(key);
+                pairs.add(new NodePair(n, nB));
+            }
+        }
+
+        return createDiff(a, b, pairs);
+    }
+
+    private static void ensureScheduled(InputGraph a) {
+        if (a.getBlocks().isEmpty()) {
+            Scheduler s = Lookup.getDefault().lookup(Scheduler.class);
+            a.clearBlocks();
+            s.schedule(a);
+            a.ensureNodesInBlocks();
+        }
+    }
+
+    private static InputGraph createDiff(InputGraph a, InputGraph b, Set<NodePair> pairs) {
+        ensureScheduled(a);
+        ensureScheduled(b);
+
+        Group g = new Group(null);
+        g.setMethod(a.getGroup().getMethod());
+        if (a.getGroup() == b.getGroup()) {
+            g.getProperties().add(a.getGroup().getProperties());
+        } else {
+            // copy properties that have the same value in both groups
+            Properties bps = b.getGroup().getProperties();
+            for (Property p : a.getGroup().getProperties()) {
+                String value = p.getValue();
+                if (value != null && value.equals(bps.get(p.getName()))) {
+                    g.getProperties().setProperty(p.getName(), value);
+                }
+            }
+        }
+        g.getProperties().setProperty("name", "Difference");
+        InputGraph graph = new InputGraph(a.getName() + ", " + b.getName());
+        g.addElement(graph);
+
+        Map<InputBlock, InputBlock> blocksMap = new HashMap<>();
+        for (InputBlock blk : a.getBlocks()) {
+            InputBlock diffblk = graph.addBlock(blk.getName());
+            blocksMap.put(blk, diffblk);
+        }
+        for (InputBlock blk : b.getBlocks()) {
+            InputBlock diffblk = graph.getBlock(blk.getName());
+            if (diffblk == null) {
+                diffblk = graph.addBlock(blk.getName());
+            }
+            blocksMap.put(blk, diffblk);
+        }
+
+        // Difference between block edges
+        Set<Pair<String, String>> aEdges = new HashSet<>();
+        for (InputBlockEdge edge : a.getBlockEdges()) {
+            aEdges.add(new Pair<>(edge.getFrom().getName(), edge.getTo().getName()));
+        }
+        for (InputBlockEdge bEdge : b.getBlockEdges()) {
+            InputBlock from = bEdge.getFrom();
+            InputBlock to = bEdge.getTo();
+            Pair<String, String> pair = new Pair<>(from.getName(), to.getName());
+            if (aEdges.contains(pair)) {
+                // same
+                graph.addBlockEdge(blocksMap.get(from), blocksMap.get(to));
+                aEdges.remove(pair);
+            } else {
+                // added
+                InputBlockEdge edge = graph.addBlockEdge(blocksMap.get(from), blocksMap.get(to));
+                edge.setState(InputBlockEdge.State.NEW);
+            }
+        }
+        for (Pair<String, String> deleted : aEdges) {
+            // removed
+            InputBlock from = graph.getBlock(deleted.getLeft());
+            InputBlock to = graph.getBlock(deleted.getRight());
+            InputBlockEdge edge = graph.addBlockEdge(from, to);
+            edge.setState(InputBlockEdge.State.DELETED);
+        }
+
+        Set<InputNode> nodesA = new HashSet<>(a.getNodes());
+        Set<InputNode> nodesB = new HashSet<>(b.getNodes());
+
+        Map<InputNode, InputNode> inputNodeMap = new HashMap<>(pairs.size());
+        for (NodePair p : pairs) {
+            InputNode n = p.getLeft();
+            assert nodesA.contains(n);
+            InputNode nB = p.getRight();
+            assert nodesB.contains(nB);
+
+            nodesA.remove(n);
+            nodesB.remove(nB);
+            InputNode n2 = new InputNode(n);
+            inputNodeMap.put(n, n2);
+            inputNodeMap.put(nB, n2);
+            graph.addNode(n2);
+            InputBlock block = blocksMap.get(a.getBlock(n));
+            block.addNode(n2.getId());
+            markAsChanged(n2, n, nB);
+        }
+
+        for (InputNode n : nodesA) {
+            InputNode n2 = new InputNode(n);
+            graph.addNode(n2);
+            InputBlock block = blocksMap.get(a.getBlock(n));
+            block.addNode(n2.getId());
+            markAsDeleted(n2);
+            inputNodeMap.put(n, n2);
+        }
+
+        int curIndex = 0;
+        for (InputNode n : nodesB) {
+            InputNode n2 = new InputNode(n);
+
+            // Find new ID for node of b, does not change the id property
+            while (graph.getNode(curIndex) != null) {
+                curIndex++;
+            }
+
+            n2.setId(curIndex);
+            graph.addNode(n2);
+            InputBlock block = blocksMap.get(b.getBlock(n));
+            block.addNode(n2.getId());
+            markAsNew(n2);
+            inputNodeMap.put(n, n2);
+        }
+
+        Collection<InputEdge> edgesA = a.getEdges();
+        Collection<InputEdge> edgesB = b.getEdges();
+
+        Set<InputEdge> newEdges = new HashSet<>();
+
+        for (InputEdge e : edgesA) {
+            int from = e.getFrom();
+            int to = e.getTo();
+            InputNode nodeFrom = inputNodeMap.get(a.getNode(from));
+            InputNode nodeTo = inputNodeMap.get(a.getNode(to));
+            char fromIndex = e.getFromIndex();
+            char toIndex = e.getToIndex();
+
+            InputEdge newEdge = new InputEdge(fromIndex, toIndex, nodeFrom.getId(), nodeTo.getId());
+            if (!newEdges.contains(newEdge)) {
+                markAsDeleted(newEdge);
+                newEdges.add(newEdge);
+                graph.addEdge(newEdge);
+            }
+        }
+
+        for (InputEdge e : edgesB) {
+            int from = e.getFrom();
+            int to = e.getTo();
+            InputNode nodeFrom = inputNodeMap.get(b.getNode(from));
+            InputNode nodeTo = inputNodeMap.get(b.getNode(to));
+            char fromIndex = e.getFromIndex();
+            char toIndex = e.getToIndex();
+
+            InputEdge newEdge = new InputEdge(fromIndex, toIndex, nodeFrom.getId(), nodeTo.getId());
+            if (!newEdges.contains(newEdge)) {
+                markAsNew(newEdge);
+                newEdges.add(newEdge);
+                graph.addEdge(newEdge);
+            } else {
+                newEdges.remove(newEdge);
+                graph.removeEdge(newEdge);
+                markAsSame(newEdge);
+                newEdges.add(newEdge);
+                graph.addEdge(newEdge);
+            }
+        }
+
+        return graph;
+    }
+
+    private static class NodePair extends Pair<InputNode, InputNode> {
+
+
+        public NodePair(InputNode n1, InputNode n2) {
+            super(n1, n2);
+        }
+
+        public double getValue() {
+
+            double result = 0.0;
+            for (Property p : getLeft().getProperties()) {
+                double faktor = 1.0;
+                for (String forbidden : IGNORE_PROPERTIES) {
+                    if (p.getName().equals(forbidden)) {
+                        faktor = 0.1;
+                        break;
+                    }
+                }
+                String p2 = getRight().getProperties().get(p.getName());
+                result += evaluate(p.getValue(), p2) * faktor;
+            }
+
+            return result;
+        }
+
+        private double evaluate(String p, String p2) {
+            if (p2 == null) {
+                return 1.0;
+            }
+            if (p.equals(p2)) {
+                return 0.0;
+            } else {
+                return (double) (Math.abs(p.length() - p2.length())) / p.length() + 0.5;
+            }
+        }
+    }
+
+    private static InputGraph createDiff(InputGraph a, InputGraph b) {
+
+        Set<InputNode> matched = new HashSet<>();
+
+        Set<NodePair> pairs = new HashSet<>();
+        for (InputNode n : a.getNodes()) {
+            String s = n.getProperties().get(MAIN_PROPERTY);
+            if (s == null) {
+                s = "";
+            }
+            for (InputNode n2 : b.getNodes()) {
+                String s2 = n2.getProperties().get(MAIN_PROPERTY);
+                if (s2 == null) {
+                    s2 = "";
+                }
+
+                if (s.equals(s2)) {
+                    NodePair p = new NodePair(n, n2);
+                    pairs.add(p);
+                }
+            }
+        }
+
+        Set<NodePair> selectedPairs = new HashSet<>();
+        while (pairs.size() > 0) {
+
+            double min = Double.MAX_VALUE;
+            NodePair minPair = null;
+            for (NodePair p : pairs) {
+                double cur = p.getValue();
+                if (cur < min) {
+                    minPair = p;
+                    min = cur;
+                }
+            }
+
+            if (min > LIMIT) {
+                break;
+            } else {
+                selectedPairs.add(minPair);
+
+                Set<NodePair> toRemove = new HashSet<>();
+                for (NodePair p : pairs) {
+                    if (p.getLeft() == minPair.getLeft() || p.getRight() == minPair.getRight()) {
+                        toRemove.add(p);
+                    }
+                }
+                pairs.removeAll(toRemove);
+            }
+        }
+
+        return createDiff(a, b, selectedPairs);
+    }
+
+    private static void markAsNew(InputEdge e) {
+        e.setState(InputEdge.State.NEW);
+    }
+
+    private static void markAsDeleted(InputEdge e) {
+        e.setState(InputEdge.State.DELETED);
+
+    }
+
+    private static void markAsSame(InputEdge e) {
+        e.setState(InputEdge.State.SAME);
+    }
+
+    private static void markAsChanged(InputNode n, InputNode firstNode, InputNode otherNode) {
+
+        boolean difference = false;
+        for (Property p : otherNode.getProperties()) {
+            String s = firstNode.getProperties().get(p.getName());
+            if (!p.getValue().equals(s)) {
+                difference = true;
+                n.getProperties().setProperty(OLD_PREFIX + p.getName(), p.getValue());
+            }
+        }
+
+        for (Property p : firstNode.getProperties()) {
+            String s = otherNode.getProperties().get(p.getName());
+            if (s == null && p.getValue().length() > 0) {
+                difference = true;
+                n.getProperties().setProperty(OLD_PREFIX + p.getName(), "");
+            }
+        }
+
+        if (difference) {
+            n.getProperties().setProperty(PROPERTY_STATE, VALUE_CHANGED);
+        } else {
+            n.getProperties().setProperty(PROPERTY_STATE, VALUE_SAME);
+        }
+    }
+
+    private static void markAsDeleted(InputNode n) {
+        n.getProperties().setProperty(PROPERTY_STATE, VALUE_DELETED);
+    }
+
+    private static void markAsNew(InputNode n) {
+        n.getProperties().setProperty(PROPERTY_STATE, VALUE_NEW);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Draw2DLibrary/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="org.eclipse.draw2d" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project org.eclipse.draw2d.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Draw2DLibrary/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: org.eclipse.draw2d
+OpenIDE-Module-Localizing-Bundle: org/eclipse/draw2d/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Draw2DLibrary/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="org.eclipse.draw2d-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Draw2DLibrary/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=36988202
+build.xml.script.CRC32=0429cbcb
+build.xml.stylesheet.CRC32=a56c6a5b@2.47.1
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=36988202
+nbproject/build-impl.xml.script.CRC32=92856d71
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.47.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Draw2DLibrary/nbproject/platform.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,204 @@
+cluster.path=\
+    ${nbplatform.active.dir}/ide:\
+    ${nbplatform.active.dir}/platform
+disabled.modules=\
+    com.jcraft.jsch,\
+    com.jcraft.jzlib,\
+    org.apache.commons.codec,\
+    org.apache.commons.httpclient,\
+    org.apache.commons.io,\
+    org.apache.commons.lang,\
+    org.apache.commons.logging,\
+    org.apache.ws.commons.util,\
+    org.apache.xml.resolver,\
+    org.apache.xmlrpc,\
+    org.eclipse.core.contenttype,\
+    org.eclipse.core.jobs,\
+    org.eclipse.core.net,\
+    org.eclipse.core.runtime,\
+    org.eclipse.core.runtime.compatibility.auth,\
+    org.eclipse.equinox.app,\
+    org.eclipse.equinox.common,\
+    org.eclipse.equinox.preferences,\
+    org.eclipse.equinox.registry,\
+    org.eclipse.equinox.security,\
+    org.eclipse.jgit,\
+    org.eclipse.mylyn.bugzilla.core,\
+    org.eclipse.mylyn.commons.core,\
+    org.eclipse.mylyn.commons.net,\
+    org.eclipse.mylyn.commons.xmlrpc,\
+    org.eclipse.mylyn.tasks.core,\
+    org.mozilla.rhino.patched,\
+    org.netbeans.api.debugger,\
+    org.netbeans.api.java.classpath,\
+    org.netbeans.api.xml,\
+    org.netbeans.core.browser,\
+    org.netbeans.core.execution,\
+    org.netbeans.core.ide,\
+    org.netbeans.core.io.ui,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.nativeaccess,\
+    org.netbeans.core.osgi,\
+    org.netbeans.lib.cvsclient,\
+    org.netbeans.lib.terminalemulator,\
+    org.netbeans.libs.antlr3.runtime,\
+    org.netbeans.libs.bytelist,\
+    org.netbeans.libs.commons_net,\
+    org.netbeans.libs.freemarker,\
+    org.netbeans.libs.git,\
+    org.netbeans.libs.ini4j,\
+    org.netbeans.libs.jaxb,\
+    org.netbeans.libs.jsr223,\
+    org.netbeans.libs.junit4,\
+    org.netbeans.libs.jvyamlb,\
+    org.netbeans.libs.lucene,\
+    org.netbeans.libs.smack,\
+    org.netbeans.libs.svnClientAdapter,\
+    org.netbeans.libs.svnClientAdapter.javahl,\
+    org.netbeans.libs.svnClientAdapter.svnkit,\
+    org.netbeans.libs.swingx,\
+    org.netbeans.libs.xerces,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.bugtracking,\
+    org.netbeans.modules.bugtracking.bridge,\
+    org.netbeans.modules.bugzilla,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.csl.api,\
+    org.netbeans.modules.css.editor,\
+    org.netbeans.modules.css.lib,\
+    org.netbeans.modules.css.visual,\
+    org.netbeans.modules.db,\
+    org.netbeans.modules.db.core,\
+    org.netbeans.modules.db.dataview,\
+    org.netbeans.modules.db.drivers,\
+    org.netbeans.modules.db.kit,\
+    org.netbeans.modules.db.metadata.model,\
+    org.netbeans.modules.db.mysql,\
+    org.netbeans.modules.db.sql.editor,\
+    org.netbeans.modules.db.sql.visualeditor,\
+    org.netbeans.modules.dbapi,\
+    org.netbeans.modules.defaults,\
+    org.netbeans.modules.derby,\
+    org.netbeans.modules.dlight.nativeexecution,\
+    org.netbeans.modules.dlight.terminal,\
+    org.netbeans.modules.editor.bookmarks,\
+    org.netbeans.modules.editor.bracesmatching,\
+    org.netbeans.modules.editor.codetemplates,\
+    org.netbeans.modules.editor.completion,\
+    org.netbeans.modules.editor.guards,\
+    org.netbeans.modules.editor.indent.project,\
+    org.netbeans.modules.editor.kit,\
+    org.netbeans.modules.editor.macros,\
+    org.netbeans.modules.editor.structure,\
+    org.netbeans.modules.extbrowser,\
+    org.netbeans.modules.extexecution,\
+    org.netbeans.modules.extexecution.destroy,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.git,\
+    org.netbeans.modules.glassfish.common,\
+    org.netbeans.modules.gototest,\
+    org.netbeans.modules.gsf.codecoverage,\
+    org.netbeans.modules.gsf.testrunner,\
+    org.netbeans.modules.html,\
+    org.netbeans.modules.html.editor,\
+    org.netbeans.modules.html.editor.lib,\
+    org.netbeans.modules.html.lexer,\
+    org.netbeans.modules.html.parser,\
+    org.netbeans.modules.html.validation,\
+    org.netbeans.modules.httpserver,\
+    org.netbeans.modules.hudson,\
+    org.netbeans.modules.hudson.git,\
+    org.netbeans.modules.hudson.mercurial,\
+    org.netbeans.modules.hudson.subversion,\
+    org.netbeans.modules.hudson.tasklist,\
+    org.netbeans.modules.ide.kit,\
+    org.netbeans.modules.image,\
+    org.netbeans.modules.javascript.editing,\
+    org.netbeans.modules.javascript.hints,\
+    org.netbeans.modules.javascript.kit,\
+    org.netbeans.modules.javascript.refactoring,\
+    org.netbeans.modules.jellytools.ide,\
+    org.netbeans.modules.jumpto,\
+    org.netbeans.modules.keyring.impl,\
+    org.netbeans.modules.languages,\
+    org.netbeans.modules.languages.diff,\
+    org.netbeans.modules.languages.manifest,\
+    org.netbeans.modules.languages.yaml,\
+    org.netbeans.modules.lexer.nbbridge,\
+    org.netbeans.modules.localhistory,\
+    org.netbeans.modules.mercurial,\
+    org.netbeans.modules.netbinox,\
+    org.netbeans.modules.parsing.api,\
+    org.netbeans.modules.parsing.lucene,\
+    org.netbeans.modules.print.editor,\
+    org.netbeans.modules.project.ant,\
+    org.netbeans.modules.project.libraries,\
+    org.netbeans.modules.projectui,\
+    org.netbeans.modules.projectui.buildmenu,\
+    org.netbeans.modules.projectuiapi,\
+    org.netbeans.modules.properties,\
+    org.netbeans.modules.properties.syntax,\
+    org.netbeans.modules.refactoring.api,\
+    org.netbeans.modules.schema2beans,\
+    org.netbeans.modules.server,\
+    org.netbeans.modules.servletapi,\
+    org.netbeans.modules.spellchecker,\
+    org.netbeans.modules.spellchecker.apimodule,\
+    org.netbeans.modules.spellchecker.bindings.htmlxml,\
+    org.netbeans.modules.spellchecker.bindings.properties,\
+    org.netbeans.modules.spellchecker.dictionary_en,\
+    org.netbeans.modules.spellchecker.kit,\
+    org.netbeans.modules.spi.actions,\
+    org.netbeans.modules.subversion,\
+    org.netbeans.modules.swing.validation,\
+    org.netbeans.modules.target.iterator,\
+    org.netbeans.modules.tasklist.kit,\
+    org.netbeans.modules.tasklist.projectint,\
+    org.netbeans.modules.tasklist.todo,\
+    org.netbeans.modules.tasklist.ui,\
+    org.netbeans.modules.terminal,\
+    org.netbeans.modules.usersguide,\
+    org.netbeans.modules.utilities,\
+    org.netbeans.modules.utilities.project,\
+    org.netbeans.modules.versioning,\
+    org.netbeans.modules.versioning.indexingbridge,\
+    org.netbeans.modules.versioning.system.cvss.installer,\
+    org.netbeans.modules.versioning.util,\
+    org.netbeans.modules.web.client.tools.api,\
+    org.netbeans.modules.web.common,\
+    org.netbeans.modules.web.indent,\
+    org.netbeans.modules.xml,\
+    org.netbeans.modules.xml.axi,\
+    org.netbeans.modules.xml.catalog,\
+    org.netbeans.modules.xml.core,\
+    org.netbeans.modules.xml.jaxb.api,\
+    org.netbeans.modules.xml.lexer,\
+    org.netbeans.modules.xml.multiview,\
+    org.netbeans.modules.xml.retriever,\
+    org.netbeans.modules.xml.schema.completion,\
+    org.netbeans.modules.xml.schema.model,\
+    org.netbeans.modules.xml.tax,\
+    org.netbeans.modules.xml.text,\
+    org.netbeans.modules.xml.tools,\
+    org.netbeans.modules.xml.wsdl.model,\
+    org.netbeans.modules.xml.xam,\
+    org.netbeans.modules.xml.xdm,\
+    org.netbeans.modules.xsl,\
+    org.netbeans.spi.debugger.ui,\
+    org.netbeans.spi.editor.hints,\
+    org.netbeans.spi.navigator,\
+    org.netbeans.spi.palette,\
+    org.netbeans.spi.tasklist,\
+    org.netbeans.spi.viewmodel,\
+    org.netbeans.swing.dirchooser,\
+    org.openide.compat,\
+    org.openide.execution,\
+    org.openide.options,\
+    org.openide.util.enumerations
+## Not disabled because of NetBeans bug 206347:
+## Applications not using OSGi don't start on NbP 7.1
+#   org.netbeans.core.netigso,\
+#   org.netbeans.libs.felix,\
+#   org.netbeans.libs.osgi,\
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Draw2DLibrary/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+is.autoload=true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Draw2DLibrary/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>org.eclipse.draw2d</code-name-base>
+            <suite-component/>
+            <module-dependencies/>
+            <public-packages>
+                <package>org.eclipse.draw2d</package>
+                <package>org.eclipse.draw2d.geometry</package>
+                <package>org.eclipse.draw2d.graph</package>
+                <package>org.eclipse.draw2d.internal</package>
+                <package>org.eclipse.draw2d.internal.graph</package>
+                <package>org.eclipse.draw2d.parts</package>
+                <package>org.eclipse.draw2d.text</package>
+                <package>org.eclipse.draw2d.widgets</package>
+            </public-packages>
+            <class-path-extension>
+                <runtime-relative-path>ext/org.eclipse.draw2d_3.1.0.jar</runtime-relative-path>
+                <binary-origin>release/modules/ext/org.eclipse.draw2d_3.1.0.jar</binary-origin>
+            </class-path-extension>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Draw2DLibrary/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
Binary file visualizer/Draw2DLibrary/release/modules/ext/org.eclipse.draw2d_3.1.0.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Draw2DLibrary/src/org/eclipse/draw2d/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=Draw2DLibrary
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.oracle.graal.visualizer.editor" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.oracle.graal.visualizer.editor.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.oracle.graal.visualizer.editor
+OpenIDE-Module-Layer: com/oracle/graal/visualizer/editor/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/oracle/graal/visualizer/editor/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.oracle.graal.visualizer.editor-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=5dcda8e3
+build.xml.script.CRC32=98c4f3b3
+build.xml.stylesheet.CRC32=a56c6a5b@2.47.1
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=5dcda8e3
+nbproject/build-impl.xml.script.CRC32=6243c7e2
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.47.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.oracle.graal.visualizer.editor</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.difference</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.filter</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.settings</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.spi.quicksearch</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.12.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.actions</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.24.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.39.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.dialogs</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.23.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.filesystems</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.53.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.loaders</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.32.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.19.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.11.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.48.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.oracle.graal.visualizer.editor</package>
+                <package>com.oracle.graal.visualizer.editor.actions</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/src/META-INF/services/com.sun.hotspot.igv.data.services.GraphViewer	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+com.oracle.graal.visualizer.editor.GraphViewerImplementation
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/src/com/oracle/graal/visualizer/editor/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,3 @@
+OpenIDE-Module-Name=Editor
+CTL_EditorTopComponent=Compilation
+HINT_EditorTopComponent=Shows the snapshots of a single compilation.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/src/com/oracle/graal/visualizer/editor/CompilationViewer.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2008, 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.visualizer.editor;
+
+import com.sun.hotspot.igv.graph.Figure;
+import java.awt.Component;
+import java.awt.Graphics2D;
+import java.util.Collection;
+import org.openide.awt.UndoRedo;
+import org.openide.util.Lookup;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface CompilationViewer {
+
+    public Lookup getLookup();
+
+    public Component getComponent();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/src/com/oracle/graal/visualizer/editor/CompilationViewerFactory.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,31 @@
+/*
+ * 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.visualizer.editor;
+
+import com.sun.hotspot.igv.data.InputGraph;
+
+public interface CompilationViewerFactory {
+    CompilationViewer createViewer(InputGraph firstGraph, InputGraph secondGraph);
+    String getName();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/src/com/oracle/graal/visualizer/editor/DiagramViewModel.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 1998, 2008, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.visualizer.editor;
+
+import com.sun.hotspot.igv.data.*;
+import com.sun.hotspot.igv.difference.Difference;
+import com.sun.hotspot.igv.filter.CustomFilter;
+import com.sun.hotspot.igv.filter.FilterChain;
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.settings.Settings;
+import java.util.*;
+
+public class DiagramViewModel {
+
+    private Set<Integer> hiddenNodes;
+    private Set<Integer> onScreenNodes;
+    private Set<Integer> selectedNodes;
+    private FilterChain filterChain;
+    private FilterChain sequenceFilterChain;
+    private Diagram diagram;
+    private InputGraph inputGraph;
+    private ChangedEvent<DiagramViewModel> diagramChangedEvent;
+    private ChangedEvent<DiagramViewModel> viewChangedEvent;
+    private ChangedEvent<DiagramViewModel> hiddenNodesChangedEvent;
+    private ChangedEvent<DiagramViewModel> viewPropertiesChangedEvent;
+    private boolean showNodeHull;
+    private final InputGraph secondGraph;
+    private final InputGraph firstGraph;
+    private ChangedListener<FilterChain> filterChainChangedListener = new ChangedListener<FilterChain>() {
+
+        @Override
+        public void changed(FilterChain source) {
+            diagramChanged();
+        }
+    };
+
+    public boolean getShowNodeHull() {
+        return showNodeHull;
+    }
+
+    public void setShowNodeHull(boolean b) {
+        showNodeHull = b;
+        viewPropertiesChangedEvent.fire();
+    }
+
+    public DiagramViewModel(InputGraph firstGraph, InputGraph secondGraph, Group g, FilterChain filterChain, FilterChain sequenceFilterChain) {
+
+        this.firstGraph = firstGraph;
+        this.secondGraph = secondGraph;
+        this.showNodeHull = true;
+        assert filterChain != null;
+        this.filterChain = filterChain;
+        assert sequenceFilterChain != null;
+        this.sequenceFilterChain = sequenceFilterChain;
+        hiddenNodes = new HashSet<>();
+        onScreenNodes = new HashSet<>();
+        selectedNodes = new HashSet<>();
+        diagramChangedEvent = new ChangedEvent<>(this);
+        viewChangedEvent = new ChangedEvent<>(this);
+        hiddenNodesChangedEvent = new ChangedEvent<>(this);
+        viewPropertiesChangedEvent = new ChangedEvent<>(this);
+
+        filterChain.getChangedEvent().addListener(filterChainChangedListener);
+        sequenceFilterChain.getChangedEvent().addListener(filterChainChangedListener);
+    }
+
+    public ChangedEvent<DiagramViewModel> getDiagramChangedEvent() {
+        return diagramChangedEvent;
+    }
+
+    public ChangedEvent<DiagramViewModel> getViewChangedEvent() {
+        return viewChangedEvent;
+    }
+
+    public ChangedEvent<DiagramViewModel> getHiddenNodesChangedEvent() {
+        return hiddenNodesChangedEvent;
+    }
+
+    public ChangedEvent<DiagramViewModel> getViewPropertiesChangedEvent() {
+        return viewPropertiesChangedEvent;
+    }
+
+    public Set<Integer> getSelectedNodes() {
+        return selectedNodes;
+    }
+
+    public Set<Integer> getHiddenNodes() {
+        return hiddenNodes;
+    }
+
+    public Set<Integer> getOnScreenNodes() {
+        return onScreenNodes;
+    }
+
+    public void setSelectedNodes(Set<Integer> nodes) {
+        this.selectedNodes = nodes;
+       /* List<Color> colors = new ArrayList<>();
+        for (int i = 0; i < group.getGraphs().size(); ++i) {
+            colors.add(Color.black);
+        }
+        if (nodes.size() >= 1) {
+            for (Integer id : nodes) {
+                if (id < 0) {
+                    id = -id;
+                }
+                InputNode last = null;
+                int index = 0;
+                for (InputGraph g : group.getGraphs()) {
+                    Color curColor = colors.get(index);
+                    InputNode cur = g.getNode(id);
+                    if (cur != null) {
+                        if (last == null) {
+                            curColor = Color.green;
+                        } else {
+                            if (last.equals(cur)) {
+                                if (curColor == Color.black) {
+                                    curColor = Color.white;
+                                }
+                            } else {
+                                if (curColor != Color.green) {
+                                    curColor = Color.orange;
+                                }
+                            }
+                        }
+                    }
+                    last = cur;
+                    colors.set(index, curColor);
+                    index++;
+                }
+            }
+        }
+        compilationViewModel.setColors(colors);*/
+        // TODO: Add colorization.
+        viewChangedEvent.fire();
+    }
+
+    public void showNot(final Set<Integer> nodes) {
+        System.out.println("Shownot called with " + nodes);
+        setHiddenNodes(nodes);
+    }
+
+    public void showFigures(Collection<Figure> f) {
+        HashSet<Integer> newHiddenNodes = new HashSet<>(getHiddenNodes());
+        for (Figure fig : f) {
+            newHiddenNodes.removeAll(fig.getSource().getSourceNodesAsSet());
+        }
+        setHiddenNodes(newHiddenNodes);
+    }
+
+    public Set<Figure> getSelectedFigures() {
+        Set<Figure> result = new HashSet<>();
+        for (Figure f : diagram.getFigures()) {
+            for (InputNode node : f.getSource().getSourceNodes()) {
+                if (getSelectedNodes().contains(node.getId())) {
+                    result.add(f);
+                }
+            }
+        }
+        return result;
+    }
+
+    public void showAll(final Collection<Figure> f) {
+        showFigures(f);
+    }
+
+    public void showOnly(final Set<Integer> nodes) {
+        final HashSet<Integer> allNodes = new HashSet<>(getGraphToView().getGroup().getAllNodes());
+        allNodes.removeAll(nodes);
+        setHiddenNodes(allNodes);
+    }
+
+    public void setHiddenNodes(Set<Integer> nodes) {
+        this.hiddenNodes = nodes;
+        hiddenNodesChangedEvent.fire();
+    }
+
+    public void setOnScreenNodes(Set<Integer> onScreenNodes) {
+        this.onScreenNodes = onScreenNodes;
+        viewChangedEvent.fire();
+    }
+
+    public FilterChain getSequenceFilterChain() {
+        return filterChain;
+    }
+
+    public void setSequenceFilterChain(FilterChain chain) {
+        assert chain != null : "sequenceFilterChain must never be null";
+        sequenceFilterChain.getChangedEvent().removeListener(filterChainChangedListener);
+        sequenceFilterChain = chain;
+        sequenceFilterChain.getChangedEvent().addListener(filterChainChangedListener);
+        diagramChanged();
+    }
+
+    private void diagramChanged() {
+        // clear diagram
+        diagram = null;
+        getDiagramChangedEvent().fire();
+
+    }
+
+    public FilterChain getFilterChain() {
+        return filterChain;
+    }
+
+    public void setFilterChain(FilterChain chain) {
+        assert chain != null : "filterChain must never be null";
+        filterChain.getChangedEvent().removeListener(filterChainChangedListener);
+        filterChain = chain;
+        filterChain.getChangedEvent().addListener(filterChainChangedListener);
+        diagramChanged();
+    }
+
+    private static List<String> calculateStringList(Group g) {
+        List<String> result = new ArrayList<>();
+        for (InputGraph graph : g.getGraphs()) {
+            result.add(graph.getName());
+        }
+        return result;
+    }
+
+    public InputGraph getFirstGraph() {
+        return firstGraph;
+    }
+
+    public InputGraph getSecondGraph() {
+        return secondGraph;
+    }
+
+    public Diagram getDiagramToView() {
+
+        if (diagram == null) {
+            diagram = Diagram.createDiagram(getGraphToView(), Settings.get().get(Settings.NODE_TEXT, Settings.NODE_TEXT_DEFAULT));
+            getFilterChain().apply(diagram, getSequenceFilterChain());
+            if (getFirstGraph() != getSecondGraph()) {
+                CustomFilter f = new CustomFilter(
+                        "difference", "colorize('state', 'same', white);"
+                        + "colorize('state', 'changed', orange);"
+                        + "colorize('state', 'new', green);"
+                        + "colorize('state', 'deleted', red);");
+                f.apply(diagram);
+            }
+        }
+
+        return diagram;
+    }
+
+    public InputGraph getGraphToView() {
+        if (inputGraph == null) {
+            if (getFirstGraph() != getSecondGraph()) {
+                inputGraph = Difference.createDiffGraph(getFirstGraph(), getSecondGraph());
+            } else {
+                inputGraph = getFirstGraph();
+            }
+        }
+
+        return inputGraph;
+    }
+
+    void setSelectedFigures(List<Figure> list) {
+        Set<Integer> newSelectedNodes = new HashSet<>();
+        for (Figure f : list) {
+            newSelectedNodes.addAll(f.getSource().getSourceNodesAsSet());
+        }
+        this.setSelectedNodes(newSelectedNodes);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/src/com/oracle/graal/visualizer/editor/EditorTopComponent.form	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <NonVisualComponents>
+    <Component class="javax.swing.JCheckBox" name="jCheckBox1">
+      <Properties>
+        <Property name="text" type="java.lang.String" value="jCheckBox1"/>
+        <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+          <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
+            <EmptyBorder bottom="0" left="0" right="0" top="0"/>
+          </Border>
+        </Property>
+        <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
+          <Insets value="[0, 0, 0, 0]"/>
+        </Property>
+      </Properties>
+    </Component>
+  </NonVisualComponents>
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+    <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
+  </AuxValues>
+
+  <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+</Form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/src/com/oracle/graal/visualizer/editor/EditorTopComponent.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,291 @@
+/*
+ * 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.visualizer.editor;
+
+import com.oracle.graal.visualizer.util.LookupUtils;
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.data.Group;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.util.RangeSliderModel;
+import java.awt.BorderLayout;
+import java.awt.CardLayout;
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.*;
+import java.util.prefs.Preferences;
+import javax.swing.*;
+import org.openide.awt.Toolbar;
+import org.openide.util.Lookup;
+import org.openide.util.NbBundle;
+import org.openide.util.NbPreferences;
+import org.openide.util.Utilities;
+import org.openide.util.actions.Presenter;
+import org.openide.util.lookup.AbstractLookup;
+import org.openide.util.lookup.InstanceContent;
+import org.openide.util.lookup.Lookups;
+import org.openide.util.lookup.ProxyLookup;
+import org.openide.windows.Mode;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
+
+public final class EditorTopComponent extends TopComponent {
+
+    private InstanceContent content;
+    private static final String PREFERRED_ID = "EditorTopComponent";
+    private RangeSliderModel rangeSliderModel;
+    private CompilationViewer activeViewer;
+    private CompilationViewerFactory activeFactory;
+    private Group group;
+    private final JToolBar viewerToolBar;
+    private final JPanel viewerPanel;
+    private final CardLayout viewerPanelCardLayout;
+    private final Map<String, CompilationViewer> createdComponents = new HashMap<>();
+    private final Lookup proxyLookup;
+    private Lookup currentLookup = Lookups.fixed();
+    private final Lookup.Provider currentViewLookupProvider = new Lookup.Provider() {
+
+        @Override
+        public Lookup getLookup() {
+            return currentLookup;
+        }
+    };
+    private static final String PREFERENCE_FACTORY = "factory";
+
+    public static Preferences getPreferences() {
+        return NbPreferences.forModule(EditorTopComponent.class);
+    }
+
+    private InputGraph getFirstGraph() {
+        return group.getGraphs().get(getModel().getFirstPosition());
+    }
+
+    private InputGraph getSecondGraph() {
+        return group.getGraphs().get(getModel().getSecondPosition());
+    }
+
+    private void updateDisplayName() {
+        int first = getModel().getFirstPosition();
+        int second = getModel().getSecondPosition();
+        if (first == second) {
+            setDisplayName(getModel().getPositions().get(first));
+        } else {
+            setDisplayName(String.format("%s: %s - %s", activeFactory.getName(), getModel().getPositions().get(first), getModel().getPositions().get(second)));
+        }
+    }
+
+    private void activateFactory(CompilationViewerFactory factory) {
+        this.activeFactory = factory;
+        getPreferences().put(PREFERENCE_FACTORY, activeFactory.getName());
+        updateView();
+    }
+
+    public EditorTopComponent(InputGraph graph) {
+        setName(NbBundle.getMessage(EditorTopComponent.class, "CTL_EditorTopComponent"));
+        setToolTipText(NbBundle.getMessage(EditorTopComponent.class, "HINT_EditorTopComponent"));
+
+        initComponents();
+
+        Toolbar toolBar = new Toolbar();
+        this.add(BorderLayout.NORTH, toolBar);
+
+        this.group = graph.getGroup();
+        rangeSliderModel = new RangeSliderModel(calculateStringList(group));
+        content = new InstanceContent();
+        content.add(rangeSliderModel);
+        int graphPos = group.getGraphs().indexOf(graph);
+        rangeSliderModel.setPositions(graphPos, graphPos);
+
+        Collection<? extends CompilationViewerFactory> factories = Lookup.getDefault().lookupAll(CompilationViewerFactory.class);
+        proxyLookup = Lookups.proxy(currentViewLookupProvider);
+        this.associateLookup(new ProxyLookup(new Lookup[]{proxyLookup, new AbstractLookup(content)}));
+
+        rangeSliderModel.getChangedEvent().addListener(rangeSliderListener);
+
+        ButtonGroup factoryButtonGroup = new ButtonGroup();
+        for (CompilationViewerFactory factory : factories) {
+            AbstractButton button = createFactoryChangeButton(factory);
+            factoryButtonGroup.add(button);
+            toolBar.add(button);
+        }
+        toolBar.addSeparator();
+
+        viewerToolBar = new JToolBar();
+        viewerToolBar.setFloatable(false);
+        toolBar.add(viewerToolBar);
+        toolBar.add(Box.createHorizontalGlue());
+
+        Action action = Utilities.actionsForPath("QuickSearchShadow").get(0);
+        Component quicksearch = ((Presenter.Toolbar) action).getToolbarPresenter();
+        quicksearch.setMinimumSize(quicksearch.getPreferredSize()); // necessary for GTK LAF
+        toolBar.add(quicksearch);
+
+        viewerPanel = new JPanel();
+        viewerPanelCardLayout = new CardLayout();
+        viewerPanel.setLayout(viewerPanelCardLayout);
+        this.add(viewerPanel, BorderLayout.CENTER);
+
+        if (factories.size() > 0) {
+            String activeFactoryName = getPreferences().get(PREFERENCE_FACTORY, factories.iterator().next().getName());
+            Enumeration<AbstractButton> buttons = factoryButtonGroup.getElements();
+            for (CompilationViewerFactory factory : factories) {
+                JToggleButton curButton = (JToggleButton) buttons.nextElement();
+                if (factory.getName().equals(activeFactoryName)) {
+                    activeFactory = factory;
+                    curButton.setSelected(true);
+                }
+            }
+        }
+        updateView();
+    }
+
+    private static List<String> calculateStringList(Group g) {
+        List<String> result = new ArrayList<>();
+        for (InputGraph graph : g.getGraphs()) {
+            result.add(graph.getName());
+        }
+        return result;
+    }
+
+    private RangeSliderModel getModel() {
+        return rangeSliderModel;
+    }
+
+    public static EditorTopComponent getActive() {
+        Set<? extends Mode> modes = WindowManager.getDefault().getModes();
+        for (Mode m : modes) {
+            TopComponent tc = m.getSelectedTopComponent();
+            if (tc instanceof EditorTopComponent) {
+                return (EditorTopComponent) tc;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * This method is called from within the constructor to initialize the form. WARNING: Do NOT modify this code. The content of this method is always
+     * regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        jCheckBox1 = new javax.swing.JCheckBox();
+
+        org.openide.awt.Mnemonics.setLocalizedText(jCheckBox1, "jCheckBox1");
+        jCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
+        jCheckBox1.setMargin(new java.awt.Insets(0, 0, 0, 0));
+
+        setLayout(new java.awt.BorderLayout());
+    }// </editor-fold>//GEN-END:initComponents
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JCheckBox jCheckBox1;
+    // End of variables declaration//GEN-END:variables
+
+    @Override
+    public int getPersistenceType() {
+        return TopComponent.PERSISTENCE_NEVER;
+    }
+
+    @Override
+    public void componentOpened() {
+    }
+
+    @Override
+    public void componentClosed() {
+    }
+
+    @Override
+    protected String preferredID() {
+        return PREFERRED_ID;
+    }
+    private ChangedListener<RangeSliderModel> rangeSliderListener = new ChangedListener<RangeSliderModel>() {
+
+        @Override
+        public void changed(RangeSliderModel source) {
+            SwingUtilities.invokeLater(new Runnable() {
+
+                @Override
+                public void run() {
+                    updateView();
+                }
+            });
+        }
+    };
+
+    private void updateView() {
+        updateDisplayName();
+        String id = getViewStringIdentifier();
+        if (!createdComponents.containsKey(id)) {
+            CompilationViewer newViewer = createViewer(activeFactory);
+            createdComponents.put(id, newViewer);
+            viewerPanel.add(newViewer.getComponent(), id);
+        }
+
+        CompilationViewer newViewer = createdComponents.get(id);
+        if (newViewer != activeViewer) {
+            activeViewer = newViewer;
+            viewerPanelCardLayout.show(viewerPanel, id);
+
+            currentLookup = new ProxyLookup(activeViewer.getLookup(), Lookups.fixed(getFirstGraph(), getSecondGraph()));
+            initializeToolBar(activeFactory.getName());
+
+            // Make sure that lookup is updated.
+            proxyLookup.lookup(Object.class);
+        }
+    }
+
+    private String getViewStringIdentifier() {
+        return String.format("%s/%d/%d", activeFactory.getName(), getModel().getFirstPosition(), getModel().getSecondPosition());
+    }
+
+    private AbstractButton createFactoryChangeButton(final CompilationViewerFactory factory) {
+        JToggleButton toggleButton = new JToggleButton(factory.getName());
+        toggleButton.addActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                activateFactory(factory);
+            }
+        });
+        return toggleButton;
+    }
+
+    private CompilationViewer createViewer(CompilationViewerFactory activeFactory) {
+        InputGraph firstSnapshot = getFirstGraph();
+        InputGraph secondSnapshot = getSecondGraph();
+        return activeFactory.createViewer(firstSnapshot, secondSnapshot);
+    }
+
+    private void initializeToolBar(String id) {
+        viewerToolBar.removeAll();
+        for (Action a : LookupUtils.lookupActions(String.format("CompilationViewer/%s/Actions", id), activeViewer.getLookup())) {
+            if (a instanceof Presenter.Toolbar) {
+                viewerToolBar.add(((Presenter.Toolbar) a).getToolbarPresenter());
+            } else {
+                viewerToolBar.add(a);
+            }
+        }
+        viewerToolBar.updateUI();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/src/com/oracle/graal/visualizer/editor/GraphViewerImplementation.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2008, 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.visualizer.editor;
+
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.services.GraphViewer;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class GraphViewerImplementation implements GraphViewer {
+
+    @Override
+    public void view(InputGraph graph) {
+        EditorTopComponent tc = new EditorTopComponent(graph);
+        tc.open();
+        tc.requestActive();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/src/com/oracle/graal/visualizer/editor/NodeQuickSearch.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2008, 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.visualizer.editor;
+
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher;
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+import org.netbeans.spi.quicksearch.SearchProvider;
+import org.netbeans.spi.quicksearch.SearchRequest;
+import org.netbeans.spi.quicksearch.SearchResponse;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.NotifyDescriptor.Message;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class NodeQuickSearch implements SearchProvider {
+
+    private static final String DEFAULT_PROPERTY = "name";
+
+    /**
+     * Method is called by infrastructure when search operation was requested.
+     * Implementors should evaluate given request and fill response object with
+     * apropriate results
+     *
+     * @param request Search request object that contains information what to search for
+     * @param response Search response object that stores search results. Note that it's important to react to return value of SearchResponse.addResult(...) method and stop computation if false value is returned.
+     */
+    @Override
+    public void evaluate(SearchRequest request, SearchResponse response) {
+        String query = request.getText();
+        if (query.trim().isEmpty()) {
+            return;
+        }
+
+        final String[] parts = query.split("=", 2);
+
+        String name;
+        String value;
+
+        if (parts.length == 1) {
+            name = DEFAULT_PROPERTY;
+            value = ".*" + Pattern.quote(parts[0]) + ".*";
+        } else {
+            name = parts[0];
+            value = parts[1];
+        }
+
+        if (value.isEmpty()) {
+            value = ".*";
+        }
+
+        final InputGraphProvider p = null;// TODO: FIXME LookupHistory.getLast(InputGraphProvider.class);
+        if (p != null && p.getGraph() != null) {
+            List<InputNode> matches = null;
+            try {
+                RegexpPropertyMatcher matcher = new RegexpPropertyMatcher(name, value, Pattern.CASE_INSENSITIVE);
+                Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<>(p.getGraph().getNodes());
+
+                matches = selector.selectMultiple(matcher);
+            } catch (Exception e) {
+                final String msg = e.getMessage();
+                response.addResult(new Runnable() {
+                    @Override
+                        public void run() {
+                            Message desc = new NotifyDescriptor.Message("An exception occurred during the search, "
+                                    + "perhaps due to a malformed query string:\n" + msg,
+                                    NotifyDescriptor.WARNING_MESSAGE);
+                            DialogDisplayer.getDefault().notify(desc);
+                        }
+                    },
+                    "(Error during search)"
+                );
+            }
+
+            if (matches != null) {
+                final Set<InputNode> set = new HashSet<>(matches);
+                response.addResult(new Runnable() {
+                    @Override
+                        public void run() {
+                            final EditorTopComponent comp = EditorTopComponent.getActive();
+                            if (comp != null) {
+                                // TODO: find connection again!
+                                //comp.setSelectedNodes(set);
+                                comp.requestActive();
+                            }
+                        }
+                    },
+                    "All " + matches.size() + " matching nodes (" + name + "=" + value + ")"
+                );
+
+                // Single matches
+                for (final InputNode n : matches) {
+                    response.addResult(new Runnable() {
+                        @Override
+                            public void run() {
+                                final EditorTopComponent comp = EditorTopComponent.getActive();
+                                if (comp != null) {
+                                    final Set<InputNode> tmpSet = new HashSet<>();
+                                    tmpSet.add(n);
+                                    // TODO: find connection again!
+                                    //comp.setSelectedNodes(tmpSet);
+                                    comp.requestActive();
+                                }
+                            }
+                        },
+                        n.getProperties().get(name) + " (" + n.getId() + " " + n.getProperties().get("name") + ")"
+                    );
+                }
+            }
+        } else {
+            System.out.println("no input graph provider!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/src/com/oracle/graal/visualizer/editor/SplitCompilationViewer.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,95 @@
+/*
+ * 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.visualizer.editor;
+
+import com.sun.hotspot.igv.graph.Figure;
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.Collection;
+import java.util.prefs.Preferences;
+import javax.swing.JPanel;
+import javax.swing.JSplitPane;
+import javax.swing.JToolBar;
+import org.openide.util.Lookup;
+import org.openide.util.NbPreferences;
+import org.openide.util.lookup.Lookups;
+import org.openide.util.lookup.ProxyLookup;
+
+class SplitCompilationViewer implements CompilationViewer {
+
+    private JSplitPane splitPane;
+    private Component firstPanel;
+    private Component secondPanel;
+    private Lookup combinedLookup;
+    private static final String DIVIDER_LOCATION = "dividerLocation";
+    private final PropertyChangeListener splitChanged = new PropertyChangeListener() {
+
+        @Override
+        public void propertyChange(PropertyChangeEvent changeEvent) {
+            String propertyName = changeEvent.getPropertyName();
+            if (propertyName.equals(JSplitPane.DIVIDER_LOCATION_PROPERTY)) {
+                setLastDividerLocation((Integer) changeEvent.getNewValue());
+            }
+        }
+    };
+
+    private static void setLastDividerLocation(int pos) {
+        NbPreferences.forModule(SplitCompilationViewer.class).put(DIVIDER_LOCATION, Integer.toString(pos));
+    }
+
+    private static int getLastDividerLocation() {
+        try {
+            return Integer.parseInt(NbPreferences.forModule(SplitCompilationViewer.class).get(DIVIDER_LOCATION, "400"));
+        } catch (NumberFormatException e) {
+            return 400;
+        }
+    }
+
+    public SplitCompilationViewer(CompilationViewer firstViewer, CompilationViewer secondViewer) {
+        splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
+        firstPanel = createComponent(firstViewer);
+        secondPanel = createComponent(secondViewer);
+        splitPane.add(firstPanel);
+        splitPane.add(secondPanel);
+        splitPane.addPropertyChangeListener(splitChanged);
+        splitPane.setDividerLocation(getLastDividerLocation());
+        combinedLookup = new ProxyLookup(firstViewer.getLookup(), secondViewer.getLookup());
+    }
+
+    @Override
+    public Lookup getLookup() {
+        return combinedLookup;
+    }
+
+    @Override
+    public Component getComponent() {
+        return splitPane;
+    }
+
+    private Component createComponent(CompilationViewer viewer) {
+        return viewer.getComponent();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/src/com/oracle/graal/visualizer/editor/SplitCompilationViewerFactory.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * 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.visualizer.editor;
+
+import com.sun.hotspot.igv.data.InputGraph;
+
+public abstract class SplitCompilationViewerFactory implements CompilationViewerFactory {
+
+    @Override
+    public CompilationViewer createViewer(InputGraph firstGraph, InputGraph secondGraph) {
+        if (firstGraph == secondGraph) {
+            return createViewer(firstGraph);
+        } else {
+            CompilationViewer firstViewer = createViewer(firstGraph);
+            CompilationViewer secondViewer = createViewer(secondGraph);
+            return new SplitCompilationViewer(firstViewer, secondViewer);
+        }
+    }
+
+    protected abstract CompilationViewer createViewer(InputGraph graph);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Editor/src/com/oracle/graal/visualizer/editor/layer.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
+<filesystem>
+    <folder name="QuickSearch">
+        <folder name="Nodes">
+            <attr name="command" stringvalue="n"/>
+            <attr name="position" intvalue="0"/>
+            <file name="com-oracle-graal-visualizer-editor-NodeQuickSearch.instance"/>
+        </folder>
+    </folder>
+    
+    <folder name="QuickSearchShadow">
+        <file name="org-netbeans-modules-quicksearch-QuickSearchAction.shadow">
+            <attr name="originalFile" stringvalue="Actions/Edit/org-netbeans-modules-quicksearch-QuickSearchAction.instance"/>
+        </file>    
+    </folder>
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.filter" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.filter.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.filter
+OpenIDE-Module-Layer: com/sun/hotspot/igv/filter/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/filter/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.filter-impl" basedir="..">
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+        <condition>
+            <not>
+                <available file="${harness.dir}" type="dir"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=7c032ebf
+build.xml.script.CRC32=3b022a25
+build.xml.stylesheet.CRC32=79c3b980
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=7c032ebf
+nbproject/build-impl.xml.script.CRC32=26513f91
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/nbproject/platform.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.javahelp,\
+    org.netbeans.modules.masterfs,\
+    org.netbeans.modules.options.keymap,\
+    org.netbeans.modules.sendopts,\
+    org.netbeans.modules.templates,\
+    org.openide.compat,\
+    org.openide.execution,\
+    org.openide.util.enumerations
+enabled.clusters=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.filter</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.layout</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.jdesktop.layout</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.16.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.30.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.dialogs</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.18.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.filesystems</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.46.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.nodes</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.20.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.39.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.sun.hotspot.igv.filter</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/AbstractFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1998, 2007, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.data.Properties;
+import org.openide.cookies.OpenCookie;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public abstract class AbstractFilter implements Filter {
+
+    private ChangedEvent<Filter> changedEvent;
+    private Properties properties;
+
+    public AbstractFilter() {
+        changedEvent = new ChangedEvent<Filter>(this);
+        properties = new Properties();
+    }
+
+    @Override
+    public Properties getProperties() {
+        return properties;
+    }
+
+    @Override
+    public OpenCookie getEditor() {
+        return null;
+    }
+
+    @Override
+    public ChangedEvent<Filter> getChangedEvent() {
+        return changedEvent;
+    }
+
+    protected void fireChangedEvent() {
+        changedEvent.fire();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,11 @@
+OpenIDE-Module-Name=Filter
+
+jLabel1.text=Name\:
+jLabel2.text=Source\:
+
+nameTextField.text=
+
+jButton1.text=OK
+jButton2.text=Cancel
+
+title=Edit Filter Dialog
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/ColorFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.graph.Connection.ConnectionStyle;
+import com.sun.hotspot.igv.graph.*;
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ColorFilter extends AbstractFilter {
+
+    private List<ColorRule> colorRules;
+    private String name;
+
+    public ColorFilter(String name) {
+        this.name = name;
+        colorRules = new ArrayList<>();
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void apply(Diagram diagram) {
+
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(diagram.getFigures());
+        for (ColorRule rule : colorRules) {
+            if (rule.getSelector() != null) {
+                List<Figure> figures = rule.getSelector().selected(diagram);
+                for (Figure f : figures) {
+                    applyRule(rule, f);
+                    if (rule.getColor() != null) {
+                        f.setColor(rule.getColor());
+                    }
+                }
+            } else {
+                for (Figure f : diagram.getFigures()) {
+                    applyRule(rule, f);
+                }
+            }
+        }
+    }
+
+    private void applyRule(ColorRule rule, Figure f) {
+        if (rule.getColor() != null) {
+            f.setColor(rule.getColor());
+        }
+        Color color = rule.getLineColor();
+        ConnectionStyle style = rule.getLineStyle();
+
+        for (OutputSlot s : f.getOutputSlots()) {
+            for (Connection c : s.getConnections()) {
+                if (color != null) {
+                    c.setColor(color);
+                }
+
+                if (style != null) {
+                    c.setStyle(style);
+                }
+            }
+        }
+    }
+
+    public void addRule(ColorRule r) {
+        colorRules.add(r);
+    }
+
+    public static class ColorRule {
+
+        private Color color;
+        private Color lineColor;
+        private Connection.ConnectionStyle lineStyle;
+        private Selector selector;
+
+        public ColorRule(Selector selector, Color c) {
+            this(selector, c, null, null);
+        }
+
+        public ColorRule(Selector selector, Color c, Color lineColor, Connection.ConnectionStyle lineStyle) {
+            this.selector = selector;
+            this.color = c;
+            this.lineColor = lineColor;
+            this.lineStyle = lineStyle;
+
+        }
+
+        public ColorRule(Color c) {
+            this(null, c);
+        }
+
+        public Color getColor() {
+            return color;
+        }
+
+        public Selector getSelector() {
+            return selector;
+        }
+
+        public Color getLineColor() {
+            return lineColor;
+        }
+
+        public Connection.ConnectionStyle getLineStyle() {
+            return lineStyle;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/CombineFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Properties.PropertyMatcher;
+import com.sun.hotspot.igv.graph.*;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class CombineFilter extends AbstractFilter {
+
+    private List<CombineRule> rules;
+    private String name;
+
+    public CombineFilter(String name) {
+        this.name = name;
+        rules = new ArrayList<>();
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void apply(Diagram diagram) {
+
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(diagram.getFigures());
+        for (CombineRule r : rules) {
+
+            List<Figure> list = selector.selectMultiple(r.getFirstMatcher());
+            Set<Figure> figuresToRemove = new HashSet<>();
+            for (Figure f : list) {
+
+                List<Figure> successors = new ArrayList<>(f.getSuccessors());
+                if (r.isReversed()) {
+                    if (successors.size() == 1) {
+                        Figure succ = successors.get(0);
+                        InputSlot slot = null;
+
+                        for (InputSlot s : succ.getInputSlots()) {
+                            for (Connection c : s.getConnections()) {
+                                if (c.getOutputSlot().getFigure() == f) {
+                                    slot = s;
+                                }
+                            }
+                        }
+
+                        slot.getSource().addSourceNodes(f.getSource());
+                        if (r.getShortProperty() != null) {
+                            String s = f.getProperties().get(r.getShortProperty());
+                            if (s != null && s.length() > 0) {
+                                slot.setShortName(s);
+                                slot.setText(s);
+                                slot.setColor(f.getColor());
+                            }
+                        } else {
+                            assert slot != null;
+                            slot.setText(f.getProperties().get("dump_spec"));
+                            if (f.getProperties().get("short_name") != null) {
+                                slot.setShortName(f.getProperties().get("short_name"));
+                            } else {
+                                String s = f.getProperties().get("dump_spec");
+                                if (s != null && s.length() <= 5) {
+                                    slot.setShortName(s);
+                                }
+                            }
+                        }
+
+                        for (InputSlot s : f.getInputSlots()) {
+                            for (Connection c : s.getConnections()) {
+                                Connection newConn = diagram.createConnection(slot, c.getOutputSlot(), c.getLabel());
+                                newConn.setColor(c.getColor());
+                                newConn.setStyle(c.getStyle());
+                            }
+                        }
+
+                        figuresToRemove.add(f);
+                    }
+                } else {
+
+                    for (Figure succ : successors) {
+                        if (succ.getPredecessors().size() == 1 && succ.getInputSlots().size() == 1) {
+                            if (succ.getProperties().selectSingle(r.getSecondMatcher()) != null && succ.getOutputSlots().size() == 1) {
+
+
+                                OutputSlot oldSlot = null;
+                                for (OutputSlot s : f.getOutputSlots()) {
+                                    for (Connection c : s.getConnections()) {
+                                        if (c.getInputSlot().getFigure() == succ) {
+                                            oldSlot = s;
+                                        }
+                                    }
+                                }
+
+                                assert oldSlot != null;
+
+                                OutputSlot nextSlot = succ.getOutputSlots().get(0);
+                                int pos = 0;
+                                if (succ.getProperties().get("con") != null) {
+                                    pos = Integer.parseInt(succ.getProperties().get("con"));
+                                }
+                                OutputSlot slot = f.createOutputSlot(pos);
+                                slot.getSource().addSourceNodes(succ.getSource());
+                                if (r.getShortProperty() != null) {
+                                    String s = succ.getProperties().get(r.getShortProperty());
+                                    if (s != null && s.length() > 0) {
+                                        slot.setShortName(s);
+                                        slot.setText(s);
+                                        slot.setColor(succ.getColor());
+                                    }
+                                } else {
+                                    slot.setText(succ.getProperties().get("dump_spec"));
+                                    if (succ.getProperties().get("short_name") != null) {
+                                        slot.setShortName(succ.getProperties().get("short_name"));
+                                    } else {
+                                        String s = succ.getProperties().get("dump_spec");
+                                        if (s != null && s.length() <= 2) {
+                                            slot.setShortName(s);
+                                        } else {
+                                            String tmpName = succ.getProperties().get("name");
+                                            if (tmpName != null && tmpName.length() > 0) {
+                                                slot.setShortName(tmpName.substring(0, 1));
+                                            }
+                                        }
+                                    }
+                                }
+                                for (Connection c : nextSlot.getConnections()) {
+                                    Connection newConn = diagram.createConnection(c.getInputSlot(), slot, c.getLabel());
+                                    newConn.setColor(c.getColor());
+                                    newConn.setStyle(c.getStyle());
+                                }
+
+
+                                figuresToRemove.add(succ);
+
+                                if (oldSlot.getConnections().size() == 0) {
+                                    f.removeSlot(oldSlot);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            diagram.removeAllFigures(figuresToRemove);
+        }
+    }
+
+    public void addRule(CombineRule combineRule) {
+        rules.add(combineRule);
+    }
+
+    public static class CombineRule {
+
+        private PropertyMatcher first;
+        private PropertyMatcher second;
+        private boolean reversed;
+        private String shortProperty;
+
+        public CombineRule(PropertyMatcher first, PropertyMatcher second) {
+            this(first, second, false);
+
+        }
+
+        public CombineRule(PropertyMatcher first, PropertyMatcher second, boolean reversed) {
+            this(first, second, reversed, null);
+        }
+
+        public CombineRule(PropertyMatcher first, PropertyMatcher second, boolean reversed, String shortProperty) {
+            this.first = first;
+            this.second = second;
+            this.reversed = reversed;
+            this.shortProperty = shortProperty;
+        }
+
+        public boolean isReversed() {
+            return reversed;
+        }
+
+        public PropertyMatcher getFirstMatcher() {
+            return first;
+        }
+
+        public PropertyMatcher getSecondMatcher() {
+            return second;
+        }
+
+        public String getShortProperty() {
+            return shortProperty;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/ConnectionFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.graph.*;
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ConnectionFilter extends AbstractFilter {
+
+    private List<ConnectionStyleRule> connectionStyleRules;
+    private String name;
+
+    public ConnectionFilter(String name) {
+        this.name = name;
+        connectionStyleRules = new ArrayList<>();
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void apply(Diagram diagram) {
+
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(diagram.getFigures());
+        for (ConnectionStyleRule rule : connectionStyleRules) {
+            List<Figure> figures = null;
+            if (rule.getSelector() != null) {
+                figures = rule.getSelector().selected(diagram);
+            } else {
+                figures = diagram.getFigures();
+            }
+
+            for (Figure f : figures) {
+                for (OutputSlot os : f.getOutputSlots()) {
+                    for (Connection c : os.getConnections()) {
+                        if (figures.contains(c.getInputSlot().getFigure())) {
+                            c.setStyle(rule.getLineStyle());
+                            c.setColor(rule.getLineColor());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void addRule(ConnectionStyleRule r) {
+        connectionStyleRules.add(r);
+    }
+
+    public static class ConnectionStyleRule {
+
+        private Color lineColor;
+        private Connection.ConnectionStyle lineStyle;
+        private Selector selector;
+
+        public ConnectionStyleRule(Selector selector, Color lineColor, Connection.ConnectionStyle lineStyle) {
+            this.selector = selector;
+            this.lineColor = lineColor;
+            this.lineStyle = lineStyle;
+        }
+
+        public Selector getSelector() {
+            return selector;
+        }
+
+        public Color getLineColor() {
+            return lineColor;
+        }
+
+        public Connection.ConnectionStyle getLineStyle() {
+            return lineStyle;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/CustomFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 1998, 2008, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.graph.Diagram;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.script.*;
+import org.openide.cookies.OpenCookie;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.util.Exceptions;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class CustomFilter extends AbstractFilter {
+
+    public static final String JAVASCRIPT_HELPER_ID = "JavaScriptHelper";
+    private String code;
+    private String name;
+
+    public CustomFilter(String name, String code) {
+        this.name = name;
+        this.code = code;
+        getProperties().setProperty("name", name);
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setName(String s) {
+        name = s;
+        fireChangedEvent();
+    }
+
+    public void setCode(String s) {
+        code = s;
+        fireChangedEvent();
+    }
+
+    @Override
+    public OpenCookie getEditor() {
+        return new OpenCookie() {
+
+            @Override
+            public void open() {
+                openInEditor();
+            }
+        };
+    }
+
+    public boolean openInEditor() {
+        EditFilterDialog dialog = new EditFilterDialog(CustomFilter.this);
+        dialog.setVisible(true);
+        boolean result = dialog.wasAccepted();
+        this.getChangedEvent().fire();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return getName();
+    }
+
+    private static String getJsHelperText() {
+        InputStream is = null;
+        StringBuilder sb = new StringBuilder("importPackage(Packages.com.sun.hotspot.igv.filter);importPackage(Packages.com.sun.hotspot.igv.graph);importPackage(Packages.com.sun.hotspot.igv.data);importPackage(Packages.com.sun.hotspot.igv.util);importPackage(java.awt);");
+        try {
+            FileObject fo = FileUtil.getConfigRoot().getFileObject(JAVASCRIPT_HELPER_ID);
+            is = fo.getInputStream();
+            BufferedReader r = new BufferedReader(new InputStreamReader(is));
+            String s;
+            while ((s = r.readLine()) != null) {
+                sb.append(s);
+                sb.append("\n");
+            }
+
+        } catch (IOException ex) {
+            Logger.getLogger("global").log(Level.SEVERE, null, ex);
+        } finally {
+            try {
+                is.close();
+            } catch (IOException ex) {
+                Exceptions.printStackTrace(ex);
+            }
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        try {
+            ScriptEngineManager sem = new ScriptEngineManager();
+            ScriptEngine e = sem.getEngineByName("ECMAScript");
+            e.eval(getJsHelperText());
+            Bindings b = e.getContext().getBindings(ScriptContext.ENGINE_SCOPE);
+            b.put("graph", d);
+            b.put("IO", System.out);
+            e.eval(code, b);
+        } catch (ScriptException ex) {
+            Exceptions.printStackTrace(ex);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/EdgeColorIndexFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,77 @@
+/*
+ * 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.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.graph.*;
+import java.awt.Color;
+import java.util.List;
+
+public class EdgeColorIndexFilter extends AbstractFilter {
+
+    public static final String INPUTS = "INPUTS";
+    public static final String OUTPUTS = "OUTPUTS";
+    private final String applyTo;
+    private final Color[] colors;
+
+    public EdgeColorIndexFilter(String applyTo, Color... color) {
+        if (!applyTo.equals(INPUTS) && !applyTo.equals(OUTPUTS)) {
+            throw new IllegalArgumentException("applyTo");
+        }
+
+        this.applyTo = applyTo;
+        this.colors = color;
+    }
+
+    @Override
+    public String getName() {
+        return "Edge Color Index Filter";
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        List<Figure> figures = d.getFigures();
+        for (Figure f : figures) {
+            Slot[] slots;
+            if (applyTo.equals(INPUTS)) {
+                List<InputSlot> inputSlots = f.getInputSlots();
+                slots = inputSlots.toArray(new Slot[inputSlots.size()]);
+            } else {
+                List<OutputSlot> outputSlots = f.getOutputSlots();
+                slots = outputSlots.toArray(new Slot[outputSlots.size()]);
+            }
+            int index = 0;
+            for (Slot slot : slots) {
+                if (index < colors.length && colors[index] != null) {
+                    slot.setColor(colors[index]);
+                    for (Connection c : slot.getConnections()) {
+
+                        c.setColor(colors[index]);
+                    }
+                }
+                index++;
+            }
+
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/EditFilterDialog.form	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
+  <Properties>
+    <Property name="defaultCloseOperation" type="int" value="2"/>
+    <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+      <ResourceString bundle="at/ssw/graphanalyzer/filter/Bundle.properties" key="title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+    </Property>
+    <Property name="resizable" type="boolean" value="false"/>
+  </Properties>
+  <SyntheticProperties>
+    <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+  </SyntheticProperties>
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="102" alignment="1" attributes="0">
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Component id="sourceLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                          <Component id="nameLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                      </Group>
+                      <EmptySpace min="-2" pref="25" max="-2" attributes="0"/>
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Component id="jScrollPane1" pref="695" max="32767" attributes="1"/>
+                          <Component id="nameTextField" alignment="0" pref="695" max="32767" attributes="1"/>
+                      </Group>
+                  </Group>
+                  <Group type="102" alignment="1" attributes="0">
+                      <Component id="okButton" min="-2" pref="76" max="-2" attributes="0"/>
+                      <EmptySpace max="-2" attributes="0"/>
+                      <Component id="cancelButton" min="-2" max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="nameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="nameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Component id="sourceLabel" min="-2" max="-2" attributes="0"/>
+                  <Component id="jScrollPane1" min="-2" pref="337" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace pref="16" max="32767" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="okButton" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JScrollPane" name="jScrollPane1">
+      <AuxValues>
+        <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+      </AuxValues>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+      <SubComponents>
+        <Component class="javax.swing.JTextArea" name="sourceTextArea">
+          <Properties>
+            <Property name="columns" type="int" value="20"/>
+            <Property name="rows" type="int" value="5"/>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Component class="javax.swing.JTextField" name="nameTextField">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="at/ssw/graphanalyzer/coordinator/Bundle.properties" key="nameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="nameLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="at/ssw/graphanalyzer/filter/Bundle.properties" key="jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="sourceLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="at/ssw/graphanalyzer/filter/Bundle.properties" key="jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JButton" name="okButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="at/ssw/graphanalyzer/filter/Bundle.properties" key="jButton1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonClicked,okButtonClicked"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JButton" name="cancelButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="at/ssw/graphanalyzer/filter/Bundle.properties" key="jButton2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonClicked"/>
+      </Events>
+    </Component>
+  </SubComponents>
+</Form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/EditFilterDialog.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 1998, 2007, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.filter;
+
+import org.openide.windows.WindowManager;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class EditFilterDialog extends javax.swing.JDialog {
+
+    private CustomFilter customFilter;
+    private boolean accepted;
+
+    /** Creates new form EditFilterDialog */
+    public EditFilterDialog(CustomFilter customFilter) {
+        super(WindowManager.getDefault().getMainWindow(), true);
+        this.customFilter = customFilter;
+        initComponents();
+
+        sourceTextArea.setText(customFilter.getCode());
+        nameTextField.setText(customFilter.getName());
+    }
+
+    public boolean wasAccepted() {
+        return accepted;
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        jScrollPane1 = new javax.swing.JScrollPane();
+        sourceTextArea = new javax.swing.JTextArea();
+        nameTextField = new javax.swing.JTextField();
+        nameLabel = new javax.swing.JLabel();
+        sourceLabel = new javax.swing.JLabel();
+        okButton = new javax.swing.JButton();
+        cancelButton = new javax.swing.JButton();
+
+        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+        setTitle(org.openide.util.NbBundle.getMessage(EditFilterDialog.class, "title")); // NOI18N
+        setResizable(false);
+
+        sourceTextArea.setColumns(20);
+        sourceTextArea.setRows(5);
+        jScrollPane1.setViewportView(sourceTextArea);
+
+        nameTextField.setText("null");
+
+        nameLabel.setText(org.openide.util.NbBundle.getMessage(EditFilterDialog.class, "jLabel1.text")); // NOI18N
+
+        sourceLabel.setText(org.openide.util.NbBundle.getMessage(EditFilterDialog.class, "jLabel2.text")); // NOI18N
+
+        okButton.setText(org.openide.util.NbBundle.getMessage(EditFilterDialog.class, "jButton1.text")); // NOI18N
+        okButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                cancelButtonClicked(evt);
+                okButtonClicked(evt);
+            }
+        });
+
+        cancelButton.setText(org.openide.util.NbBundle.getMessage(EditFilterDialog.class, "jButton2.text")); // NOI18N
+        cancelButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                cancelButtonClicked(evt);
+            }
+        });
+
+        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
+        getContentPane().setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+            .add(layout.createSequentialGroup()
+                .addContainerGap()
+                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
+                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                            .add(sourceLabel)
+                            .add(nameLabel))
+                        .add(25, 25, 25)
+                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                            .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 695, Short.MAX_VALUE)
+                            .add(nameTextField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 695, Short.MAX_VALUE)))
+                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
+                        .add(okButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 76, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
+                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
+                        .add(cancelButton)))
+                .addContainerGap())
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+            .add(layout.createSequentialGroup()
+                .addContainerGap()
+                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
+                    .add(nameLabel)
+                    .add(nameTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
+                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
+                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                    .add(sourceLabel)
+                    .add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 337, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
+                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 16, Short.MAX_VALUE)
+                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
+                    .add(cancelButton)
+                    .add(okButton))
+                .addContainerGap())
+        );
+
+        pack();
+    }// </editor-fold>//GEN-END:initComponents
+
+private void okButtonClicked(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonClicked
+	this.customFilter.setName(this.nameTextField.getText());
+	this.customFilter.setCode(this.sourceTextArea.getText());
+	accepted = true;
+	setVisible(false);
+}//GEN-LAST:event_okButtonClicked
+
+private void cancelButtonClicked(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonClicked
+	setVisible(false);
+}//GEN-LAST:event_cancelButtonClicked
+	
+	
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton cancelButton;
+    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JLabel nameLabel;
+    private javax.swing.JTextField nameTextField;
+    private javax.swing.JButton okButton;
+    private javax.swing.JLabel sourceLabel;
+    private javax.swing.JTextArea sourceTextArea;
+    // End of variables declaration//GEN-END:variables
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/Filter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.data.ChangedEventProvider;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.graph.Diagram;
+import org.openide.cookies.OpenCookie;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface Filter extends Properties.Provider, ChangedEventProvider<Filter> {
+
+    public String getName();
+
+    public void apply(Diagram d);
+
+    OpenCookie getEditor();
+
+    @Override
+    ChangedEvent<Filter> getChangedEvent();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/FilterChain.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.data.ChangedEventProvider;
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.graph.Diagram;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class FilterChain implements ChangedEventProvider<FilterChain> {
+
+    private List<Filter> filters;
+    private transient ChangedEvent<FilterChain> changedEvent;
+    
+    private ChangedListener<Filter> changedListener = new ChangedListener<Filter>() {
+        @Override
+        public void changed(Filter source) {
+            changedEvent.fire();
+        }
+    };
+
+    public FilterChain() {
+        filters = new ArrayList<>();
+        changedEvent = new ChangedEvent<>(this);
+    }
+
+    public FilterChain(FilterChain f) {
+        this.filters = new ArrayList<>(f.filters);
+        changedEvent = new ChangedEvent<>(this);
+    }
+
+    @Override
+    public ChangedEvent<FilterChain> getChangedEvent() {
+        return changedEvent;
+    }
+
+    public Filter getFilterAt(int index) {
+        assert index >= 0 && index < filters.size();
+        return filters.get(index);
+    }
+
+    public void apply(Diagram d) {
+        for (Filter f : filters) {
+            f.apply(d);
+        }
+    }
+
+    public void apply(Diagram d, FilterChain sequence) {
+        List<Filter> applied = new ArrayList<>();
+        for (Filter f : sequence.getFilters()) {
+            if (filters.contains(f)) {
+                f.apply(d);
+                applied.add(f);
+            }
+        }
+
+
+        for (Filter f : filters) {
+            if (!applied.contains(f)) {
+                f.apply(d);
+            }
+        }
+    }
+
+
+    public void addFilter(Filter filter) {
+        assert filter != null;
+        filters.add(filter);
+        filter.getChangedEvent().addListener(changedListener);
+        changedEvent.fire();
+    }
+
+    public boolean containsFilter(Filter filter) {
+        return filters.contains(filter);
+    }
+
+    public void removeFilter(Filter filter) {
+        assert filters.contains(filter);
+        filters.remove(filter);
+        filter.getChangedEvent().removeListener(changedListener);
+        changedEvent.fire();
+    }
+
+    public void moveFilterUp(Filter filter) {
+        assert filters.contains(filter);
+        int index = filters.indexOf(filter);
+        if (index != 0) {
+            filters.remove(index);
+            filters.add(index - 1, filter);
+        }
+        changedEvent.fire();
+    }
+
+    public void moveFilterDown(Filter filter) {
+        assert filters.contains(filter);
+        int index = filters.indexOf(filter);
+        if (index != filters.size() - 1) {
+            filters.remove(index);
+            filters.add(index + 1, filter);
+        }
+        changedEvent.fire();
+    }
+
+    public List<Filter> getFilters() {
+        return Collections.unmodifiableList(filters);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/FilterChainProvider.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filter;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface FilterChainProvider {
+
+    public FilterChain getFilterChain();
+
+    public FilterChain getSequence();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/FilterSetting.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filter;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class FilterSetting {
+
+    private Set<Filter> filters;
+    private String name;
+
+    public FilterSetting() {
+        this(null);
+    }
+
+    public FilterSetting(String name) {
+        this.name = name;
+        filters = new HashSet<>();
+    }
+
+    public Set<Filter> getFilters() {
+        return Collections.unmodifiableSet(filters);
+    }
+
+    public void addFilter(Filter f) {
+        assert !filters.contains(f);
+        filters.add(f);
+    }
+
+    public void removeFilter(Filter f) {
+        assert filters.contains(f);
+        filters.remove(f);
+    }
+
+    public boolean containsFilter(Filter f) {
+        return filters.contains(f);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getFilterCount() {
+        return filters.size();
+    }
+
+    @Override
+    public String toString() {
+        return getName();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/GradientColorFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,161 @@
+/*
+ * 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.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.Figure;
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import java.awt.image.Raster;
+import java.util.List;
+
+/**
+ * Filter that colors nodes using a customizable color gradient, based on how
+ * a numeric property is located in a specified interval.
+ * 
+ * @author Peter Hofer
+ */
+public class GradientColorFilter extends AbstractFilter {
+
+    public static final String LINEAR = "LINEAR";
+    public static final String LOGARITHMIC = "LOGARITHMIC";
+
+    private String propertyName = "probability";
+    private float minValue = 0;
+    private float maxValue = 500;
+    private float[] fractions = {0, 0.5f, 1};
+    private Color[] colors = {Color.BLUE, Color.YELLOW, Color.RED};
+    private int shadeCount = 8;
+    private String mode = LINEAR;
+
+    @Override
+    public String getName() {
+        return "Gradient Color Filter";
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        boolean logarithmic = mode.equalsIgnoreCase(LOGARITHMIC);
+        if (!logarithmic && !mode.equalsIgnoreCase(LINEAR)) {
+            throw new RuntimeException("Unknown mode: " + mode);
+        }
+
+        Rectangle bounds = new Rectangle(shadeCount, 1);
+        LinearGradientPaint lgp = new LinearGradientPaint(bounds.x, bounds.y, bounds.width, bounds.y, fractions, colors);
+        PaintContext context = lgp.createContext(null, bounds, bounds.getBounds2D(), AffineTransform.getTranslateInstance(0, 0), new RenderingHints(null));
+        Raster raster = context.getRaster(bounds.x, bounds.y, bounds.width, bounds.height);
+        int[] rgb = raster.getPixels(bounds.x, bounds.y, bounds.width, bounds.height, (int[]) null);
+        Color[] shades = new Color[rgb.length / 3];
+        for (int i = 0; i < shades.length; ++i) {
+            shades[i] = new Color(rgb[i * 3], rgb[i * 3 + 1], rgb[i * 3 + 2]);
+        }
+
+        List<Figure> figures = d.getFigures();
+        for (Figure f : figures) {
+            String property = f.getProperties().get(propertyName);
+            if (property != null) {
+                try {
+                    float value = Float.parseFloat(property);
+
+                    Color nodeColor;
+                    if (value <= minValue) {
+                        nodeColor = colors[0];
+                    } else if (value >= maxValue) {
+                        nodeColor = colors[colors.length - 1];
+                    } else {
+                        double normalized = value - minValue;
+                        double interval = maxValue - minValue;
+                        int index;
+                        // Use Math.ceil() to make values above zero distinguishable from zero
+                        if (logarithmic) {
+                            index = (int) Math.ceil(shades.length * Math.log(1 + normalized) / Math.log(1 + interval));
+                        } else {
+                            index = (int) Math.ceil(shades.length * normalized / interval);
+                        }
+                        nodeColor = shades[index];
+                    }
+                    f.setColor(nodeColor);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    public String getPropertyName() {
+        return propertyName;
+    }
+
+    public void setPropertyName(String propertyName) {
+        this.propertyName = propertyName;
+    }
+
+    public float getMinValue() {
+        return minValue;
+    }
+
+    public void setMinValue(float minValue) {
+        this.minValue = minValue;
+    }
+
+    public float getMaxValue() {
+        return maxValue;
+    }
+
+    public void setMaxValue(float maxValue) {
+        this.maxValue = maxValue;
+    }
+
+    public float[] getFractions() {
+        return fractions;
+    }
+
+    public void setFractions(float[] fractions) {
+        this.fractions = fractions;
+    }
+
+    public Color[] getColors() {
+        return colors;
+    }
+
+    public void setColors(Color[] colors) {
+        this.colors = colors;
+    }
+
+    public int getShadeCount() {
+        return shadeCount;
+    }
+
+    public void setShadeCount(int shadeCount) {
+        this.shadeCount = shadeCount;
+    }
+
+    public String getMode() {
+        return mode;
+    }
+
+    public void setMode(String mode) {
+        this.mode = mode;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.graph.Selector;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class RemoveFilter extends AbstractFilter {
+
+    private List<RemoveRule> rules;
+    private String name;
+
+    public RemoveFilter(String name) {
+        this.name = name;
+        rules = new ArrayList<>();
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void apply(Diagram diagram) {
+        for (RemoveRule r : rules) {
+            List<Figure> selected = r.getSelector().selected(diagram);
+            Set<Figure> toRemove = new HashSet<>(selected);
+
+            if (r.getRemoveOrphans()) {
+                boolean changed;
+                do {
+                    changed = false;
+                    for (Figure f : diagram.getFigures()) {
+                        if (!toRemove.contains(f)) {
+                            if (toRemove.containsAll(f.getPredecessors()) && toRemove.containsAll(f.getSuccessors())) {
+                                toRemove.add(f);
+                                changed = true;
+                            }
+                        }
+                    }
+                } while (changed);
+            }
+
+            diagram.removeAllFigures(toRemove);
+        }
+    }
+
+    public void addRule(RemoveRule rule) {
+        rules.add(rule);
+    }
+
+    public static class RemoveRule {
+
+        private Selector selector;
+        private boolean removeOrphans;
+
+        public RemoveRule(Selector selector) {
+            this(selector, false);
+        }
+
+        public RemoveRule(Selector selector, boolean removeOrphans) {
+            this.selector = selector;
+            this.removeOrphans = removeOrphans;
+        }
+
+        public Selector getSelector() {
+            return selector;
+        }
+
+        public boolean getRemoveOrphans() {
+            return removeOrphans;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveInputsFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.graph.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class RemoveInputsFilter extends AbstractFilter {
+
+    private List<RemoveInputsRule> rules;
+    private String name;
+
+    public RemoveInputsFilter(String name) {
+        this.name = name;
+        rules = new ArrayList<>();
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void apply(Diagram diagram) {
+
+        for (RemoveInputsRule r : rules) {
+
+            List<Figure> list = r.getSelector().selected(diagram);
+            for (Figure f : list) {
+                int z = 0;
+                List<InputSlot> last = new ArrayList<>();
+                for (InputSlot is : f.getInputSlots()) {
+                    if (z >= r.getStartingIndex() && z <= r.getEndIndex() && is.getConnections().size() > 0) {
+                        StringBuilder sb = new StringBuilder();
+                        List<Connection> conns = is.getConnections();
+                        for (int i = 0; i < conns.size(); i++) {
+                            Connection c = conns.get(i);
+                            OutputSlot os = c.getOutputSlot();
+                            Figure pred = os.getFigure();
+                            if (i != 0) {
+                                sb.append("<BR>");
+                            }
+                            sb.append(pred.getLines()[0]);
+                        }
+                        is.removeAllConnections();
+                        is.setShortName("X");
+                        is.setText(sb.toString());
+                        last.add(is);
+                    } else {
+                        last.clear();
+                    }
+                    z++;
+                }
+
+                if (last.size() > 3) {
+                    InputSlot first = last.get(0);
+                    first.setShortName("XX");
+
+                    StringBuilder sb = new StringBuilder();
+                    for (int i = 0; i < last.size(); i++) {
+                        InputSlot is2 = last.get(i);
+                        if (i != 0) {
+                            sb.append("<BR>");
+                        }
+                        sb.append(is2.getText());
+                    }
+
+                    first.setText(sb.toString());
+
+                    for (int i = 1; i < last.size(); i++) {
+                        f.removeSlot(last.get(i));
+                    }
+                }
+            }
+        }
+    }
+
+    public void addRule(RemoveInputsRule rule) {
+        rules.add(rule);
+    }
+
+    public static class RemoveInputsRule {
+
+        private Selector selector;
+        private int startingIndex;
+        private int endIndex;
+
+        public RemoveInputsRule(Selector selector) {
+            this(selector, 0);
+        }
+
+        public RemoveInputsRule(Selector selector, int startIndex) {
+            this(selector, startIndex, Integer.MAX_VALUE);
+        }
+
+        public RemoveInputsRule(Selector selector, int startIndex, int endIndex) {
+            this.startingIndex = startIndex;
+            this.endIndex = endIndex;
+            this.selector = selector;
+        }
+
+        public int getStartingIndex() {
+            return startingIndex;
+        }
+
+        public int getEndIndex() {
+            return endIndex;
+        }
+
+        public Selector getSelector() {
+            return selector;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveSelfLoopsFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.graph.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class RemoveSelfLoopsFilter extends AbstractFilter {
+
+    private String name;
+
+    /** Creates a new instance of RemoveSelfLoops */
+    public RemoveSelfLoopsFilter(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void apply(Diagram d) {
+
+        for (Figure f : d.getFigures()) {
+
+            for (InputSlot is : f.getInputSlots()) {
+
+                List<Connection> toRemove = new ArrayList<>();
+                for (Connection c : is.getConnections()) {
+
+                    if (c.getOutputSlot().getFigure() == f) {
+                        toRemove.add(c);
+                    }
+                }
+
+                for (Connection c : toRemove) {
+
+                    c.remove();
+
+                    OutputSlot os = c.getOutputSlot();
+                    if (os.getConnections().size() == 0) {
+                        f.removeSlot(os);
+                    }
+
+                    c.getInputSlot().setShortName("O");
+                    c.getInputSlot().setText("Self Loop");
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/SplitFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.graph.*;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class SplitFilter extends AbstractFilter {
+
+    private String name;
+    private Selector selector;
+    private String propertyName;
+
+    public SplitFilter(String name, Selector selector, String propertyName) {
+        this.name = name;
+        this.selector = selector;
+        this.propertyName = propertyName;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+    
+    @Override
+    public void apply(Diagram d) {
+        List<Figure> list = selector.selected(d);
+
+        for (Figure f : list) {
+            
+            for (InputSlot is : f.getInputSlots()) {
+                for (Connection c : is.getConnections()) {
+                    OutputSlot os = c.getOutputSlot();
+                    if (f.getSource().getSourceNodes().size() > 0) {
+                        os.getSource().addSourceNodes(f.getSource());
+                        os.setAssociatedNode(f.getSource().getSourceNodes().get(0));
+                        os.setColor(f.getColor());
+                    }
+
+
+                    String s = Figure.resolveString(propertyName, f.getProperties());
+                    if (s != null) {
+                        os.setShortName(s);
+                    }
+
+                }
+            }
+            for (OutputSlot os : f.getOutputSlots()) {
+                for (Connection c : os.getConnections()) {
+                    InputSlot is = c.getInputSlot();
+                    if (f.getSource().getSourceNodes().size() > 0) {
+                        is.getSource().addSourceNodes(f.getSource());
+                        is.setAssociatedNode(f.getSource().getSourceNodes().get(0));
+                        is.setColor(f.getColor());
+                    }
+
+                    String s = Figure.resolveString(propertyName, f.getProperties());
+                    if (s != null) {
+                        is.setShortName(s);
+                    }
+                }
+            }
+
+            d.removeFigure(f);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/UnconnectedSlotFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,76 @@
+/*
+ * 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.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.graph.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Filter that hides slots with no connections.
+ */
+public class UnconnectedSlotFilter extends AbstractFilter {
+
+    private final boolean removeInputs;
+    private final boolean removeOutputs;
+
+    public UnconnectedSlotFilter(boolean inputs, boolean outputs) {
+        this.removeInputs = inputs;
+        this.removeOutputs = outputs;
+    }
+
+    @Override
+    public String getName() {
+        return "Unconnected Slot Filter";
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        if (!removeInputs && !removeOutputs) {
+            return;
+        }
+
+        List<Figure> figures = d.getFigures();
+        for (Figure f : figures) {
+            List<Slot> remove = new ArrayList<>();
+            if (removeInputs) {
+                for (InputSlot is : f.getInputSlots()) {
+                    if (is.getConnections().isEmpty()) {
+                        remove.add(is);
+                    }
+                }
+            }
+            if (removeOutputs) {
+                for (OutputSlot os : f.getOutputSlots()) {
+                    if (os.getConnections().isEmpty()) {
+                        remove.add(os);
+                    }
+                }
+            }
+            for (Slot s : remove) {
+                f.removeSlot(s);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/helper.js	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2008, 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.
+ *
+ */
+ 
+ /**
+ *
+ * @author Thomas Wuerthinger
+ */
+ 
+function colorize(property, regexp, color) {
+    var f = new ColorFilter("");
+    f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), color));
+    f.apply(graph); 
+}
+
+function remove(property, regexp) {
+    var f = new RemoveFilter("");
+    f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp))));
+    f.apply(graph);
+}
+
+function removeIncludingOrphans(property, regexp) {
+    var f = new RemoveFilter("");
+    f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), true));
+    f.apply(graph);
+}
+
+function split(property, regexp, propertyName) {
+    if (propertyName == undefined) {
+        propertyName = graph.getNodeText();
+    }
+    var f = new SplitFilter("", new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), propertyName);
+    f.apply(graph);
+}
+
+function removeInputs(property, regexp, from, to) {
+    var f = new RemoveInputsFilter("");
+    if(from == undefined && to == undefined) {
+        f.addRule(new RemoveInputsFilter.RemoveInputsRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp))));
+    } else if(to == undefined) {
+        f.addRule(new RemoveInputsFilter.RemoveInputsRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), from));
+    } else {
+        f.addRule(new RemoveInputsFilter.RemoveInputsRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), from, to));
+    }
+    f.apply(graph);
+}
+
+function removeUnconnectedSlots(inputs, outputs) {
+    var f = new UnconnectedSlotFilter(inputs, outputs);
+    f.apply(graph);
+}
+
+function colorizeGradient(property, min, max) {
+    var f = new GradientColorFilter();
+    f.setPropertyName(property);
+    f.setMinValue(min);
+    f.setMaxValue(max);
+    f.apply(graph);
+}
+
+function colorizeGradientWithMode(property, min, max, mode) {
+    var f = new GradientColorFilter();
+    f.setPropertyName(property);
+    f.setMinValue(min);
+    f.setMaxValue(max);
+    f.setMode(mode);
+    f.apply(graph);
+}
+
+function colorizeGradientCustom(property, min, max, mode, colors, fractions, nshades) {
+    var f = new GradientColorFilter();
+    f.setPropertyName(property);
+    f.setMinValue(min);
+    f.setMaxValue(max);
+    f.setMode(mode);
+    f.setColors(colors);
+    f.setFractions(fractions);
+    f.setShadeCount(nshades);
+    f.apply(graph);
+}
+
+var black = Color.black;
+var blue = Color.blue;
+var cyan = Color.cyan;
+var darkGray = Color.darkGray;
+var gray = Color.gray;
+var green = Color.green;
+var lightGray = Color.lightGray;
+var magenta = Color.magenta;
+var orange = Color.orange;
+var pink = Color.pink
+var red = Color.red;
+var yellow = Color.yellow;
+var white = Color.white;
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Filter/src/com/sun/hotspot/igv/filter/layer.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
+<filesystem>
+        <file name="JavaScriptHelper" url="helper.js"/>
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.filterwindow" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.filterwindow.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.filterwindow
+OpenIDE-Module-Layer: com/sun/hotspot/igv/filterwindow/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/filterwindow/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.filterwindow-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,5 @@
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=09ba2a87
+nbproject/build-impl.xml.script.CRC32=e4293f0e
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.45.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.filterwindow</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.filter</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.actions</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.21.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.dialogs</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.18.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.explorer</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.34.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.filesystems</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.46.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.loaders</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.20.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.nodes</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.20.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.39.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages/>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/META-INF/services/com.sun.hotspot.igv.filter.FilterChainProvider	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+com.sun.hotspot.igv.filterwindow.FilterChainProviderImplementation
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,3 @@
+OpenIDE-Module-Name=FilterWindow
+CTL_FilterTopComponent=Filters
+HINT_FilterTopComponent=Allows to choose active filters and modify them.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckListView.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filterwindow;
+
+import javax.swing.JList;
+import org.openide.explorer.view.ListView;
+import org.openide.explorer.view.NodeListModel;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class CheckListView extends ListView {
+
+    @Override
+    public void showSelection(int[] indices) {
+        super.showSelection(indices);
+    }
+
+    @Override
+    protected NodeListModel createModel() {
+        return new CheckNodeListModel();
+    }
+
+    @Override
+    protected JList<Object> createList() {
+        JList<Object> tmpList = super.createList();
+        tmpList.setCellRenderer(new CheckRenderer(tmpList));
+        return tmpList;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filterwindow;
+
+import com.sun.hotspot.igv.data.ChangedEvent;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.util.Lookup;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class CheckNode extends AbstractNode {
+
+    private ChangedEvent<CheckNode> selectionChangedEvent;
+    public boolean selected;
+    public boolean enabled;
+
+    public CheckNode(Children c, Lookup lookup) {
+        super(c, lookup);
+        selectionChangedEvent = new ChangedEvent<>(this);
+        selected = false;
+        enabled = true;
+    }
+
+    public ChangedEvent<CheckNode> getSelectionChangedEvent() {
+        return selectionChangedEvent;
+    }
+
+    public boolean isSelected() {
+        return selected;
+    }
+
+    public void setSelected(boolean b) {
+        if (b != selected) {
+            selected = b;
+            selectionChangedEvent.fire();
+        }
+    }
+
+    public void setEnabled(boolean b) {
+        enabled = b;
+    }
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckNodeListModel.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filterwindow;
+
+import org.openide.explorer.view.NodeListModel;
+import org.openide.explorer.view.Visualizer;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class CheckNodeListModel extends NodeListModel {
+
+    public CheckNode getCheckNodeAt(int index) {
+        Object item = getElementAt(index);
+        if (item != null) {
+            return (CheckNode) Visualizer.findNode(item);
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckRenderer.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filterwindow;
+
+import java.awt.*;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import javax.swing.JCheckBox;
+import javax.swing.JList;
+import javax.swing.ListCellRenderer;
+
+/**
+ * @author Thomas Wuerthinger
+ */
+public class CheckRenderer extends JCheckBox implements ListCellRenderer<Object> {
+
+    private JList<Object> list;
+    private Color startBackground;
+
+    public CheckRenderer(final JList<Object> list) {
+        this.list = list;
+        list.addMouseListener(
+                new MouseAdapter() {
+
+                    @Override
+                    public void mouseClicked(MouseEvent e) {
+                        int index = list.locationToIndex(e.getPoint());
+                        Point p2 = list.indexToLocation(index);
+                        Rectangle r = new Rectangle(p2.x, p2.y, getPreferredSize().height, getPreferredSize().height);
+                        if (r.contains(e.getPoint())) {
+                            CheckNode node = ((CheckNodeListModel) list.getModel()).getCheckNodeAt(index);
+                            node.setSelected(!node.isSelected());
+                            list.repaint();
+                            e.consume();
+                        }
+                    }
+                });
+
+        this.setPreferredSize(new Dimension(getPreferredSize().width, getPreferredSize().height - 5));
+        startBackground = this.getBackground();
+    }
+
+    @Override
+    public Component getListCellRendererComponent(final JList<? extends Object> list, Object value, final int index, boolean isSelected, boolean cellHasFocus) {
+        setText(value.toString());
+        CheckNode node = ((CheckNodeListModel) list.getModel()).getCheckNodeAt(index);
+        this.setSelected(node.isSelected());
+        this.setEnabled(list.isEnabled());
+
+        if (isSelected && list.hasFocus()) {
+            this.setBackground(list.getSelectionBackground());
+            this.setForeground(list.getSelectionForeground());
+        } else if (isSelected) {
+            assert !list.hasFocus();
+            this.setBackground(startBackground);
+            this.setForeground(list.getForeground());
+
+        } else {
+            this.setBackground(list.getBackground());
+            this.setForeground(list.getForeground());
+        }
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterChainProviderImplementation.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filterwindow;
+
+import com.sun.hotspot.igv.filter.FilterChain;
+import com.sun.hotspot.igv.filter.FilterChainProvider;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class FilterChainProviderImplementation implements FilterChainProvider {
+
+    @Override
+    public FilterChain getFilterChain() {
+        return FilterTopComponent.findInstance().getFilterChain();
+    }
+
+    @Override
+    public FilterChain getSequence() {
+        return FilterTopComponent.findInstance().getSequence();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filterwindow;
+
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.filter.Filter;
+import com.sun.hotspot.igv.filter.FilterChain;
+import com.sun.hotspot.igv.filterwindow.actions.MoveFilterDownAction;
+import com.sun.hotspot.igv.filterwindow.actions.MoveFilterUpAction;
+import com.sun.hotspot.igv.filterwindow.actions.RemoveFilterAction;
+import com.sun.hotspot.igv.util.PropertiesSheet;
+import javax.swing.Action;
+import org.openide.actions.OpenAction;
+import org.openide.nodes.Children;
+import org.openide.nodes.Sheet;
+import org.openide.util.Lookup;
+import org.openide.util.LookupEvent;
+import org.openide.util.LookupListener;
+import org.openide.util.Utilities;
+import org.openide.util.lookup.AbstractLookup;
+import org.openide.util.lookup.InstanceContent;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class FilterNode extends CheckNode implements LookupListener, ChangedListener<FilterTopComponent> {
+
+    private Filter filter;
+    private Lookup.Result<FilterChain> result;
+
+    public FilterNode(Filter filter) {
+        this(filter, new InstanceContent());
+    }
+
+    private FilterNode(Filter filter, InstanceContent content) {
+        super(Children.LEAF, new AbstractLookup(content));
+        content.add(filter);
+
+        content.add(filter.getEditor());
+        this.filter = filter;
+        filter.getChangedEvent().addListener(new ChangedListener<Filter>() {
+
+            @Override
+            public void changed(Filter source) {
+                update();
+            }
+        });
+
+        update();
+
+        Lookup.Template<FilterChain> tpl = new Lookup.Template<>(FilterChain.class);
+        result = Utilities.actionsGlobalContext().lookup(tpl);
+        result.addLookupListener(this);
+
+        FilterTopComponent.findInstance().getFilterSettingsChangedEvent().addListener(this);
+        resultChanged(null);
+        
+        setShortDescription("Double-click to open filter");
+    }
+
+    private void update() {
+        this.setDisplayName(filter.getName());
+    }
+
+    public Filter getFilter() {
+        return filter;
+    }
+
+    @Override
+    protected Sheet createSheet() {
+        Sheet s = super.createSheet();
+        PropertiesSheet.initializeSheet(getFilter().getProperties(), s);
+        return s;
+    }
+
+    @Override
+    public Action[] getActions(boolean b) {
+        return new Action[]{(Action) OpenAction.findObject(OpenAction.class, true), (Action) MoveFilterUpAction.findObject(MoveFilterUpAction.class, true), (Action) MoveFilterDownAction.findObject(MoveFilterDownAction.class, true), (Action) RemoveFilterAction.findObject(RemoveFilterAction.class, true)};
+    }
+
+    @Override
+    public Action getPreferredAction() {
+        return OpenAction.get(OpenAction.class).createContextAwareInstance(Utilities.actionsGlobalContext());
+    }
+
+    @Override
+    public void resultChanged(LookupEvent lookupEvent) {
+        changed(FilterTopComponent.findInstance());
+    }
+
+    @Override
+    public void changed(FilterTopComponent source) {
+        setSelected(source.getFilterChain().containsFilter(filter));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponent.form	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+    <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
+  </AuxValues>
+
+  <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+</Form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponent.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,670 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filterwindow;
+
+import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.filter.CustomFilter;
+import com.sun.hotspot.igv.filter.Filter;
+import com.sun.hotspot.igv.filter.FilterChain;
+import com.sun.hotspot.igv.filter.FilterSetting;
+import com.sun.hotspot.igv.filterwindow.actions.*;
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.*;
+import java.util.*;
+import javax.swing.JComboBox;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
+import org.openide.DialogDisplayer;
+import org.openide.ErrorManager;
+import org.openide.NotifyDescriptor;
+import org.openide.awt.Toolbar;
+import org.openide.awt.ToolbarPool;
+import org.openide.explorer.ExplorerManager;
+import org.openide.explorer.ExplorerUtils;
+import org.openide.filesystems.FileLock;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.openide.util.*;
+import org.openide.util.actions.SystemAction;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
+
+/**
+ * 
+ * @author Thomas Wuerthinger
+ */
+public final class FilterTopComponent extends TopComponent implements LookupListener, ExplorerManager.Provider {
+
+    private static FilterTopComponent instance;
+    public static final String FOLDER_ID = "Filters";
+    public static final String AFTER_ID = "after";
+    public static final String ENABLED_ID = "enabled";
+    public static final String PREFERRED_ID = "FilterTopComponent";
+    private CheckListView view;
+    private ExplorerManager manager;
+    private FilterChain filterChain;
+    private FilterChain sequence;
+    private Lookup.Result<FilterChain> result;
+    private JComboBox comboBox;
+    private List<FilterSetting> filterSettings;
+    private FilterSetting customFilterSetting = new FilterSetting("-- Custom --");
+    private ChangedEvent<FilterTopComponent> filterSettingsChangedEvent;
+    private ActionListener comboBoxActionListener = new ActionListener() {
+
+        @Override
+        public void actionPerformed(ActionEvent e) {
+            comboBoxSelectionChanged();
+        }
+    };
+
+    public ChangedEvent<FilterTopComponent> getFilterSettingsChangedEvent() {
+        return filterSettingsChangedEvent;
+    }
+
+    public FilterChain getSequence() {
+        return sequence;
+    }
+
+    public void updateSelection() {
+        Node[] nodes = this.getExplorerManager().getSelectedNodes();
+        int[] arr = new int[nodes.length];
+        for (int i = 0; i < nodes.length; i++) {
+            int index = sequence.getFilters().indexOf(((FilterNode) nodes[i]).getFilter());
+            arr[i] = index;
+        }
+        view.showSelection(arr);
+    }
+
+    private void comboBoxSelectionChanged() {
+
+        Object o = comboBox.getSelectedItem();
+        if (o == null) {
+            return;
+        }
+        assert o instanceof FilterSetting;
+        FilterSetting s = (FilterSetting) o;
+
+        if (s != customFilterSetting) {
+            FilterChain chain = getFilterChain();
+            chain.getChangedEvent().beginAtomic();
+            List<Filter> toRemove = new ArrayList<>();
+            for (Filter f : chain.getFilters()) {
+                if (!s.containsFilter(f)) {
+                    toRemove.add(f);
+                }
+            }
+            for (Filter f : toRemove) {
+                chain.removeFilter(f);
+            }
+
+            for (Filter f : s.getFilters()) {
+                if (!chain.containsFilter(f)) {
+                    chain.addFilter(f);
+                }
+            }
+
+            chain.getChangedEvent().endAtomic();
+            filterSettingsChangedEvent.fire();
+        } else {
+            this.updateComboBoxSelection();
+        }
+
+        SystemAction.get(RemoveFilterSettingsAction.class).setEnabled(comboBox.getSelectedItem() != this.customFilterSetting);
+        SystemAction.get(SaveFilterSettingsAction.class).setEnabled(comboBox.getSelectedItem() == this.customFilterSetting);
+    }
+
+    private void updateComboBox() {
+        comboBox.removeAllItems();
+        comboBox.addItem(customFilterSetting);
+        for (FilterSetting s : filterSettings) {
+            comboBox.addItem(s);
+        }
+
+        this.updateComboBoxSelection();
+    }
+
+    public void addFilterSetting() {
+        NotifyDescriptor.InputLine l = new NotifyDescriptor.InputLine("Name of the new profile:", "Filter Profile");
+        if (DialogDisplayer.getDefault().notify(l) == NotifyDescriptor.OK_OPTION) {
+            String name = l.getInputText();
+
+            FilterSetting toRemove = null;
+            for (FilterSetting s : filterSettings) {
+                if (s.getName().equals(name)) {
+                    NotifyDescriptor.Confirmation conf = new NotifyDescriptor.Confirmation("Filter profile \"" + name + "\" already exists, do you want to replace it?", "Filter");
+                    if (DialogDisplayer.getDefault().notify(conf) == NotifyDescriptor.YES_OPTION) {
+                        toRemove = s;
+                        break;
+                    } else {
+                        return;
+                    }
+                }
+            }
+
+            if (toRemove != null) {
+                filterSettings.remove(toRemove);
+            }
+            FilterSetting setting = createFilterSetting(name);
+            filterSettings.add(setting);
+
+            // Sort alphabetically
+            Collections.sort(filterSettings, new Comparator<FilterSetting>() {
+
+                @Override
+                public int compare(FilterSetting o1, FilterSetting o2) {
+                    return o1.getName().compareTo(o2.getName());
+                }
+            });
+
+            updateComboBox();
+        }
+    }
+
+    public boolean canRemoveFilterSetting() {
+        return comboBox.getSelectedItem() != customFilterSetting;
+    }
+
+    public void removeFilterSetting() {
+        if (canRemoveFilterSetting()) {
+            Object o = comboBox.getSelectedItem();
+            assert o instanceof FilterSetting;
+            FilterSetting f = (FilterSetting) o;
+            assert f != customFilterSetting;
+            assert filterSettings.contains(f);
+            NotifyDescriptor.Confirmation l = new NotifyDescriptor.Confirmation("Do you really want to remove filter profile \"" + f + "\"?", "Filter Profile");
+            if (DialogDisplayer.getDefault().notify(l) == NotifyDescriptor.YES_OPTION) {
+                filterSettings.remove(f);
+                updateComboBox();
+            }
+        }
+    }
+
+    private FilterSetting createFilterSetting(String name) {
+        FilterSetting s = new FilterSetting(name);
+        FilterChain chain = this.getFilterChain();
+        for (Filter f : chain.getFilters()) {
+            s.addFilter(f);
+        }
+        return s;
+    }
+
+    private void updateComboBoxSelection() {
+        List<Filter> filters = this.getFilterChain().getFilters();
+        boolean found = false;
+        for (FilterSetting s : filterSettings) {
+            if (s.getFilterCount() == filters.size()) {
+                boolean ok = true;
+                for (Filter f : filters) {
+                    if (!s.containsFilter(f)) {
+                        ok = false;
+                    }
+                }
+
+                if (ok) {
+                    if (comboBox.getSelectedItem() != s) {
+                        comboBox.setSelectedItem(s);
+                    }
+                    found = true;
+                    break;
+                }
+            }
+        }
+
+        if (!found && comboBox.getSelectedItem() != customFilterSetting) {
+            comboBox.setSelectedItem(customFilterSetting);
+        }
+    }
+
+    private class FilterChildren extends Children.Keys<Filter> implements ChangedListener<CheckNode> {
+
+        private HashMap<Filter, Node> nodeHash = new HashMap<>();
+
+        @Override
+        protected Node[] createNodes(Filter filter) {
+            if (nodeHash.containsKey(filter)) {
+                return new Node[]{nodeHash.get(filter)};
+            }
+
+            FilterNode node = new FilterNode(filter);
+            node.getSelectionChangedEvent().addListener(this);
+            nodeHash.put(filter, node);
+            return new Node[]{node};
+        }
+
+        public FilterChildren() {
+            sequence.getChangedEvent().addListener(new ChangedListener<FilterChain>() {
+
+                @Override
+                public void changed(FilterChain source) {
+                    addNotify();
+                }
+            });
+
+            setBefore(false);
+        }
+
+        @Override
+        protected void addNotify() {
+            setKeys(sequence.getFilters());
+            updateSelection();
+        }
+
+        @Override
+        public void changed(CheckNode source) {
+            FilterNode node = (FilterNode) source;
+            Filter f = node.getFilter();
+            FilterChain chain = getFilterChain();
+            if (node.isSelected()) {
+                if (!chain.containsFilter(f)) {
+                    chain.addFilter(f);
+                }
+            } else {
+                if (chain.containsFilter(f)) {
+                    chain.removeFilter(f);
+                }
+            }
+            view.revalidate();
+            view.repaint();
+            updateComboBoxSelection();
+        }
+    }
+
+    public FilterChain getFilterChain() {
+        return filterChain;
+    }
+
+    private FilterTopComponent() {
+        filterSettingsChangedEvent = new ChangedEvent<>(this);
+        initComponents();
+        setName(NbBundle.getMessage(FilterTopComponent.class, "CTL_FilterTopComponent"));
+        setToolTipText(NbBundle.getMessage(FilterTopComponent.class, "HINT_FilterTopComponent"));
+        //        setIcon(Utilities.loadImage(ICON_PATH, true));
+
+        sequence = new FilterChain();
+        filterChain = new FilterChain();
+        initFilters();
+        manager = new ExplorerManager();
+        manager.setRootContext(new AbstractNode(new FilterChildren()));
+        associateLookup(ExplorerUtils.createLookup(manager, getActionMap()));
+        view = new CheckListView();
+
+        ToolbarPool.getDefault().setPreferredIconSize(16);
+        Toolbar toolBar = new Toolbar();
+        Border b = (Border) UIManager.get("Nb.Editor.Toolbar.border"); //NOI18N
+        toolBar.setBorder(b);
+        comboBox = new JComboBox();
+        toolBar.add(comboBox);
+        this.add(toolBar, BorderLayout.NORTH);
+        toolBar.add(SaveFilterSettingsAction.get(SaveFilterSettingsAction.class));
+        toolBar.add(RemoveFilterSettingsAction.get(RemoveFilterSettingsAction.class));
+        toolBar.addSeparator();
+        toolBar.add(NewFilterAction.get(NewFilterAction.class));
+        toolBar.add(RemoveFilterAction.get(RemoveFilterAction.class).createContextAwareInstance(this.getLookup()));
+        toolBar.add(MoveFilterUpAction.get(MoveFilterUpAction.class).createContextAwareInstance(this.getLookup()));
+        toolBar.add(MoveFilterDownAction.get(MoveFilterDownAction.class).createContextAwareInstance(this.getLookup()));
+        this.add(view, BorderLayout.CENTER);
+
+        filterSettings = new ArrayList<>();
+        updateComboBox();
+
+        comboBox.addActionListener(comboBoxActionListener);
+        setChain(filterChain);
+    }
+
+    public void newFilter() {
+        CustomFilter cf = new CustomFilter("My custom filter", "");
+        if (cf.openInEditor()) {
+            sequence.addFilter(cf);
+            FileObject fo = getFileObject(cf);
+            FilterChangedListener listener = new FilterChangedListener(fo, cf);
+            listener.changed(cf);
+            cf.getChangedEvent().addListener(listener);
+        }
+    }
+
+    public void removeFilter(Filter f) {
+        com.sun.hotspot.igv.filter.CustomFilter cf = (com.sun.hotspot.igv.filter.CustomFilter) f;
+
+        sequence.removeFilter(cf);
+        try {
+            getFileObject(cf).delete();
+        } catch (IOException ex) {
+            Exceptions.printStackTrace(ex);
+        }
+
+    }
+
+    private static class FilterChangedListener implements ChangedListener<Filter> {
+
+        private FileObject fileObject;
+        private CustomFilter filter;
+
+        public FilterChangedListener(FileObject fo, CustomFilter cf) {
+            fileObject = fo;
+            filter = cf;
+        }
+
+        @Override
+        public void changed(Filter source) {
+            try {
+                if (!fileObject.getName().equals(filter.getName())) {
+                    FileLock lock = fileObject.lock();
+                    fileObject.move(lock, fileObject.getParent(), filter.getName(), "");
+                    lock.releaseLock();
+                    FileObject newFileObject = fileObject.getParent().getFileObject(filter.getName());
+                    fileObject = newFileObject;
+                }
+
+                FileLock lock = fileObject.lock();
+                OutputStream os = fileObject.getOutputStream(lock);
+                try (Writer w = new OutputStreamWriter(os)) {
+                    String s = filter.getCode();
+                    w.write(s);
+                }
+                lock.releaseLock();
+
+            } catch (IOException ex) {
+                Exceptions.printStackTrace(ex);
+            }
+        }
+    }
+
+    public void initFilters() {
+        FileObject folder = FileUtil.getConfigRoot().getFileObject(FOLDER_ID);
+        FileObject[] children = folder.getChildren();
+
+        List<CustomFilter> customFilters = new ArrayList<>();
+        HashMap<CustomFilter, String> afterMap = new HashMap<>();
+        Set<CustomFilter> enabledSet = new HashSet<>();
+        HashMap<String, CustomFilter> map = new HashMap<>();
+
+        for (final FileObject fo : children) {
+            InputStream is = null;
+
+            String code = "";
+            FileLock lock = null;
+            try {
+                lock = fo.lock();
+                is = fo.getInputStream();
+                BufferedReader r = new BufferedReader(new InputStreamReader(is));
+                String s;
+                StringBuilder sb = new StringBuilder();
+                while ((s = r.readLine()) != null) {
+                    sb.append(s);
+                    sb.append("\n");
+                }
+                code = sb.toString();
+            } catch (FileNotFoundException ex) {
+                Exceptions.printStackTrace(ex);
+            } catch (IOException ex) {
+                Exceptions.printStackTrace(ex);
+            } finally {
+                try {
+                    is.close();
+                } catch (IOException ex) {
+                    Exceptions.printStackTrace(ex);
+                }
+                lock.releaseLock();
+            }
+
+            String displayName = fo.getName();
+
+
+            final CustomFilter cf = new CustomFilter(displayName, code);
+            map.put(displayName, cf);
+
+            String after = (String) fo.getAttribute(AFTER_ID);
+            afterMap.put(cf, after);
+
+            Boolean enabled = (Boolean) fo.getAttribute(ENABLED_ID);
+            if (enabled != null && (boolean) enabled) {
+                enabledSet.add(cf);
+            }
+
+            cf.getChangedEvent().addListener(new FilterChangedListener(fo, cf));
+
+            customFilters.add(cf);
+        }
+
+        for (int j = 0; j < customFilters.size(); j++) {
+            for (int i = 0; i < customFilters.size(); i++) {
+                List<CustomFilter> copiedList = new ArrayList<>(customFilters);
+                for (CustomFilter cf : copiedList) {
+
+                    String after = afterMap.get(cf);
+
+                    if (map.containsKey(after)) {
+                        CustomFilter afterCf = map.get(after);
+                        int index = customFilters.indexOf(afterCf);
+                        int currentIndex = customFilters.indexOf(cf);
+
+                        if (currentIndex < index) {
+                            customFilters.remove(currentIndex);
+                            customFilters.add(index, cf);
+                        }
+                    }
+                }
+            }
+        }
+
+        for (CustomFilter cf : customFilters) {
+            sequence.addFilter(cf);
+            if (enabledSet.contains(cf)) {
+                filterChain.addFilter(cf);
+            }
+        }
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        setLayout(new java.awt.BorderLayout());
+
+    }// </editor-fold>//GEN-END:initComponents
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    // End of variables declaration//GEN-END:variables
+    /**
+     * Gets default instance. Do not use directly: reserved for *.settings files only,
+     * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
+     * To obtain the singleton instance, use {@link findInstance}.
+     */
+    public static synchronized FilterTopComponent getDefault() {
+        if (instance == null) {
+            instance = new FilterTopComponent();
+        }
+        return instance;
+    }
+
+    /**
+     * Obtain the FilterTopComponent instance. Never call {@link #getDefault} directly!
+     */
+    public static synchronized FilterTopComponent findInstance() {
+        TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
+        if (win == null) {
+            ErrorManager.getDefault().log(ErrorManager.WARNING, "Cannot find Filter component. It will not be located properly in the window system.");
+            return getDefault();
+        }
+        if (win instanceof FilterTopComponent) {
+            return (FilterTopComponent) win;
+        }
+        ErrorManager.getDefault().log(ErrorManager.WARNING, "There seem to be multiple components with the '" + PREFERRED_ID + "' ID. That is a potential source of errors and unexpected behavior.");
+        return getDefault();
+    }
+
+    @Override
+    public int getPersistenceType() {
+        return TopComponent.PERSISTENCE_ALWAYS;
+    }
+
+    @Override
+    protected String preferredID() {
+        return PREFERRED_ID;
+    }
+
+    @Override
+    public ExplorerManager getExplorerManager() {
+        return manager;
+    }
+
+    @Override
+    public void componentOpened() {
+        Lookup.Template<FilterChain> tpl = new Lookup.Template<>(FilterChain.class);
+        result = Utilities.actionsGlobalContext().lookup(tpl);
+        result.addLookupListener(this);
+    }
+
+    @Override
+    public void componentClosed() {
+        result.removeLookupListener(this);
+        result = null;
+    }
+
+    @Override
+    public void resultChanged(LookupEvent lookupEvent) {
+        setChain(Utilities.actionsGlobalContext().lookup(FilterChain.class));
+    }
+
+    public void setChain(FilterChain chain) {
+        updateComboBoxSelection();
+    }
+
+    private FileObject getFileObject(CustomFilter cf) {
+        FileObject fo = FileUtil.getConfigRoot().getFileObject(FOLDER_ID + "/" + cf.getName());
+        if (fo == null) {
+            try {
+                fo = FileUtil.getConfigRoot().getFileObject(FOLDER_ID).createData(cf.getName());
+            } catch (IOException ex) {
+                Exceptions.printStackTrace(ex);
+            }
+        }
+        return fo;
+    }
+
+    @Override
+    public boolean requestFocus(boolean temporary) {
+        view.requestFocus();
+        return super.requestFocus(temporary);
+    }
+
+    @Override
+    protected boolean requestFocusInWindow(boolean temporary) {
+        view.requestFocus();
+        return super.requestFocusInWindow(temporary);
+    }
+
+    @Override
+    public void requestActive() {
+        super.requestActive();
+        view.requestFocus();
+    }
+
+    @Override
+    public void writeExternal(ObjectOutput out) throws IOException {
+        super.writeExternal(out);
+
+        out.writeInt(filterSettings.size());
+        for (FilterSetting f : filterSettings) {
+            out.writeUTF(f.getName());
+
+            out.writeInt(f.getFilterCount());
+            for (Filter filter : f.getFilters()) {
+                CustomFilter cf = (CustomFilter) filter;
+                out.writeUTF(cf.getName());
+            }
+        }
+
+        CustomFilter prev = null;
+        for (Filter f : this.sequence.getFilters()) {
+            CustomFilter cf = (CustomFilter) f;
+            FileObject fo = getFileObject(cf);
+            if (getFilterChain().containsFilter(cf)) {
+                fo.setAttribute(ENABLED_ID, true);
+            } else {
+                fo.setAttribute(ENABLED_ID, false);
+            }
+
+            if (prev == null) {
+                fo.setAttribute(AFTER_ID, null);
+            } else {
+                fo.setAttribute(AFTER_ID, prev.getName());
+            }
+
+            prev = cf;
+        }
+    }
+
+    public CustomFilter findFilter(String name) {
+        for (Filter f : sequence.getFilters()) {
+
+            CustomFilter cf = (CustomFilter) f;
+            if (cf.getName().equals(name)) {
+                return cf;
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        super.readExternal(in);
+
+        int filterSettingsCount = in.readInt();
+        for (int i = 0; i < filterSettingsCount; i++) {
+            String name = in.readUTF();
+            FilterSetting s = new FilterSetting(name);
+            int filterCount = in.readInt();
+            for (int j = 0; j < filterCount; j++) {
+                String filterName = in.readUTF();
+                CustomFilter filter = findFilter(filterName);
+                if (filter != null) {
+                    s.addFilter(filter);
+                }
+            }
+
+            filterSettings.add(s);
+        }
+        updateComboBox();
+    }
+
+    final static class ResolvableHelper implements Serializable {
+
+        private static final long serialVersionUID = 1L;
+
+        public Object readResolve() {
+            return FilterTopComponent.getDefault();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponentSettings.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd">
+<settings version="1.0">
+    <module name="com.sun.hotspot.igv.filterwindow" spec="1.0"/>
+    <instanceof class="org.openide.windows.TopComponent"/>
+    <instanceof class="com.sun.hotspot.igv.filterwindow.FilterTopComponent"/>
+    <instance class="com.sun.hotspot.igv.filterwindow.FilterTopComponent" method="getDefault"/>
+</settings>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponentWstcref.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE tc-ref PUBLIC "-//NetBeans//DTD Top Component in Mode Properties 2.0//EN" "http://www.netbeans.org/dtds/tc-ref2_0.dtd">
+<tc-ref version="2.0" >
+    <module name="com.sun.hotspot.igv.filterwindow" spec="1.0"/>
+    <tc-id id="FilterTopComponent"/>
+    <state opened="true"/>
+</tc-ref>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,7 @@
+CTL_FilterAction=Filters
+CTL_MoveFilterUpAction=Move upwards
+CTL_MoveFilterDownAction=Move downwards
+CTL_RemoveFilterAction=Remove
+CTL_RemoveFilterSettingsAction=Remove filter setting
+CTL_SaveFilterSettingsAction=Create filter profile...
+CTL_NewFilterAction=New filter...
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/FilterAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filterwindow.actions;
+
+import com.sun.hotspot.igv.filterwindow.FilterTopComponent;
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.openide.util.NbBundle;
+import org.openide.windows.TopComponent;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class FilterAction extends AbstractAction {
+
+    public FilterAction() {
+        super(NbBundle.getMessage(FilterAction.class, "CTL_FilterAction"));
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent evt) {
+        TopComponent win = FilterTopComponent.findInstance();
+        win.open();
+        win.requestActive();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/MoveFilterDownAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filterwindow.actions;
+
+import com.sun.hotspot.igv.filter.Filter;
+import com.sun.hotspot.igv.filterwindow.FilterTopComponent;
+import javax.swing.Action;
+import org.openide.nodes.Node;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CookieAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class MoveFilterDownAction extends CookieAction {
+
+    @Override
+    protected void performAction(Node[] activatedNodes) {
+        for (Node n : activatedNodes) {
+            Filter c = n.getLookup().lookup(Filter.class);
+            FilterTopComponent.findInstance().getSequence().moveFilterDown(c);
+        }
+    }
+
+    @Override
+    protected int mode() {
+        return CookieAction.MODE_EXACTLY_ONE;
+    }
+
+    public MoveFilterDownAction() {
+
+        putValue(Action.SHORT_DESCRIPTION, "Move selected filter downwards");
+    }
+
+    @Override
+    public String getName() {
+        return NbBundle.getMessage(MoveFilterUpAction.class, "CTL_MoveFilterDownAction");
+    }
+
+    @Override
+    protected Class[] cookieClasses() {
+        return new Class[]{
+            Filter.class
+        };
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/filterwindow/images/down.png";
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+        putValue("noIconInMenu", Boolean.TRUE);
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/MoveFilterUpAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filterwindow.actions;
+
+import com.sun.hotspot.igv.filter.Filter;
+import com.sun.hotspot.igv.filterwindow.FilterTopComponent;
+import javax.swing.Action;
+import org.openide.nodes.Node;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CookieAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class MoveFilterUpAction extends CookieAction {
+
+    @Override
+    protected void performAction(Node[] activatedNodes) {
+        for (Node n : activatedNodes) {
+            Filter c = n.getLookup().lookup(Filter.class);
+            FilterTopComponent.findInstance().getSequence().moveFilterUp(c);
+        }
+    }
+
+    @Override
+    protected int mode() {
+        return CookieAction.MODE_EXACTLY_ONE;
+    }
+
+    public MoveFilterUpAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Move selected filter upwards");
+    }
+
+    @Override
+    public String getName() {
+        return NbBundle.getMessage(MoveFilterUpAction.class, "CTL_MoveFilterUpAction");
+    }
+
+    @Override
+    protected Class[] cookieClasses() {
+        return new Class[]{
+            Filter.class
+        };
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/filterwindow/images/up.png";
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+        putValue("noIconInMenu", Boolean.TRUE);
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/NewFilterAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filterwindow.actions;
+
+import com.sun.hotspot.igv.filterwindow.FilterTopComponent;
+import javax.swing.Action;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CallableSystemAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class NewFilterAction extends CallableSystemAction {
+
+    public NewFilterAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Create new filter");
+    }
+
+    @Override
+    public void performAction() {
+        FilterTopComponent.findInstance().newFilter();
+    }
+
+    @Override
+    public String getName() {
+        return NbBundle.getMessage(SaveFilterSettingsAction.class, "CTL_NewFilterAction");
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/filterwindow/images/plus.png";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/RemoveFilterAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filterwindow.actions;
+
+import com.sun.hotspot.igv.filter.Filter;
+import com.sun.hotspot.igv.filterwindow.FilterTopComponent;
+import javax.swing.Action;
+import javax.swing.JOptionPane;
+import org.openide.nodes.Node;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CookieAction;
+import org.openide.windows.WindowManager;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class RemoveFilterAction extends CookieAction {
+
+    @Override
+    protected void performAction(Node[] activatedNodes) {
+        Object[] options = {"Yes",
+            "No",
+            "Cancel"
+        };
+        int n = JOptionPane.showOptionDialog(WindowManager.getDefault().getMainWindow(),
+                "Do you really want to delete " + activatedNodes.length + " filter(s)?", "Delete Filters",
+                JOptionPane.YES_NO_CANCEL_OPTION,
+                JOptionPane.QUESTION_MESSAGE,
+                null,
+                options,
+                options[2]);
+
+        if (n == JOptionPane.YES_OPTION) {
+            for (int i = 0; i < activatedNodes.length; i++) {
+                FilterTopComponent.findInstance().removeFilter(activatedNodes[i].getLookup().lookup(Filter.class));
+            }
+        }
+    }
+
+    @Override
+    protected int mode() {
+        return CookieAction.MODE_ALL;
+    }
+
+    @Override
+    public String getName() {
+        return NbBundle.getMessage(RemoveFilterAction.class, "CTL_RemoveFilterAction");
+    }
+
+    public RemoveFilterAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Remove selected filter");
+    }
+
+    @Override
+    protected Class[] cookieClasses() {
+        return new Class[]{
+            Filter.class
+        };
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+        putValue("noIconInMenu", Boolean.TRUE);
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/filterwindow/images/minus.png";
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/RemoveFilterSettingsAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filterwindow.actions;
+
+import com.sun.hotspot.igv.filterwindow.FilterTopComponent;
+import javax.swing.Action;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CallableSystemAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class RemoveFilterSettingsAction extends CallableSystemAction {
+
+    @Override
+    public void performAction() {
+        FilterTopComponent.findInstance().removeFilterSetting();
+    }
+
+    @Override
+    public String getName() {
+        return NbBundle.getMessage(RemoveFilterSettingsAction.class, "CTL_RemoveFilterSettingsAction");
+    }
+
+    public RemoveFilterSettingsAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Delete current filter profile");
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/filterwindow/images/delete.png";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/SaveFilterSettingsAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.filterwindow.actions;
+
+import com.sun.hotspot.igv.filterwindow.FilterTopComponent;
+import javax.swing.Action;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CallableSystemAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class SaveFilterSettingsAction extends CallableSystemAction {
+
+    @Override
+    public void performAction() {
+        FilterTopComponent.findInstance().addFilterSetting();
+    }
+
+    @Override
+    public String getName() {
+        return NbBundle.getMessage(SaveFilterSettingsAction.class, "CTL_SaveFilterSettingsAction");
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+    }
+
+    public SaveFilterSettingsAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Save filter configuration as profile...");
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/filterwindow/images/add.png";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/customRightTopWsmode.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mode version="2.1">
+    <name unique="customRightTopMode" />
+    <kind type="view" />
+    <state type="joined" />
+    <constraints>
+        <path orientation="horizontal" number="90" weight="0.2"/>
+        <path orientation="vertical" number="0" weight="0.75"/>
+    </constraints>
+    <bounds x="0" y="0" width="0" height="0" />
+    <frame state="0"/>
+    <active-tc id="FilterTopComponent"/>
+    <empty-behavior permanent="false"/>
+</mode>
Binary file visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/add.png has changed
Binary file visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/delete.png has changed
Binary file visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/down.png has changed
Binary file visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/minus.png has changed
Binary file visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/plus.png has changed
Binary file visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/up.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/layer.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
+<filesystem>
+    <folder name="Edit">
+        <file name="com-sun-hotspot-igv-filterwindow-actions-MoveFilterDownAction.instance">
+            <attr name="position" intvalue="300"/>
+        </file>
+        <file name="com-sun-hotspot-igv-filterwindow-actions-MoveFilterUpAction.instance">
+            <attr name="position" intvalue="400"/>
+        </file>
+        <file name="com-sun-hotspot-igv-filterwindow-actions-RemoveFilterAction.instance">
+            <attr name="position" intvalue="500"/>
+        </file>
+        <file name="com-sun-hotspot-igv-filterwindow-actions-RemoveFilterSettingsAction.instance">
+            <attr name="position" intvalue="600"/>
+        </file>
+        <file name="com-sun-hotspot-igv-filterwindow-actions-SaveFilterSettingsAction.instance">
+            <attr name="position" intvalue="900"/>
+        </file>
+    </folder>
+    
+    <folder name="Actions">
+        <folder name="Window">
+            <file name="com-sun-hotspot-igv-filterwindow-actions-FilterAction.instance"/>
+        </folder>
+    </folder>
+    <folder name="Menu">
+        <folder name="Window">
+            <file name="FilterAction.shadow">
+                <attr name="originalFile" stringvalue="Actions/Window/com-sun-hotspot-igv-filterwindow-actions-FilterAction.instance"/>
+            </file>
+        </folder>
+    </folder>
+    <folder name="Windows2">
+        <folder name="Components">
+            <file name="FilterTopComponent.settings" url="FilterTopComponentSettings.xml"/>
+        </folder>
+        <folder name="Modes">
+            <file name="customRightTopMode.wsmode" url="customRightTopWsmode.xml"/>
+            <folder name="customRightTopMode">
+                <file name="FilterTopComponent.wstcref" url="FilterTopComponentWstcref.xml"/>
+            </folder>
+        </folder>
+    </folder>
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.graal" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.graal.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.graal
+OpenIDE-Module-Layer: com/sun/hotspot/igv/graal/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/graal/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.graal-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=79002a09
+build.xml.script.CRC32=3534d355
+build.xml.stylesheet.CRC32=a56c6a5b@2.47.1
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=79002a09
+nbproject/build-impl.xml.script.CRC32=2867f2d5
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.47.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.graal</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.filter</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages/>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/src/com/sun/hotspot/igv/graal/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=GraalCompilerSupport
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/src/com/sun/hotspot/igv/graal/filters/GraalCFGFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * 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.sun.hotspot.igv.graal.filters;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.filter.AbstractFilter;
+import com.sun.hotspot.igv.graph.Connection;
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.graph.InputSlot;
+import java.util.HashSet;
+import java.util.Set;
+
+public class GraalCFGFilter extends AbstractFilter {
+    
+    @Override
+    public String getName() {
+        return "Graal CFG Filter";
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        Set<Figure> figuresToRemove = new HashSet<>();
+        Set<Connection> connectionsToRemove = new HashSet<>();
+        for (Figure f : d.getFigures()) {
+            final String prop = f.getProperties().get("probability");
+            
+            if (prop == null) {
+                figuresToRemove.add(f);
+            }
+        }
+        d.removeAllFigures(figuresToRemove);
+        
+        for (Figure f : d.getFigures()) {
+            Properties p = f.getProperties();
+            int predCount = Integer.parseInt(p.get("predecessorCount"));
+            for (InputSlot is : f.getInputSlots()) {
+                if (is.getPosition() >= predCount && !"EndNode".equals(is.getProperties().get("class"))) {
+                    for (Connection c : is.getConnections()) {
+                        if (!"EndNode".equals(c.getOutputSlot().getFigure().getProperties().get("class"))) {
+                            connectionsToRemove.add(c);
+                        }
+                    }
+                }
+            }
+        }
+        
+        for (Connection c : connectionsToRemove) {
+            c.remove();
+            System.out.println("rm " + c);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/src/com/sun/hotspot/igv/graal/filters/GraalColoringFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,81 @@
+/*
+ * 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.sun.hotspot.igv.graal.filters;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.filter.AbstractFilter;
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.Figure;
+import java.awt.Color;
+import java.util.List;
+
+public class GraalColoringFilter extends AbstractFilter {
+    
+    private String colorName;
+
+    public GraalColoringFilter(String colorName) {
+        this.colorName = colorName;
+    }
+
+    @Override
+    public String getName() {
+        return "Graal Coloring Filter (" + colorName + ")";
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        List<Figure> figures = d.getFigures();
+        int colors = 0;
+        for (Figure f : figures) {
+            Properties p = f.getProperties();
+            final String prop = p.get(colorName + "Color");
+            if (prop == null) {
+                continue;
+            }
+            try {
+                int color = Integer.parseInt(prop);
+                if (color > colors) {
+                    colors = color;
+                }
+            } catch (NumberFormatException nfe) {
+                // nothing to do
+            }
+        }
+        colors++;
+        for (Figure f : figures) {
+            Properties p = f.getProperties();
+            final String prop = p.get(colorName + "Color");
+            if (prop == null) {
+                continue;
+            }
+            try {
+                int color = Integer.parseInt(prop);
+                Color c = Color.getHSBColor((float) color / colors, 1.0f, 0.7f);
+                f.setColor(c);
+            } catch (NumberFormatException nfe) {
+                // nothing to do
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/src/com/sun/hotspot/igv/graal/filters/GraalEdgeColorFilter.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,116 @@
+/*
+ * 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.sun.hotspot.igv.graal.filters;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.filter.AbstractFilter;
+import com.sun.hotspot.igv.graph.Connection;
+import com.sun.hotspot.igv.graph.Connection.ConnectionStyle;
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.graph.InputSlot;
+import java.awt.Color;
+import java.util.List;
+
+/**
+ * Filter that colors usage and successor edges differently.
+ *
+ * @author Peter Hofer
+ */
+public class GraalEdgeColorFilter extends AbstractFilter {
+
+    private Color successorColor = Color.BLUE;
+    private Color usageColor = Color.RED;
+    private Color memoryColor = Color.GREEN;
+
+    public GraalEdgeColorFilter() {
+    }
+
+    @Override
+    public String getName() {
+        return "Graal Edge Color Filter";
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        List<Figure> figures = d.getFigures();
+        for (Figure f : figures) {
+            Properties p = f.getProperties();
+            int predCount;
+            if (p.get("predecessorCount") != null) {
+                predCount = Integer.parseInt(p.get("predecessorCount"));
+            } else {
+                predCount = 0;
+            }
+            for (InputSlot is : f.getInputSlots()) {
+                Color color;
+                ConnectionStyle style = ConnectionStyle.NORMAL;
+                if (is.getPosition() < predCount) {
+                    color = successorColor;
+                    style = ConnectionStyle.BOLD;
+                } else {
+                    color = usageColor;
+                }
+
+                is.setColor(color);
+                for (Connection c : is.getConnections()) {
+                    if (c.getLabel() == null || !c.getLabel().endsWith("#NDF")) {
+                        c.setColor(color);
+                        if (c.getStyle() != ConnectionStyle.DASHED) {
+                            c.setStyle(style);
+                        }
+                    } else if ("EndNode".equals(c.getOutputSlot().getFigure().getProperties().get("class"))
+                            || "EndNode".equals(c.getOutputSlot().getProperties().get("class"))) {
+                        c.setColor(successorColor);
+                        c.setStyle(ConnectionStyle.BOLD);
+                    }
+                }
+            }
+        }
+    }
+
+    public Color getUsageColor() {
+        return usageColor;
+    }
+
+    public void setUsageColor(Color usageColor) {
+        this.usageColor = usageColor;
+    }
+
+    public void setMemoryColor(Color memoryColor) {
+        this.memoryColor = memoryColor;
+    }
+
+    public Color getMemoryColor() {
+        return memoryColor;
+    }
+
+    public Color getSuccessorColor() {
+        return successorColor;
+    }
+
+    public void setSuccessorColor(Color successorColor) {
+        this.successorColor = successorColor;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/src/com/sun/hotspot/igv/graal/filters/beginend.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,4 @@
+var f = new CombineFilter("Combine Filter");
+f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("class", ".*"), new Properties.RegexpPropertyMatcher("class", "BeginNode"), false, "shortName"));
+f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("class", "EndNode"), new Properties.RegexpPropertyMatcher("class", ".*"), true, "shortName"));
+f.apply(graph);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/src/com/sun/hotspot/igv/graal/filters/callgraph.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,4 @@
+colorize("name", "<init>.*", yellow);
+colorize("name", "<clinit>.*", pink);
+colorize("leaf", "1", lightGray);
+colorize("cutoff", "1", red);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/src/com/sun/hotspot/igv/graal/filters/cfg.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+var f = new com.sun.hotspot.igv.graal.filters.GraalCFGFilter();
+f.apply(graph);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/src/com/sun/hotspot/igv/graal/filters/color.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,11 @@
+colorize("name", ".*", white);
+colorize("name", "Begin|EndNode|LoopBegin|LoopEnd|Return", orange);
+colorize("name", "Phi.*", magenta);
+colorize("name", "FrameState@.*", new java.awt.Color(0.5, 0.8, 1.0));
+colorize("name", "If|Merge", pink);
+colorize("name", "const.*", new java.awt.Color(0.7, 0.7, 0.7));
+colorize("name", "Local", new java.awt.Color(0.85, 0.85, 0.85));
+colorize("name", "\\+|-|\\*|/|&|\\||<<|>>|>>>", cyan);
+colorize("name", "Comp .*", yellow);
+
+colorize("notInOwnBlock", "true", red);
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/src/com/sun/hotspot/igv/graal/filters/edgeColor.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,4 @@
+var f = new com.sun.hotspot.igv.graal.filters.GraalEdgeColorFilter();
+f.setUsageColor(blue);
+f.setSuccessorColor(red);
+f.apply(graph);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/src/com/sun/hotspot/igv/graal/filters/framestatelocks.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+colorize("class", "FrameState", red);
+colorize("locks", "", gray);
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/src/com/sun/hotspot/igv/graal/filters/noframestate.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+remove("class", "FrameState");
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/src/com/sun/hotspot/igv/graal/filters/probability.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,3 @@
+colorizeGradientWithMode("probability", 0, 500, "logarithmic");
+
+// more parameters: colorizeGradientCustom("probability", 0, 500, "logarithmic", [blue, yellow, red], [0, 0.5, 1], 16);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/src/com/sun/hotspot/igv/graal/filters/slots.filter	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+removeUnconnectedSlots(true, true);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graal/src/com/sun/hotspot/igv/graal/layer.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
+<filesystem>
+    <folder name="Filters">
+        <file name="Graal Coloring" url="filters/color.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Graal Edge Coloring" url="filters/edgeColor.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Graal Remove Unconnected Slots" url="filters/slots.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Graal Probability" url="filters/probability.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Graal Reduce Begin-End" url="filters/beginend.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Graal Remove FrameState" url="filters/noframestate.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Graal Mark FrameState With Lock" url="filters/framestatelocks.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Graal Call Analysis" url="filters/callgraph.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Graal CFG-only" url="filters/cfg.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+    </folder>
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.graph" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.graph.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.graph
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/graph/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.graph-impl" basedir="..">
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+        <condition>
+            <not>
+                <available file="${harness.dir}" type="dir"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=b2bc2f02
+build.xml.script.CRC32=486d5dab
+build.xml.stylesheet.CRC32=79c3b980
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=b2bc2f02
+nbproject/build-impl.xml.script.CRC32=17fa0f49
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/nbproject/platform.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.javahelp,\
+    org.netbeans.modules.masterfs,\
+    org.netbeans.modules.options.keymap,\
+    org.netbeans.modules.sendopts,\
+    org.netbeans.modules.templates,\
+    org.openide.compat,\
+    org.openide.execution,\
+    org.openide.util.enumerations
+enabled.clusters=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.layout</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.sun.hotspot.igv.graph</package>
+                <package>com.sun.hotspot.igv.graph.services</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/src/com/sun/hotspot/igv/graph/AndSelector.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.graph;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class AndSelector implements Selector {
+
+    private Selector selector1;
+    private Selector selector2;
+
+    public AndSelector(Selector s1, Selector s2) {
+        this.selector1 = s1;
+        this.selector2 = s2;
+    }
+
+    @Override
+    public List<Figure> selected(Diagram d) {
+        List<Figure> l1 = selector1.selected(d);
+        List<Figure> l2 = selector2.selected(d);
+        List<Figure> result = new ArrayList<>();
+        for (Figure f : l2) {
+            if (l1.contains(f)) {
+                result.add(f);
+            }
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/src/com/sun/hotspot/igv/graph/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=Graph
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/src/com/sun/hotspot/igv/graph/Connection.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.graph;
+
+import com.sun.hotspot.igv.data.Source;
+import com.sun.hotspot.igv.layout.Link;
+import com.sun.hotspot.igv.layout.Port;
+import java.awt.Color;
+import java.awt.Point;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Connection implements Source.Provider, Link {
+
+    @Override
+    public boolean isVIP() {
+        return style == ConnectionStyle.BOLD;
+    }
+
+    public enum ConnectionStyle {
+
+        NORMAL,
+        DASHED,
+        BOLD
+    }
+    private InputSlot inputSlot;
+    private OutputSlot outputSlot;
+    private Source source;
+    private Color color;
+    private ConnectionStyle style;
+    private List<Point> controlPoints;
+    private String label;
+
+    protected Connection(InputSlot inputSlot, OutputSlot outputSlot, String label) {
+        this.inputSlot = inputSlot;
+        this.outputSlot = outputSlot;
+        this.label = label;
+        this.inputSlot.connections.add(this);
+        this.outputSlot.connections.add(this);
+        controlPoints = new ArrayList<>();
+        Figure sourceFigure = this.outputSlot.getFigure();
+        Figure destFigure = this.inputSlot.getFigure();
+        sourceFigure.addSuccessor(destFigure);
+        destFigure.addPredecessor(sourceFigure);
+        source = new Source();
+
+        this.color = Color.BLACK;
+        this.style = ConnectionStyle.NORMAL;
+    }
+
+    public InputSlot getInputSlot() {
+        return inputSlot;
+    }
+
+    public OutputSlot getOutputSlot() {
+        return outputSlot;
+    }
+
+    public Color getColor() {
+        return color;
+    }
+
+    public ConnectionStyle getStyle() {
+        return style;
+    }
+
+    public void setColor(Color c) {
+        color = c;
+    }
+
+    public void setStyle(ConnectionStyle s) {
+        style = s;
+    }
+
+    @Override
+    public Source getSource() {
+        return source;
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public void remove() {
+        inputSlot.getFigure().removePredecessor(outputSlot.getFigure());
+        inputSlot.connections.remove(this);
+        outputSlot.getFigure().removeSuccessor(inputSlot.getFigure());
+        outputSlot.connections.remove(this);
+    }
+
+    public String getToolTipText() {
+        StringBuilder builder = new StringBuilder();
+        if (label != null) {
+            builder.append(label).append(": from ");
+        } else {
+            builder.append("From ");
+        }
+        builder.append(getOutputSlot().getFigure().getSource().getSourceNodes().get(0).getId());
+        builder.append(" to ");
+        builder.append(getInputSlot().getFigure().getSource().getSourceNodes().get(0).getId());
+        return builder.toString();
+    }
+
+    @Override
+    public String toString() {
+        return "Connection('" + label + "', " + getFrom().getVertex() + " to " + getTo().getVertex() + ")";
+    }
+
+    @Override
+    public Port getFrom() {
+        return outputSlot;
+    }
+
+    @Override
+    public Port getTo() {
+        return inputSlot;
+    }
+
+    @Override
+    public List<Point> getControlPoints() {
+        return controlPoints;
+    }
+
+    @Override
+    public void setControlPoints(List<Point> list) {
+        controlPoints = list;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.graph;
+
+import com.sun.hotspot.igv.data.InputEdge;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Properties.StringPropertyMatcher;
+import java.awt.Font;
+import java.util.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Diagram {
+
+    private List<Figure> figures;
+    private InputGraph graph;
+    private int curId;
+    private String nodeText;
+    private Font font;
+    private Font slotFont;
+
+    public Font getFont() {
+        return font;
+    }
+
+    public Font getSlotFont() {
+        return slotFont;
+    }
+    
+    private Diagram() {
+        figures = new ArrayList<>();
+        this.nodeText = "";
+        this.font = new Font("Arial", Font.PLAIN, 13);
+        this.slotFont = new Font("Arial", Font.PLAIN, 10);
+    }
+
+    public String getNodeText() {
+        return nodeText;
+    }
+
+    public Diagram getNext() {
+        return Diagram.createDiagram(graph.getNext(), nodeText);
+    }
+
+    public Diagram getPrev() {
+        return Diagram.createDiagram(graph.getPrev(), nodeText);
+    }
+
+    public List<Figure> getFigures() {
+        return Collections.unmodifiableList(figures);
+    }
+
+    public Figure createFigure() {
+        Figure f = new Figure(this, curId);
+        curId++;
+        this.figures.add(f);
+        return f;
+    }
+
+    public Connection createConnection(InputSlot inputSlot, OutputSlot outputSlot, String label) {
+        assert inputSlot.getFigure().getDiagram() == this;
+        assert outputSlot.getFigure().getDiagram() == this;
+        return new Connection(inputSlot, outputSlot, label);
+    }
+    
+    public Map<InputNode, Set<Figure>> calcSourceToFigureRelation() {
+        Map<InputNode, Set<Figure>> map = new HashMap<>();
+        
+        for(InputNode node : this.getGraph().getNodes()) {
+            map.put(node, new HashSet<Figure>());
+        }
+        
+        for(Figure f : this.getFigures()) {
+            for(InputNode node : f.getSource().getSourceNodes()) {
+                map.get(node).add(f);
+            }
+        }
+        
+        return map;
+    }
+
+    public static Diagram createDiagram(InputGraph graph, String nodeText) {
+        if (graph == null) {
+            return null;
+        }
+
+        Diagram d = new Diagram();
+        d.graph = graph;
+        d.nodeText = nodeText;
+
+        Collection<InputNode> nodes = graph.getNodes();
+        Hashtable<Integer, Figure> figureHash = new Hashtable<>();
+        for (InputNode n : nodes) {
+            Figure f = d.createFigure();
+            f.getSource().addSourceNode(n);
+            f.getProperties().add(n.getProperties());
+            figureHash.put(n.getId(), f);
+        }
+
+        for (InputEdge e : graph.getEdges()) {
+
+            int from = e.getFrom();
+            int to = e.getTo();
+            Figure fromFigure = figureHash.get(from);
+            Figure toFigure = figureHash.get(to);
+            assert fromFigure != null && toFigure != null;
+            
+            if(fromFigure == null || toFigure == null) continue;
+
+            int fromIndex = e.getFromIndex();
+            while (fromFigure.getOutputSlots().size() <= fromIndex) {
+                fromFigure.createOutputSlot();
+            }
+            OutputSlot outputSlot = fromFigure.getOutputSlots().get(fromIndex);
+
+            int toIndex = e.getToIndex();
+            while (toFigure.getInputSlots().size() <= toIndex) {
+                toFigure.createInputSlot();
+            }
+            InputSlot inputSlot = toFigure.getInputSlots().get(toIndex);
+
+            Connection c = d.createConnection(inputSlot, outputSlot, e.getLabel());
+
+            if (e.getState() == InputEdge.State.NEW) {
+                c.setStyle(Connection.ConnectionStyle.BOLD);
+            } else if (e.getState() == InputEdge.State.DELETED) {
+                c.setStyle(Connection.ConnectionStyle.DASHED);
+            }
+        }
+
+
+        return d;
+    }
+
+    public void removeAllFigures(Set<Figure> figuresToRemove) {
+        for (Figure f : figuresToRemove) {
+            freeFigure(f);
+        }
+
+        ArrayList<Figure> newFigures = new ArrayList<>();
+        for (Figure f : this.figures) {
+            if (!figuresToRemove.contains(f)) {
+                newFigures.add(f);
+            }
+        }
+        figures = newFigures;
+    }
+
+    private void freeFigure(Figure succ) {
+
+        List<InputSlot> inputSlots = new ArrayList<>(succ.getInputSlots());
+        for (InputSlot s : inputSlots) {
+            succ.removeInputSlot(s);
+        }
+
+        List<OutputSlot> outputSlots = new ArrayList<>(succ.getOutputSlots());
+        for (OutputSlot s : outputSlots) {
+            succ.removeOutputSlot(s);
+        }
+
+        assert succ.getInputSlots().size() == 0;
+        assert succ.getOutputSlots().size() == 0;
+        assert succ.getPredecessors().size() == 0;
+        assert succ.getSuccessors().size() == 0;
+
+    }
+
+    public void removeFigure(Figure succ) {
+
+        assert this.figures.contains(succ);
+        freeFigure(succ);
+        this.figures.remove(succ);
+    }
+
+    public String getName() {
+        return graph.getName();
+    }
+
+    public InputGraph getGraph() {
+        return graph;
+    }
+
+    public Set<Connection> getConnections() {
+
+        Set<Connection> connections = new HashSet<>();
+        for (Figure f : figures) {
+
+            for (InputSlot s : f.getInputSlots()) {
+                connections.addAll(s.getConnections());
+            }
+        }
+
+        return connections;
+    }
+
+    public Figure getRootFigure() {
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(figures);
+        Figure root = selector.selectSingle(new StringPropertyMatcher("name", "Root"));
+        if (root == null) {
+            root = selector.selectSingle(new StringPropertyMatcher("name", "Start"));
+        }
+        if (root == null) {
+            List<Figure> rootFigures = getRootFigures();
+            if (rootFigures.size() > 0) {
+                root = rootFigures.get(0);
+            } else if (figures.size() > 0) {
+                root = figures.get(0);
+            }
+        }
+
+        return root;
+    }
+
+    public void printStatistics() {
+        System.out.println("=============================================================");
+        System.out.println("Diagram statistics");
+
+        List<Figure> tmpFigures = getFigures();
+        Set<Connection> connections = getConnections();
+
+        System.out.println("Number of figures: " + tmpFigures.size());
+        System.out.println("Number of connections: " + connections.size());
+
+        List<Figure> figuresSorted = new ArrayList<>(tmpFigures);
+        Collections.sort(figuresSorted, new Comparator<Figure>() {
+
+            @Override
+            public int compare(Figure a, Figure b) {
+                return b.getPredecessors().size() + b.getSuccessors().size() - a.getPredecessors().size() - a.getSuccessors().size();
+            }
+        });
+
+        final int COUNT = 10;
+        int z = 0;
+        for (Figure f : figuresSorted) {
+
+            z++;
+            int sum = f.getPredecessors().size() + f.getSuccessors().size();
+            System.out.println("#" + z + ": " + f + ", predCount=" + f.getPredecessors().size() + " succCount=" + f.getSuccessors().size());
+            if (sum < COUNT) {
+                break;
+            }
+
+        }
+
+        System.out.println("=============================================================");
+    }
+
+    public List<Figure> getRootFigures() {
+        ArrayList<Figure> rootFigures = new ArrayList<>();
+        for (Figure f : figures) {
+            if (f.getPredecessors().size() == 0) {
+                rootFigures.add(f);
+            }
+        }
+        return rootFigures;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.graph;
+
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Source;
+import com.sun.hotspot.igv.layout.Vertex;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.util.List;
+import java.util.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Figure extends Properties.Entity implements Source.Provider, Vertex {
+
+    public static final int INSET = 12;
+    public static int SLOT_WIDTH = 12;
+    public static final int OVERLAPPING = 6;
+    public static final int SLOT_START = 4;
+    public static final int SLOT_OFFSET = 8;
+    public static final boolean VERTICAL_LAYOUT = true;
+    protected List<InputSlot> inputSlots;
+    protected List<OutputSlot> outputSlots;
+    private Source source;
+    private Diagram diagram;
+    private Point position;
+    private List<Figure> predecessors;
+    private List<Figure> successors;
+    private Color color;
+    private int id;
+    private String idString;
+    private String[] lines;
+    private int heightCash = -1;
+    private int widthCash = -1;
+
+    public int getHeight() {
+        if (heightCash == -1) {
+            BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
+            Graphics g = image.getGraphics();
+            g.setFont(diagram.getFont().deriveFont(Font.BOLD));
+            FontMetrics metrics = g.getFontMetrics();
+            String nodeText = diagram.getNodeText();
+            heightCash = nodeText.split("\n").length * metrics.getHeight() + INSET;
+        }
+        return heightCash;
+    }
+    
+    public static <T> List<T> getAllBefore(List<T> inputList, T tIn) {
+        List<T> result = new ArrayList<>();
+        for(T t : inputList) {
+            if(t.equals(tIn)) {
+                break;
+            }
+            result.add(t);
+        }
+        return result;
+    }
+    
+    public static int getSlotsWidth(Collection<? extends Slot> slots) {
+        int result = Figure.SLOT_OFFSET;
+        for(Slot s : slots) {
+            result += s.getWidth() + Figure.SLOT_OFFSET;
+        }
+        return result;
+    }
+
+    public int getWidth() {
+        if (widthCash == -1) {
+            int max = 0;
+            BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
+            Graphics g = image.getGraphics();
+            g.setFont(diagram.getFont().deriveFont(Font.BOLD));
+            FontMetrics metrics = g.getFontMetrics();
+            for (String s : getLines()) {
+                int cur = metrics.stringWidth(s);
+                if (cur > max) {
+                    max = cur;
+                }
+            }
+            widthCash = max + INSET;
+            widthCash = Math.max(widthCash, Figure.getSlotsWidth(inputSlots));
+            widthCash = Math.max(widthCash, Figure.getSlotsWidth(outputSlots));
+        }
+        return widthCash;
+    }
+
+    protected Figure(Diagram diagram, int id) {
+        this.diagram = diagram;
+        this.source = new Source();
+        inputSlots = new ArrayList<>(5);
+        outputSlots = new ArrayList<>(1);
+        predecessors = new ArrayList<>(6);
+        successors = new ArrayList<>(6);
+        this.id = id;
+        idString = Integer.toString(id);
+
+        this.position = new Point(0, 0);
+        this.color = Color.WHITE;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setColor(Color color) {
+        this.color = color;
+    }
+
+    public Color getColor() {
+        return color;
+    }
+
+    public List<Figure> getPredecessors() {
+        return Collections.unmodifiableList(predecessors);
+    }
+
+    public Set<Figure> getPredecessorSet() {
+        Set<Figure> result = new HashSet<>();
+        for (Figure f : getPredecessors()) {
+            result.add(f);
+        }
+        return Collections.unmodifiableSet(result);
+    }
+
+    public Set<Figure> getSuccessorSet() {
+        Set<Figure> result = new HashSet<>();
+        for (Figure f : getSuccessors()) {
+            result.add(f);
+        }
+        return Collections.unmodifiableSet(result);
+    }
+
+    public List<Figure> getSuccessors() {
+        return Collections.unmodifiableList(successors);
+    }
+
+    protected void addPredecessor(Figure f) {
+        this.predecessors.add(f);
+    }
+
+    protected void addSuccessor(Figure f) {
+        this.successors.add(f);
+    }
+
+    protected void removePredecessor(Figure f) {
+        assert predecessors.contains(f);
+        predecessors.remove(f);
+    }
+
+    protected void removeSuccessor(Figure f) {
+        assert successors.contains(f);
+        successors.remove(f);
+    }
+
+    @Override
+    public void setPosition(Point p) {
+        this.position = p;
+    }
+
+    @Override
+    public Point getPosition() {
+        return position;
+    }
+
+    public Diagram getDiagram() {
+        return diagram;
+    }
+
+    @Override
+    public Source getSource() {
+        return source;
+    }
+
+    public InputSlot createInputSlot() {
+        InputSlot slot = new InputSlot(this, -1);
+        inputSlots.add(slot);
+        return slot;
+    }
+
+    public InputSlot createInputSlot(int index) {
+        InputSlot slot = new InputSlot(this, index);
+        inputSlots.add(slot);
+        Collections.sort(inputSlots, Slot.slotIndexComparator);
+        return slot;
+    }
+
+    public void removeSlot(Slot s) {
+
+        assert inputSlots.contains(s) || outputSlots.contains(s);
+
+        List<Connection> connections = new ArrayList<>(s.getConnections());
+        for (Connection c : connections) {
+            c.remove();
+        }
+
+        if (inputSlots.contains(s)) {
+            inputSlots.remove(s);
+        } else if (outputSlots.contains(s)) {
+            outputSlots.remove(s);
+        }
+    }
+
+    public OutputSlot createOutputSlot() {
+        OutputSlot slot = new OutputSlot(this, -1);
+        outputSlots.add(slot);
+        return slot;
+    }
+
+    public OutputSlot createOutputSlot(int index) {
+        OutputSlot slot = new OutputSlot(this, index);
+        outputSlots.add(slot);
+        Collections.sort(outputSlots, Slot.slotIndexComparator);
+        return slot;
+    }
+
+    public List<InputSlot> getInputSlots() {
+        return Collections.unmodifiableList(inputSlots);
+    }
+    
+    public Set<Slot> getSlots() {
+        Set<Slot> result = new HashSet<>();
+        result.addAll(getInputSlots());
+        result.addAll(getOutputSlots());
+        return result;
+    }
+
+    public List<OutputSlot> getOutputSlots() {
+        return Collections.unmodifiableList(outputSlots);
+    }
+
+    void removeInputSlot(InputSlot s) {
+        s.removeAllConnections();
+        inputSlots.remove(s);
+    }
+
+    void removeOutputSlot(OutputSlot s) {
+        s.removeAllConnections();
+        outputSlots.remove(s);
+    }
+
+    public String[] getLines() {
+        if (lines == null) {
+            updateLines();
+        }
+        return lines;
+    }
+
+    public void updateLines() {
+        String[] strings = diagram.getNodeText().split("\n");
+        String[] result = new String[strings.length];
+
+        for (int i = 0; i < strings.length; i++) {
+            result[i] = resolveString(strings[i], getProperties());
+        }
+
+        lines = result;
+    }
+
+    public static final String resolveString(String string, Properties properties) {
+
+        StringBuilder sb = new StringBuilder();
+        boolean inBrackets = false;
+        StringBuilder curIdent = new StringBuilder();
+
+        for (int i = 0; i < string.length(); i++) {
+            char c = string.charAt(i);
+            if (inBrackets) {
+                if (c == ']') {
+                    String value = properties.get(curIdent.toString());
+                    if (value == null) {
+                        value = "";
+                    }
+                    sb.append(value);
+                    inBrackets = false;
+                } else {
+                    curIdent.append(c);
+                }
+            } else {
+                if (c == '[') {
+                    inBrackets = true;
+                    curIdent = new StringBuilder();
+                } else {
+                    sb.append(c);
+                }
+            }
+        }
+
+        return sb.toString();
+    }
+
+    @Override
+    public Dimension getSize() {
+        if (VERTICAL_LAYOUT) {
+            int width = Math.max(getWidth(), Figure.SLOT_WIDTH * (Math.max(inputSlots.size(), outputSlots.size()) + 1));
+            int height = getHeight() + 2 * Figure.SLOT_WIDTH - 2 * Figure.OVERLAPPING;
+            
+            
+            return new Dimension(width, height);
+        } else {
+            int width = getWidth() + 2 * Figure.SLOT_WIDTH - 2*Figure.OVERLAPPING;
+            int height = Figure.SLOT_WIDTH * (Math.max(inputSlots.size(), outputSlots.size()) + 1);
+            return new Dimension(width, height);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return idString;
+    }
+
+    @Override
+    public boolean isRoot() {
+  
+        List<InputNode> sourceNodes = source.getSourceNodes();
+        if (sourceNodes.size() > 0 && sourceNodes.get(0).getProperties().get("name") != null) {
+            return source.getSourceNodes().get(0).getProperties().get("name").equals("Root");
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public int compareTo(Vertex f) {
+        return toString().compareTo(f.toString());
+    }
+
+    public Rectangle getBounds() {
+        return new Rectangle(this.getPosition(), new Dimension(this.getWidth(), this.getHeight()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/src/com/sun/hotspot/igv/graph/InputSlot.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.graph;
+
+import java.awt.Point;
+import java.util.List;
+
+/**
+ * 
+ * @author Thomas Wuerthinger
+ */
+public class InputSlot extends Slot {
+
+    protected InputSlot(Figure figure, int wantedIndex) {
+        super(figure, wantedIndex);
+    }
+
+    @Override
+    public int getPosition() {
+        return getFigure().getInputSlots().indexOf(this);
+    }
+
+    @Override
+    public void setPosition(int position) {
+        List<InputSlot> inputSlots = getFigure().inputSlots;
+        InputSlot s = inputSlots.remove(position);
+        inputSlots.add(position, s);
+    }
+    @Override
+    public Point getRelativePosition() {
+        int gap = getFigure().getWidth() - Figure.getSlotsWidth(getFigure().getInputSlots());
+        double gapRatio = (double)gap / (double)(getFigure().getInputSlots().size() + 1);
+        int gapAmount = (int)((getPosition() + 1)*gapRatio);
+        return new Point(gapAmount + Figure.getSlotsWidth(Figure.getAllBefore(getFigure().getInputSlots(), this)) + getWidth()/2, -Figure.SLOT_START);
+        //return new Point((getFigure().getWidth() / (getFigure().getInputSlots().size() * 2)) * (getPosition() * 2 + 1), -Figure.SLOT_START);
+    }
+
+    @Override
+    public String toString() {
+        return "InputSlot[figure=" + this.getFigure().toString() + ", position=" + getPosition() + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/src/com/sun/hotspot/igv/graph/InvertSelector.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.graph;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InvertSelector implements Selector {
+
+    private Selector selector;
+
+    public InvertSelector(Selector selector) {
+        this.selector = selector;
+    }
+
+    @Override
+    public List<Figure> selected(Diagram d) {
+
+        List<Figure> result = new ArrayList<>();
+        List<Figure> otherResult = selector.selected(d);
+        for (Figure f : d.getFigures()) {
+            if (!otherResult.contains(f)) {
+                result.add(f);
+            }
+        }
+
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/src/com/sun/hotspot/igv/graph/MatcherSelector.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.graph;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Properties.PropertyMatcher;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class MatcherSelector implements Selector {
+
+    private PropertyMatcher matcher;
+
+    public MatcherSelector(PropertyMatcher matcher) {
+        this.matcher = matcher;
+    }
+
+    @Override
+    public List<Figure> selected(Diagram d) {
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(d.getFigures());
+        List<Figure> list = selector.selectMultiple(matcher);
+        return list;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/src/com/sun/hotspot/igv/graph/OrSelector.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.graph;
+
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class OrSelector implements Selector {
+
+    private Selector selector1;
+    private Selector selector2;
+
+    /** Creates a new instance of OrSelector */
+    public OrSelector(Selector s1, Selector s2) {
+        this.selector1 = s1;
+        this.selector2 = s2;
+    }
+
+    @Override
+    public List<Figure> selected(Diagram d) {
+
+        List<Figure> l1 = selector1.selected(d);
+        List<Figure> l2 = selector2.selected(d);
+
+        for (Figure f : l2) {
+            if (!l1.contains(f)) {
+                l1.add(f);
+            }
+        }
+
+        return l1;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/src/com/sun/hotspot/igv/graph/OutputSlot.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.graph;
+
+import java.awt.Point;
+
+/**
+ * 
+ * @author Thomas Wuerthinger
+ */
+public class OutputSlot extends Slot {
+
+    protected OutputSlot(Figure figure, int wantedIndex) {
+        super(figure, wantedIndex);
+    }
+
+    @Override
+    public int getPosition() {
+        return getFigure().getOutputSlots().indexOf(this);
+    }
+
+    @Override
+    public void setPosition(int position) {
+        OutputSlot s = getFigure().outputSlots.remove(position);
+        getFigure().outputSlots.add(position, s);
+    }
+
+    @Override
+    public Point getRelativePosition() {
+        int gap = getFigure().getWidth() - Figure.getSlotsWidth(getFigure().getOutputSlots());
+        if(gap < 0) {
+            gap = 0;
+        }
+        double gapRatio = (double)gap / (double)(getFigure().getOutputSlots().size() + 1);
+        int gapAmount = (int)((getPosition() + 1)*gapRatio);
+        return new Point(gapAmount + Figure.getSlotsWidth(Figure.getAllBefore(getFigure().getOutputSlots(), this)) + getWidth()/2, Figure.SLOT_START);
+    }
+
+    @Override
+    public String toString() {
+        return "OutputSlot[figure=" + this.getFigure().toString() + ", position=" + getPosition() + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/src/com/sun/hotspot/igv/graph/PredecessorSelector.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.graph;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class PredecessorSelector implements Selector {
+
+    private Selector innerSelector;
+
+    public PredecessorSelector(Selector innerSelector) {
+        this.innerSelector = innerSelector;
+    }
+
+    @Override
+    public List<Figure> selected(Diagram d) {
+        List<Figure> inner = innerSelector.selected(d);
+        List<Figure> result = new ArrayList<>();
+        for (Figure f : d.getFigures()) {
+            boolean saved = false;
+            for (Figure f2 : f.getSuccessors()) {
+                if (inner.contains(f2)) {
+                    saved = true;
+                }
+            }
+
+            if (saved) {
+                result.add(f);
+            }
+        }
+
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/src/com/sun/hotspot/igv/graph/Selector.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.graph;
+
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface Selector {
+
+    List<Figure> selected(Diagram d);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/src/com/sun/hotspot/igv/graph/Slot.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.graph;
+
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Source;
+import com.sun.hotspot.igv.layout.Port;
+import com.sun.hotspot.igv.layout.Vertex;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * 
+ * @author Thomas Wuerthinger
+ */
+public abstract class Slot implements Port, Source.Provider, Properties.Provider {
+
+	private int wantedIndex;
+	private Source source;
+	protected List<Connection> connections;
+	private InputNode associatedNode;
+	private Color color;
+	private String text;
+	private String shortName;
+	private Figure figure;
+
+	protected Slot(Figure figure, int wantedIndex) {
+		this.figure = figure;
+		connections = new ArrayList<>(2);
+		source = new Source();
+		this.wantedIndex = wantedIndex;
+		text = "";
+		shortName = "";
+		assert figure != null;
+	}
+
+    @Override
+	public Properties getProperties() {
+		Properties p = new Properties();
+		if (source.getSourceNodes().size() > 0) {
+			for (InputNode n : source.getSourceNodes()) {
+				p.add(n.getProperties());
+			}
+		} else {
+			p.setProperty("name", "Slot");
+			p.setProperty("figure", figure.getProperties().get("name"));
+			p.setProperty("connectionCount", Integer.toString(connections.size()));
+		}
+		return p;
+	}
+	public static final Comparator<Slot> slotIndexComparator = new Comparator<Slot>() {
+
+        @Override
+		public int compare(Slot o1, Slot o2) {
+			return o1.wantedIndex - o2.wantedIndex;
+		}
+	};
+	public static final Comparator<Slot> slotFigureComparator = new Comparator<Slot>() {
+
+        @Override
+		public int compare(Slot o1, Slot o2) {
+			return o1.figure.getId() - o2.figure.getId();
+		}
+	};
+
+	public InputNode getAssociatedNode() {
+		return associatedNode;
+	}
+
+	public void setAssociatedNode(InputNode node) {
+		associatedNode = node;
+	}
+
+	public int getWidth() {
+		if (shortName == null || shortName.length() <= 1) {
+			return Figure.SLOT_WIDTH;
+		} else {
+			BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
+			Graphics g = image.getGraphics();
+			g.setFont(figure.getDiagram().getSlotFont().deriveFont(Font.BOLD));
+			FontMetrics metrics = g.getFontMetrics();
+			return Math.max(Figure.SLOT_WIDTH, metrics.stringWidth(shortName) + 6);
+		}
+	}
+
+	public int getWantedIndex() {
+		return wantedIndex;
+	}
+
+    @Override
+	public Source getSource() {
+		return source;
+	}
+
+	public String getText() {
+		return text;
+	}
+
+	public void setShortName(String s) {
+		assert s != null;
+//        assert s.length() <= 2;
+		this.shortName = s;
+
+	}
+
+	public String getShortName() {
+		return shortName;
+	}
+
+	public String getToolTipText() {
+		StringBuilder sb = new StringBuilder();
+		sb.append(text);
+
+		for (InputNode n : getSource().getSourceNodes()) {
+			sb.append("Node (ID=" + n.getId() + "): " + n.getProperties().get("name"));
+			sb.append("<br>");
+		}
+
+		return sb.toString();
+	}
+
+	public boolean shouldShowName() {
+		return getShortName() != null && getShortName().length() > 0;
+	}
+
+	public void setText(String s) {
+		if (s == null) {
+			s = "";
+		}
+		this.text = s;
+	}
+
+	public Figure getFigure() {
+		assert figure != null;
+		return figure;
+	}
+
+	public Color getColor() {
+		return this.color;
+	}
+
+	public void setColor(Color c) {
+		color = c;
+	}
+
+	public List<Connection> getConnections() {
+		return Collections.unmodifiableList(connections);
+	}
+
+	public void removeAllConnections() {
+		List<Connection> connectionsCopy = new ArrayList<>(this.connections);
+		for (Connection c : connectionsCopy) {
+			c.remove();
+		}
+	}
+
+    @Override
+	public Vertex getVertex() {
+		return figure;
+	}
+
+	public abstract int getPosition();
+
+	public abstract void setPosition(int position);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/src/com/sun/hotspot/igv/graph/SuccessorSelector.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.graph;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class SuccessorSelector implements Selector {
+
+    private Selector innerSelector;
+
+    public SuccessorSelector(Selector innerSelector) {
+        this.innerSelector = innerSelector;
+    }
+
+    @Override
+    public List<Figure> selected(Diagram d) {
+        List<Figure> inner = innerSelector.selected(d);
+        List<Figure> result = new ArrayList<>();
+        for (Figure f : d.getFigures()) {
+            boolean saved = false;
+            for (Figure f2 : f.getPredecessors()) {
+                if (inner.contains(f2)) {
+                    saved = true;
+                }
+            }
+
+            if (saved) {
+                result.add(f);
+            }
+        }
+
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Graph/src/com/sun/hotspot/igv/graph/services/DiagramProvider.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.graph.services;
+
+import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.graph.Diagram;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface DiagramProvider {
+    Diagram getDiagram();
+    ChangedEvent<DiagramProvider> getChangedEvent();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/HierarchicalLayout/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.hierarchicallayout" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.hierarchicallayout.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/HierarchicalLayout/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.hierarchicallayout
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/hierarchicallayout/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/HierarchicalLayout/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.hierarchicallayout-impl" basedir="..">
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+        <condition>
+            <not>
+                <available file="${harness.dir}" type="dir"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/HierarchicalLayout/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=de087df9
+build.xml.script.CRC32=98977c36
+build.xml.stylesheet.CRC32=79c3b980
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=de087df9
+nbproject/build-impl.xml.script.CRC32=0d734625
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/HierarchicalLayout/nbproject/platform.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.javahelp,\
+    org.netbeans.modules.masterfs,\
+    org.netbeans.modules.options.keymap,\
+    org.netbeans.modules.sendopts,\
+    org.netbeans.modules.templates,\
+    org.openide.compat,\
+    org.openide.execution,\
+    org.openide.util.enumerations
+enabled.clusters=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/HierarchicalLayout/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/HierarchicalLayout/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.hierarchicallayout</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.layout</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.sun.hotspot.igv.hierarchicallayout</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/HierarchicalLayout/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=HierarchicalLayout
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Edge.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.hierarchicallayout;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Edge<N, E> {
+
+    private E data;
+    private Node<N, E> source;
+    private Node<N, E> dest;
+
+    protected Edge(Graph<N, E> graph, Node<N, E> source, Node<N, E> dest, E data) {
+        setData(data);
+        this.source = source;
+        this.dest = dest;
+        assert source != null;
+        assert dest != null;
+        assert source.getGraph() == dest.getGraph();
+        assert source.getGraph() != null;
+        assert dest.getGraph() != null;
+    }
+
+    public Node<N, E> getSource() {
+        return source;
+    }
+
+    public Node<N, E> getDest() {
+        return dest;
+    }
+
+    public E getData() {
+        return data;
+    }
+
+    public void setData(E e) {
+        data = e;
+    }
+
+    public void remove() {
+        source.getGraph().removeEdge(this, null);
+    }
+
+    public boolean isSelfLoop() {
+        return source == dest;
+    }
+
+    public void reverse() {
+
+        // Remove from current source / dest
+        source.removeOutEdge(this);
+        dest.removeInEdge(this);
+
+        Node<N, E> tmp = source;
+        source = dest;
+        dest = tmp;
+
+        // Add to new source / dest
+        source.addOutEdge(this);
+        dest.addInEdge(this);
+    }
+
+    @Override
+    public String toString() {
+        return "Edge (" + source + " -- " + dest + "): " + data;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Graph.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.hierarchicallayout;
+
+import java.util.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Graph<N, E> {
+
+    private HashMap<Object, Node<N, E>> nodes;
+    private HashMap<Object, Edge<N, E>> edges;
+    private List<Node<N, E>> nodeList;
+
+    public Graph() {
+        nodes = new HashMap<>();
+        edges = new HashMap<>();
+        nodeList = new ArrayList<>();
+    }
+
+    public Node<N, E> createNode(N data, Object key) {
+        Node<N, E> n = new Node<>(this, data);
+        assert key == null || !nodes.containsKey(key);
+        if (key != null) {
+            nodes.put(key, n);
+        }
+        nodeList.add(n);
+        return n;
+    }
+
+    public Edge<N, E> createEdge(Node<N, E> source, Node<N, E> dest, E data, Object key) {
+        Edge<N, E> e = new Edge<>(this, source, dest, data);
+        source.addOutEdge(e);
+        dest.addInEdge(e);
+        if (key != null) {
+            edges.put(key, e);
+        }
+        return e;
+    }
+
+    public Node<N, E> getNode(Object key) {
+        return nodes.get(key);
+    }
+
+    public Edge<N, E> getEdge(Object key) {
+        return edges.get(key);
+    }
+
+    public Collection<Edge<N, E>> getEdges() {
+        return Collections.unmodifiableCollection(edges.values());
+    }
+
+    public Collection<Node<N, E>> getNodes() {
+        return Collections.unmodifiableList(nodeList);
+    }
+
+    public void removeEdge(Edge<N, E> e, Object key) {
+        assert key == null || edges.containsKey(key);
+        if (key != null) {
+            edges.remove(key);
+        }
+        e.getSource().removeOutEdge(e);
+        e.getDest().removeInEdge(e);
+    }
+
+    public class DFSTraversalVisitor {
+
+        public void visitNode(Node<N, E> n) {
+        }
+
+        public boolean visitEdge(Edge<N, E> e, boolean backEdge) {
+            return true;
+        }
+    }
+
+    public class BFSTraversalVisitor {
+
+        public void visitNode(Node<N, E> n, int depth) {
+        }
+    }
+
+    public List<Node<N, E>> getNodesWithInDegree(int x) {
+        return getNodesWithInDegree(x, true);
+    }
+
+    public List<Node<N, E>> getNodesWithInDegree(int x, boolean countSelfLoops) {
+
+        List<Node<N, E>> result = new ArrayList<>();
+        for (Node<N, E> n : getNodes()) {
+            if (n.getInDegree(countSelfLoops) == x) {
+                result.add(n);
+            }
+        }
+
+        return result;
+
+    }
+
+    private void markReachable(Node<N, E> startingNode) {
+        ArrayList<Node<N, E>> arr = new ArrayList<>();
+        arr.add(startingNode);
+        for (Node<N, E> n : getNodes()) {
+            n.setReachable(false);
+        }
+        traverseDFS(arr, new DFSTraversalVisitor() {
+
+            @Override
+            public void visitNode(Node<N, E> n) {
+                n.setReachable(true);
+            }
+        });
+    }
+
+    public void traverseBFS(Node<N, E> startingNode, BFSTraversalVisitor tv, boolean longestPath) {
+
+        if (longestPath) {
+            markReachable(startingNode);
+        }
+
+        for (Node<N, E> n : getNodes()) {
+            n.setVisited(false);
+            n.setActive(false);
+        }
+
+        Queue<Node<N, E>> queue = new LinkedList<>();
+        queue.add(startingNode);
+        startingNode.setVisited(true);
+        int layer = 0;
+        Node<N, E> lastOfLayer = startingNode;
+        Node<N, E> lastAdded = null;
+
+        while (!queue.isEmpty()) {
+
+            Node<N, E> current = queue.poll();
+            tv.visitNode(current, layer);
+            current.setActive(false);
+
+
+            for (Edge<N, E> e : current.getOutEdges()) {
+                if (!e.getDest().isVisited()) {
+
+                    boolean allow = true;
+                    if (longestPath) {
+                        for (Node<N, E> pred : e.getDest().getPredecessors()) {
+                            if ((!pred.isVisited() || pred.isActive()) && pred.isReachable()) {
+                                allow = false;
+                                break;
+                            }
+                        }
+                    }
+
+                    if (allow) {
+                        queue.offer(e.getDest());
+                        lastAdded = e.getDest();
+                        e.getDest().setVisited(true);
+                        e.getDest().setActive(true);
+                    }
+                }
+            }
+
+            if (current == lastOfLayer && !queue.isEmpty()) {
+                lastOfLayer = lastAdded;
+                layer++;
+            }
+        }
+    }
+
+    public void traverseDFS(DFSTraversalVisitor tv) {
+        traverseDFS(getNodes(), tv);
+    }
+
+    public void traverseDFS(Collection<Node<N, E>> startingNodes, DFSTraversalVisitor tv) {
+
+        for (Node<N, E> n : getNodes()) {
+            n.setVisited(false);
+            n.setActive(false);
+        }
+
+        boolean result = false;
+        for (Node<N, E> n : startingNodes) {
+            traverse(tv, n);
+        }
+    }
+
+    private void traverse(DFSTraversalVisitor tv, Node<N, E> n) {
+
+        if (!n.isVisited()) {
+            n.setVisited(true);
+            n.setActive(true);
+            tv.visitNode(n);
+
+            for (Edge<N, E> e : n.getOutEdges()) {
+
+                Node<N, E> next = e.getDest();
+                if (next.isActive()) {
+                    tv.visitEdge(e, true);
+                } else {
+                    if (tv.visitEdge(e, false)) {
+                        traverse(tv, next);
+                    }
+                }
+            }
+
+            n.setActive(false);
+        }
+
+    }
+
+    public boolean hasCycles() {
+
+        for (Node<N, E> n : getNodes()) {
+            n.setVisited(false);
+            n.setActive(false);
+        }
+
+        boolean result = false;
+        for (Node<N, E> n : getNodes()) {
+            result |= checkCycles(n);
+            if (result) {
+                break;
+            }
+        }
+        return result;
+    }
+
+    private boolean checkCycles(Node<N, E> n) {
+
+        if (n.isActive()) {
+            return true;
+        }
+
+        if (!n.isVisited()) {
+
+            n.setVisited(true);
+            n.setActive(true);
+
+            for (Node<N, E> succ : n.getSuccessors()) {
+                if (checkCycles(succ)) {
+                    return true;
+                }
+            }
+
+            n.setActive(false);
+
+        }
+
+        return false;
+    }
+
+    @Override
+    public String toString() {
+
+        StringBuilder s = new StringBuilder();
+        s.append("Nodes: ");
+        for (Node<N, E> n : getNodes()) {
+            s.append(n.toString());
+            s.append("\n");
+        }
+
+        s.append("Edges: ");
+
+        for (Edge<N, E> e : getEdges()) {
+            s.append(e.toString());
+            s.append("\n");
+        }
+
+        return s.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1749 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.hierarchicallayout;
+
+import com.sun.hotspot.igv.layout.LayoutGraph;
+import com.sun.hotspot.igv.layout.LayoutManager;
+import com.sun.hotspot.igv.layout.Link;
+import com.sun.hotspot.igv.layout.Vertex;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.util.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class HierarchicalLayoutManager implements LayoutManager {
+
+    public static final boolean TRACE = false;
+    public static final boolean CHECK = false;
+    public static final int SWEEP_ITERATIONS = 1;
+    public static final int CROSSING_ITERATIONS = 2;
+    public static final int DUMMY_HEIGHT = 1;
+    public static final int DUMMY_WIDTH = 1;
+    public static final int X_OFFSET = 9;
+    public static final int LAYER_OFFSET = 30;
+    public static final int MAX_LAYER_LENGTH = -1;
+    public static final int MIN_LAYER_DIFFERENCE = 1;
+    public static final int VIP_BONUS = 10;
+
+    public enum Combine {
+
+        NONE,
+        SAME_INPUTS,
+        SAME_OUTPUTS
+    }
+    // Options
+    private Combine combine;
+    private int dummyWidth;
+    private int dummyHeight;
+    private int xOffset;
+    private int layerOffset;
+    private int maxLayerLength;
+    private int minLayerDifference;
+    // Algorithm global datastructures
+    private Set<Link> reversedLinks;
+    private List<LayoutNode> nodes;
+    private HashMap<Vertex, LayoutNode> vertexToLayoutNode;
+    private HashMap<Link, List<Point>> reversedLinkStartPoints;
+    private HashMap<Link, List<Point>> reversedLinkEndPoints;
+    private HashMap<LayoutEdge, LayoutEdge> bottomEdgeHash;
+    private HashMap<Link, List<Point>> splitStartPoints;
+    private HashMap<Link, List<Point>> splitEndPoints;
+    private LayoutGraph graph;
+    private List<LayoutNode>[] layers;
+    private int layerCount;
+    private Set<? extends Vertex> firstLayerHint;
+    private Set<? extends Vertex> lastLayerHint;
+    private Set<? extends Link> importantLinks;
+    private Set<Link> linksToFollow;
+
+    private class LayoutNode {
+
+        public int x;
+        public int y;
+        public int width;
+        public int height;
+        public int layer = -1;
+        public int xOffset;
+        public int yOffset;
+        public int bottomYOffset;
+        public Vertex vertex; // Only used for non-dummy nodes, otherwise null
+
+        public List<LayoutEdge> preds = new ArrayList<>();
+        public List<LayoutEdge> succs = new ArrayList<>();
+        public HashMap<Integer, Integer> outOffsets = new HashMap<>();
+        public HashMap<Integer, Integer> inOffsets = new HashMap<>();
+        public int pos = -1; // Position within layer
+
+        public int crossingNumber;
+
+        @Override
+        public String toString() {
+            return "Node " + vertex;
+        }
+    }
+
+    private class LayoutEdge {
+
+        public LayoutNode from;
+        public LayoutNode to;
+        public int relativeFrom;
+        public int relativeTo;
+        public Link link;
+        public boolean vip;
+    }
+
+    private abstract class AlgorithmPart {
+
+        public void start() {
+            if (CHECK) {
+                preCheck();
+            }
+
+            long start = 0;
+            if (TRACE) {
+                System.out.println("##################################################");
+                System.out.println("Starting part " + this.getClass().getName());
+                start = System.currentTimeMillis();
+            }
+            run();
+            if (TRACE) {
+                System.out.println("Timing for " + this.getClass().getName() + " is " + (System.currentTimeMillis() - start));
+                printStatistics();
+            }
+
+            if (CHECK) {
+                postCheck();
+            }
+        }
+
+        protected abstract void run();
+
+        protected void printStatistics() {
+        }
+
+        protected void postCheck() {
+        }
+
+        protected void preCheck() {
+        }
+    }
+
+    public HierarchicalLayoutManager() {
+        this(Combine.NONE);
+    }
+
+    public HierarchicalLayoutManager(Combine b) {
+        this.combine = b;
+        this.dummyWidth = DUMMY_WIDTH;
+        this.dummyHeight = DUMMY_HEIGHT;
+        this.xOffset = X_OFFSET;
+        this.layerOffset = LAYER_OFFSET;
+        this.maxLayerLength = MAX_LAYER_LENGTH;
+        this.minLayerDifference = MIN_LAYER_DIFFERENCE;
+        this.linksToFollow = new HashSet<>();
+    }
+
+    public int getMaxLayerLength() {
+        return maxLayerLength;
+    }
+
+    public void setMaxLayerLength(int v) {
+        maxLayerLength = v;
+    }
+
+    public void setMinLayerDifference(int v) {
+        minLayerDifference = v;
+    }
+
+    @Override
+    public void doLayout(LayoutGraph graph) {
+        doLayout(graph, new HashSet<Vertex>(), new HashSet<Vertex>(), new HashSet<Link>());
+
+    }
+
+    @Override
+    public void doLayout(LayoutGraph graph, Set<? extends Vertex> firstLayerHint, Set<? extends Vertex> lastLayerHint, Set<? extends Link> importantLinks) {
+
+        this.importantLinks = importantLinks;
+        this.graph = graph;
+        this.firstLayerHint = firstLayerHint;
+        this.lastLayerHint = lastLayerHint;
+
+        vertexToLayoutNode = new HashMap<>();
+        reversedLinks = new HashSet<>();
+        reversedLinkStartPoints = new HashMap<>();
+        reversedLinkEndPoints = new HashMap<>();
+        bottomEdgeHash = new HashMap<>();
+        nodes = new ArrayList<>();
+        splitStartPoints = new HashMap<>();
+        splitEndPoints = new HashMap<>();
+
+        // #############################################################
+        // Step 1: Build up data structure
+        new BuildDatastructure().start();
+
+        // #############################################################
+        // STEP 2: Reverse edges, handle backedges
+        new ReverseEdges().start();
+
+        for (LayoutNode n : nodes) {
+            ArrayList<LayoutEdge> tmpArr = new ArrayList<>();
+            for (LayoutEdge e : n.succs) {
+                if (importantLinks.contains(e.link)) {
+                    tmpArr.add(e);
+                }
+            }
+
+            for (LayoutEdge e : tmpArr) {
+                //System.out.println("Removed " + e);
+                e.from.succs.remove(e);
+                e.to.preds.remove(e);
+            }
+        }
+
+        // #############################################################
+        // STEP 3: Assign layers
+        new AssignLayers().start();
+
+        // #############################################################
+        // STEP 4: Create dummy nodes
+        new CreateDummyNodes().start();
+
+        // #############################################################
+        // STEP 5: Crossing Reduction
+        new CrossingReduction().start();
+
+        // #############################################################
+        // STEP 7: Assign X coordinates
+        new AssignXCoordinates().start();
+
+        // #############################################################
+        // STEP 6: Assign Y coordinates
+        new AssignYCoordinates().start();
+
+        // #############################################################
+        // STEP 8: Write back to interface
+        new WriteResult().start();
+    }
+
+    private class WriteResult extends AlgorithmPart {
+
+        private int pointCount;
+
+        @Override
+        protected void run() {
+
+            HashMap<Vertex, Point> vertexPositions = new HashMap<>();
+            HashMap<Link, List<Point>> linkPositions = new HashMap<>();
+            for (Vertex v : graph.getVertices()) {
+                LayoutNode n = vertexToLayoutNode.get(v);
+                assert !vertexPositions.containsKey(v);
+                vertexPositions.put(v, new Point(n.x + n.xOffset, n.y + n.yOffset));
+            }
+
+            for (LayoutNode n : nodes) {
+
+                for (LayoutEdge e : n.preds) {
+                    if (e.link != null) {
+                        ArrayList<Point> points = new ArrayList<>();
+
+                        Point p = new Point(e.to.x + e.relativeTo, e.to.y + e.to.yOffset + e.link.getTo().getRelativePosition().y);
+                        points.add(p);
+                        if (e.to.inOffsets.containsKey(e.relativeTo)) {
+                            points.add(new Point(p.x, p.y + e.to.inOffsets.get(e.relativeTo) + e.link.getTo().getRelativePosition().y));
+                        }
+
+                        LayoutNode cur = e.from;
+                        LayoutNode other = e.to;
+                        LayoutEdge curEdge = e;
+                        while (cur.vertex == null && cur.preds.size() != 0) {
+                            if (points.size() > 1 && points.get(points.size() - 1).x == cur.x + cur.width / 2 && points.get(points.size() - 2).x == cur.x + cur.width / 2) {
+                                points.remove(points.size() - 1);
+                            }
+                            points.add(new Point(cur.x + cur.width / 2, cur.y + cur.height));
+                            if (points.size() > 1 && points.get(points.size() - 1).x == cur.x + cur.width / 2 && points.get(points.size() - 2).x == cur.x + cur.width / 2) {
+                                points.remove(points.size() - 1);
+                            }
+                            points.add(new Point(cur.x + cur.width / 2, cur.y));
+                            assert cur.preds.size() == 1;
+                            curEdge = cur.preds.get(0);
+                            cur = curEdge.from;
+                        }
+
+                        p = new Point(cur.x + curEdge.relativeFrom, cur.y + cur.height - cur.bottomYOffset + (curEdge.link == null ? 0 : curEdge.link.getFrom().getRelativePosition().y));
+                        if (curEdge.from.outOffsets.containsKey(curEdge.relativeFrom)) {
+                            points.add(new Point(p.x, p.y + curEdge.from.outOffsets.get(curEdge.relativeFrom) + (curEdge.link == null ? 0 : curEdge.link.getFrom().getRelativePosition().y)));
+                        }
+                        points.add(p);
+
+                        Collections.reverse(points);
+
+
+
+                        if (cur.vertex == null && cur.preds.size() == 0) {
+
+                            if (reversedLinkEndPoints.containsKey(e.link)) {
+                                for (Point p1 : reversedLinkEndPoints.get(e.link)) {
+                                    points.add(new Point(p1.x + e.to.x, p1.y + e.to.y));
+                                }
+                            }
+
+                            if (splitStartPoints.containsKey(e.link)) {
+                                points.add(0, null);
+                                points.addAll(0, splitStartPoints.get(e.link));
+
+                                //checkPoints(points);
+                                if (reversedLinks.contains(e.link)) {
+                                    Collections.reverse(points);
+                                }
+                                assert !linkPositions.containsKey(e.link);
+                                linkPositions.put(e.link, points);
+                            } else {
+                                splitEndPoints.put(e.link, points);
+                            }
+
+                        } else {
+                            if (reversedLinks.contains(e.link)) {
+                                Collections.reverse(points);
+                            }
+                            if (reversedLinkStartPoints.containsKey(e.link)) {
+                                for (Point p1 : reversedLinkStartPoints.get(e.link)) {
+                                    points.add(new Point(p1.x + cur.x, p1.y + cur.y));
+                                }
+                            }
+
+                            if (reversedLinkEndPoints.containsKey(e.link)) {
+                                for (Point p1 : reversedLinkEndPoints.get(e.link)) {
+                                    points.add(0, new Point(p1.x + other.x, p1.y + other.y));
+                                }
+                            }
+
+                            assert !linkPositions.containsKey(e.link);
+                            linkPositions.put(e.link, points);
+                        }
+                        pointCount += points.size();
+
+                        // No longer needed!
+                        e.link = null;
+                    }
+                }
+
+                for (LayoutEdge e : n.succs) {
+                    if (e.link != null) {
+                        ArrayList<Point> points = new ArrayList<>();
+                        Point p = new Point(e.from.x + e.relativeFrom, e.from.y + e.from.height - e.from.bottomYOffset + e.link.getFrom().getRelativePosition().y);
+                        points.add(p);
+                        if (e.from.outOffsets.containsKey(e.relativeFrom)) {
+                            points.add(new Point(p.x, p.y + e.from.outOffsets.get(e.relativeFrom) + e.link.getFrom().getRelativePosition().y));
+                        }
+
+                        LayoutNode cur = e.to;
+                        LayoutNode other = e.from;
+                        LayoutEdge curEdge = e;
+                        while (cur.vertex == null && cur.succs.size() != 0) {
+                            if (points.size() > 1 && points.get(points.size() - 1).x == cur.x + cur.width / 2 && points.get(points.size() - 2).x == cur.x + cur.width / 2) {
+                                points.remove(points.size() - 1);
+                            }
+                            points.add(new Point(cur.x + cur.width / 2, cur.y));
+                            if (points.size() > 1 && points.get(points.size() - 1).x == cur.x + cur.width / 2 && points.get(points.size() - 2).x == cur.x + cur.width / 2) {
+                                points.remove(points.size() - 1);
+                            }
+                            points.add(new Point(cur.x + cur.width / 2, cur.y + cur.height));
+                            if (cur.succs.size() == 0) {
+                                break;
+                            }
+                            assert cur.succs.size() == 1;
+                            curEdge = cur.succs.get(0);
+                            cur = curEdge.to;
+                        }
+
+
+                        p = new Point(cur.x + curEdge.relativeTo, cur.y + cur.yOffset + ((curEdge.link == null) ? 0 : curEdge.link.getTo().getRelativePosition().y));
+                        points.add(p);
+                        if (curEdge.to.inOffsets.containsKey(curEdge.relativeTo)) {
+                            points.add(new Point(p.x, p.y + curEdge.to.inOffsets.get(curEdge.relativeTo) + ((curEdge.link == null) ? 0 : curEdge.link.getTo().getRelativePosition().y)));
+                        }
+
+
+                        if (cur.succs.size() == 0 && cur.vertex == null) {
+                            if (reversedLinkStartPoints.containsKey(e.link)) {
+                                for (Point p1 : reversedLinkStartPoints.get(e.link)) {
+                                    points.add(0, new Point(p1.x + other.x, p1.y + other.y));
+                                }
+                            }
+
+                            if (splitEndPoints.containsKey(e.link)) {
+                                points.add(null);
+                                points.addAll(splitEndPoints.get(e.link));
+
+                                //checkPoints(points);
+                                if (reversedLinks.contains(e.link)) {
+                                    Collections.reverse(points);
+                                }
+                                assert !linkPositions.containsKey(e.link);
+                                linkPositions.put(e.link, points);
+                            } else {
+                                splitStartPoints.put(e.link, points);
+                            }
+                        } else {
+
+                            if (reversedLinkStartPoints.containsKey(e.link)) {
+                                for (Point p1 : reversedLinkStartPoints.get(e.link)) {
+                                    points.add(0, new Point(p1.x + other.x, p1.y + other.y));
+                                }
+                            }
+                            if (reversedLinkEndPoints.containsKey(e.link)) {
+                                for (Point p1 : reversedLinkEndPoints.get(e.link)) {
+                                    points.add(new Point(p1.x + cur.x, p1.y + cur.y));
+                                }
+                            }
+                            if (reversedLinks.contains(e.link)) {
+                                Collections.reverse(points);
+                            }
+                            //checkPoints(points);
+                            assert !linkPositions.containsKey(e.link);
+                            linkPositions.put(e.link, points);
+                        }
+
+                        pointCount += points.size();
+                        e.link = null;
+                    }
+                }
+            }
+
+            int minX = Integer.MAX_VALUE;
+            int minY = Integer.MAX_VALUE;
+            for (Vertex v : vertexPositions.keySet()) {
+                Point p = vertexPositions.get(v);
+                minX = Math.min(minX, p.x);
+                minY = Math.min(minY, p.y);
+            }
+
+            for (Link l : linkPositions.keySet()) {
+                List<Point> points = linkPositions.get(l);
+                for (Point p : points) {
+                    if (p != null) {
+                        minX = Math.min(minX, p.x);
+                        minY = Math.min(minY, p.y);
+                    }
+                }
+
+            }
+
+            for (Vertex v : vertexPositions.keySet()) {
+                Point p = vertexPositions.get(v);
+                p.x -= minX;
+                p.y -= minY;
+                v.setPosition(p);
+            }
+
+            for (Link l : linkPositions.keySet()) {
+                List<Point> points = linkPositions.get(l);
+                for (Point p : points) {
+                    if (p != null) {
+                        p.x -= minX;
+                        p.y -= minY;
+                    }
+                }
+                l.setControlPoints(points);
+
+            }
+        }
+
+        @Override
+        protected void printStatistics() {
+            System.out.println("Number of nodes: " + nodes.size());
+            int edgeCount = 0;
+            for (LayoutNode n : nodes) {
+                edgeCount += n.succs.size();
+            }
+            System.out.println("Number of edges: " + edgeCount);
+            System.out.println("Number of points: " + pointCount);
+        }
+    }
+
+    private static class Segment {
+
+        public float d;
+        public int orderNumber = -1;
+        public ArrayList<LayoutNode> nodes = new ArrayList<>();
+        public HashSet<Segment> succs = new HashSet<>();
+        public HashSet<Segment> preds = new HashSet<>();
+        public Region region;
+    }
+    private static final Comparator<Segment> segmentComparator = new Comparator<Segment>() {
+
+        @Override
+        public int compare(Segment s1, Segment s2) {
+            return s1.orderNumber - s2.orderNumber;
+        }
+    };
+
+    private static class Region {
+
+        public float d;
+        public int minOrderNumber;
+        public SortedSet<Segment> segments = new TreeSet<>(segmentComparator);
+        public HashSet<Region> succs = new HashSet<>(4);
+        public HashSet<Region> preds = new HashSet<>(4);
+    }
+    private static final Comparator<Region> regionComparator = new Comparator<Region>() {
+
+        @Override
+        public int compare(Region r1, Region r2) {
+            return r1.minOrderNumber - r2.minOrderNumber;
+        }
+    };
+    private static final Comparator<LayoutNode> nodePositionComparator = new Comparator<LayoutNode>() {
+
+        @Override
+        public int compare(LayoutNode n1, LayoutNode n2) {
+            return n1.pos - n2.pos;
+        }
+    };
+    private static final Comparator<LayoutNode> nodeProcessingDownComparator = new Comparator<LayoutNode>() {
+        @Override
+        public int compare(LayoutNode n1, LayoutNode n2) {
+            if (n1.vertex == null) {
+                if (n2.vertex == null) {
+                    return 0;
+                }
+                return -1;
+            }
+            if (n2.vertex == null) {
+                return 1;
+            }
+            return n1.preds.size() - n2.preds.size();
+        }
+    };
+    private static final Comparator<LayoutNode> nodeProcessingUpComparator = new Comparator<LayoutNode>() {
+
+        @Override
+        public int compare(LayoutNode n1, LayoutNode n2) {
+            if (n1.vertex == null) {
+                if (n2.vertex == null) {
+                    return 0;
+                }
+                return -1;
+            }
+            if (n2.vertex == null) {
+                return 1;
+            }
+            return n1.succs.size() - n2.succs.size();
+        }
+    };
+
+    private class AssignXCoordinates extends AlgorithmPart {
+
+        private ArrayList<Integer>[] space;
+        private ArrayList<LayoutNode>[] downProcessingOrder;
+        private ArrayList<LayoutNode>[] upProcessingOrder;
+
+        private void initialPositions() {
+            for (LayoutNode n : nodes) {
+                n.x = space[n.layer].get(n.pos);
+            }
+        }
+        
+        @SuppressWarnings("unchecked")
+        private void createArrays() {
+            space = new ArrayList[layers.length];
+            downProcessingOrder = new ArrayList[layers.length];
+            upProcessingOrder = new ArrayList[layers.length];
+        }
+
+        @Override
+        protected void run() {
+            createArrays();
+
+            for (int i = 0; i < layers.length; i++) {
+                space[i] = new ArrayList<>();
+                downProcessingOrder[i] = new ArrayList<>();
+                upProcessingOrder[i] = new ArrayList<>();
+
+                int curX = 0;
+                for (LayoutNode n : layers[i]) {
+                    space[i].add(curX);
+                    curX += n.width + xOffset;
+                    downProcessingOrder[i].add(n);
+                    upProcessingOrder[i].add(n);
+                }
+
+                Collections.sort(downProcessingOrder[i], nodeProcessingDownComparator);
+                Collections.sort(upProcessingOrder[i], nodeProcessingUpComparator);
+            }
+
+            initialPositions();
+            for (int i = 0; i < SWEEP_ITERATIONS; i++) {
+                sweepDown();
+                sweepUp();
+            }
+ 
+            sweepDown();
+            //for (int i = 0; i < SWEEP_ITERATIONS; i++) {
+            //    doubleSweep();
+            //}            
+        }
+
+        private int calculateOptimalDown(LayoutNode n) {
+            int size = n.preds.size();
+            if (size == 0) {
+                return n.x;
+            }
+            int[] values = new int[size];
+            for (int i = 0; i < size; i++) {
+                LayoutEdge e = n.preds.get(i);
+                values[i] = e.from.x + e.relativeFrom - e.relativeTo;
+                if (e.vip) {
+                    return values[i];
+                }
+            }
+            return median(values);
+        }
+
+        private int calculateOptimalBoth(LayoutNode n) {
+            if (n.preds.size() == n.succs.size()) {
+                return n.x;
+            }
+            
+            int[] values = new int[n.preds.size() + n.succs.size()];
+            int i = 0;
+
+            for (LayoutEdge e : n.preds) {
+                values[i] = e.from.x + e.relativeFrom - e.relativeTo;
+                i++;
+            }
+
+            for (LayoutEdge e : n.succs) {
+                values[i] = e.to.x + e.relativeTo - e.relativeFrom;
+                i++;
+            }
+
+            return median(values);
+        }
+
+        private int calculateOptimalUp(LayoutNode n) {
+            int size = n.succs.size();
+            if (size == 0) {
+                return n.x;
+            }
+            int[] values = new int[size];
+            for (int i = 0; i < size; i++) {
+                LayoutEdge e = n.succs.get(i);
+                values[i] = e.to.x + e.relativeTo - e.relativeFrom;
+                if (e.vip) {
+                    return values[i];
+                }
+            }
+            return median(values);
+        }
+
+        private int median(int[] values) {
+            Arrays.sort(values);
+            if (values.length % 2 == 0) {
+                return (values[values.length / 2 - 1] + values[values.length / 2]) / 2;
+            } else {
+                return values[values.length / 2];
+            }
+        }
+
+        private void sweepUp() {
+            for (int i = layers.length - 1; i >= 0; i--) {
+                NodeRow r = new NodeRow(space[i]);
+                for (LayoutNode n : upProcessingOrder[i]) {
+                    int optimal = calculateOptimalUp(n);
+                    r.insert(n, optimal);
+                }
+            }
+        }
+
+        private void doubleSweep() {
+            for (int i = layers.length - 2; i >= 0; i--) {
+                NodeRow r = new NodeRow(space[i]);
+                for (LayoutNode n : upProcessingOrder[i]) {
+                    int optimal = calculateOptimalBoth(n);
+                    r.insert(n, optimal);
+                }
+            }
+        }
+
+        private void sweepDown() {
+            for (int i = 1; i < layers.length; i++) {
+                NodeRow r = new NodeRow(space[i]);
+                for (LayoutNode n : downProcessingOrder[i]) {
+                    int optimal = calculateOptimalDown(n);
+                    r.insert(n, optimal);
+                }
+            }
+        }
+    }
+
+    private static class NodeRow {
+
+        private TreeSet<LayoutNode> treeSet;
+        private ArrayList<Integer> space;
+
+        public NodeRow(ArrayList<Integer> space) {
+            treeSet = new TreeSet<>(nodePositionComparator);
+            this.space = space;
+        }
+
+        public int offset(LayoutNode n1, LayoutNode n2) {
+            int v1 = space.get(n1.pos) + n1.width;
+            int v2 = space.get(n2.pos);
+            return v2 - v1;
+        }
+
+        public void insert(LayoutNode n, int pos) {
+
+            SortedSet<LayoutNode> headSet = treeSet.headSet(n);
+
+            LayoutNode leftNeighbor = null;
+            int minX = Integer.MIN_VALUE;
+            if (!headSet.isEmpty()) {
+                leftNeighbor = headSet.last();
+                minX = leftNeighbor.x + leftNeighbor.width + offset(leftNeighbor, n);
+            }
+
+            if (pos < minX) {
+                n.x = minX;
+            } else {
+
+                LayoutNode rightNeighbor = null;
+                SortedSet<LayoutNode> tailSet = treeSet.tailSet(n);
+                int maxX = Integer.MAX_VALUE;
+                if (!tailSet.isEmpty()) {
+                    rightNeighbor = tailSet.first();
+                    maxX = rightNeighbor.x - offset(n, rightNeighbor) - n.width;
+                }
+
+                if (pos > maxX) {
+                    n.x = maxX;
+                } else {
+                    n.x = pos;
+                }
+
+                assert minX <= maxX;
+            }
+
+            treeSet.add(n);
+        }
+    }
+    private static Comparator<LayoutNode> crossingNodeComparator = new Comparator<LayoutNode>() {
+
+        @Override
+        public int compare(LayoutNode n1, LayoutNode n2) {
+            return n1.crossingNumber - n2.crossingNumber;
+        }
+    };
+
+    private class CrossingReduction extends AlgorithmPart {
+
+        @Override
+        public void preCheck() {
+            for (LayoutNode n : nodes) {
+                assert n.layer < layerCount;
+            }
+        }
+        
+        @SuppressWarnings("unchecked")
+        private void createLayers() {
+            layers = new List[layerCount];
+
+            for (int i = 0; i < layerCount; i++) {
+                layers[i] = new ArrayList<>();
+            }
+        }
+
+        @Override
+        protected void run() {
+            createLayers();
+
+            // Generate initial ordering
+            HashSet<LayoutNode> visited = new HashSet<>();
+            for (LayoutNode n : nodes) {
+                if (n.layer == 0) {
+                    layers[0].add(n);
+                    visited.add(n);
+                } else if (n.preds.size() == 0) {
+                    layers[n.layer].add(n);
+                    visited.add(n);
+                }
+            }
+
+            for (int i = 0; i < layers.length - 1; i++) {
+                for (LayoutNode n : layers[i]) {
+                    for (LayoutEdge e : n.succs) {
+                        if (!visited.contains(e.to)) {
+                            visited.add(e.to);
+                            layers[i + 1].add(e.to);
+                        }
+                    }
+                }
+            }
+
+
+            updatePositions();
+
+            initX();
+
+            // Optimize
+            for (int i = 0; i < CROSSING_ITERATIONS; i++) {
+                downSweep();
+                upSweep();
+            }
+            if (reversedLinks.isEmpty()) {
+                // This graph seems to be a tree or forest.
+                // A final down-sweep will usually give us a better layout.
+                downSweep();
+            }
+        }
+
+        private void initX() {
+
+            for (int i = 0; i < layers.length; i++) {
+                updateXOfLayer(i);
+            }
+        }
+
+        private void updateXOfLayer(int index) {
+            int x = 0;
+
+            for (LayoutNode n : layers[index]) {
+                n.x = x;
+                x += n.width + X_OFFSET;
+            }
+        }
+
+        private void updatePositions() {
+
+            for (int i = 0; i < layers.length; i++) {
+                int z = 0;
+                for (LayoutNode n : layers[i]) {
+                    n.pos = z;
+                    z++;
+                }
+            }
+        }
+
+        private void downSweep() {
+
+            // Downsweep
+            for (int i = 1; i < layerCount; i++) {
+
+                for (LayoutNode n : layers[i]) {
+                    n.crossingNumber = 0;
+                }
+
+                for (LayoutNode n : layers[i]) {
+
+                    int sum = 0;
+                    int count = 0;
+                    for (LayoutEdge e : n.preds) {
+                        int cur = e.from.x + e.relativeFrom;
+                        int factor = 1;
+                        if (e.vip) {
+                            factor = VIP_BONUS;
+                        }
+                        sum += cur*factor;
+                        count+=factor;
+                    }
+
+                    if (count > 0) {
+                        sum /= count;
+                        n.crossingNumber = sum;
+                    }
+                }
+
+
+                updateCrossingNumbers(i, true);
+                Collections.sort(layers[i], crossingNodeComparator);
+                updateXOfLayer(i);
+
+                int z = 0;
+                for (LayoutNode n : layers[i]) {
+                    n.pos = z;
+                    z++;
+                }
+            }
+        }
+
+        private void updateCrossingNumbers(int index, boolean down) {
+            for (int i = 0; i < layers[index].size(); i++) {
+                LayoutNode n = layers[index].get(i);
+                LayoutNode prev = null;
+                if (i > 0) {
+                    prev = layers[index].get(i - 1);
+                }
+                LayoutNode next = null;
+                if (i < layers[index].size() - 1) {
+                    next = layers[index].get(i + 1);
+                }
+
+                boolean cond = n.succs.isEmpty();
+                if (down) {
+                    cond = n.preds.isEmpty();
+                }
+
+                if (cond) {
+
+                    if (prev != null && next != null) {
+                        n.crossingNumber = (prev.crossingNumber + next.crossingNumber) / 2;
+                    } else if (prev != null) {
+                        n.crossingNumber = prev.crossingNumber;
+                    } else if (next != null) {
+                        n.crossingNumber = next.crossingNumber;
+                    }
+                }
+            }
+        }
+
+        private void upSweep() {
+            // Upsweep
+            for (int i = layerCount - 2; i >= 0; i--) {
+
+                for (LayoutNode n : layers[i]) {
+                    n.crossingNumber = 0;
+                }
+
+                for (LayoutNode n : layers[i]) {
+
+                    int count = 0;
+                    int sum = 0;
+                    for (LayoutEdge e : n.succs) {
+                        int cur = e.to.x + e.relativeTo;
+                        int factor = 1;
+                        if (e.vip) {
+                            factor = VIP_BONUS;
+                        }
+                        sum += cur*factor;
+                        count+=factor;
+                    }
+
+                    if (count > 0) {
+                        sum /= count;
+                        n.crossingNumber = sum;
+                    }
+
+                }
+
+                updateCrossingNumbers(i, false);
+                Collections.sort(layers[i], crossingNodeComparator);
+                updateXOfLayer(i);
+
+                int z = 0;
+                for (LayoutNode n : layers[i]) {
+                    n.pos = z;
+                    z++;
+                }
+            }
+        }
+
+        @Override
+        public void postCheck() {
+
+            HashSet<LayoutNode> visited = new HashSet<>();
+            for (int i = 0; i < layers.length; i++) {
+                for (LayoutNode n : layers[i]) {
+                    assert !visited.contains(n);
+                    assert n.layer == i;
+                    visited.add(n);
+                }
+            }
+
+        }
+    }
+
+    private class AssignYCoordinates extends AlgorithmPart {
+
+        @Override
+        protected void run() {
+            int curY = 0;
+
+            for (int i = 0; i < layers.length; i++) {
+                int maxHeight = 0;
+                int baseLine = 0;
+                int bottomBaseLine = 0;
+                for (LayoutNode n : layers[i]) {
+                    maxHeight = Math.max(maxHeight, n.height - n.yOffset - n.bottomYOffset);
+                    baseLine = Math.max(baseLine, n.yOffset);
+                    bottomBaseLine = Math.max(bottomBaseLine, n.bottomYOffset);
+                }
+
+                int maxXOffset = 0;
+                for (LayoutNode n : layers[i]) {
+                    if (n.vertex == null) {
+                        // Dummy node
+                        n.y = curY;
+                        n.height = maxHeight + baseLine + bottomBaseLine;
+
+                    } else {
+                        n.y = curY + baseLine + (maxHeight - (n.height - n.yOffset - n.bottomYOffset)) / 2 - n.yOffset;
+                    }
+
+                    for (LayoutEdge e : n.succs) {
+                        int curXOffset = Math.abs(n.x - e.to.x);
+                        maxXOffset = Math.max(curXOffset, maxXOffset);
+                    }
+                }
+
+                curY += maxHeight + baseLine + bottomBaseLine;
+                curY += layerOffset + (int) Math.sqrt(maxXOffset);
+            }
+        }
+    }
+
+    private class CreateDummyNodes extends AlgorithmPart {
+
+        private int oldNodeCount;
+
+        @Override
+        protected void preCheck() {
+            for (LayoutNode n : nodes) {
+                for (LayoutEdge e : n.succs) {
+                    assert e.from != null;
+                    assert e.from == n;
+                    assert e.from.layer < e.to.layer;
+                }
+
+                for (LayoutEdge e : n.preds) {
+                    assert e.to != null;
+                    assert e.to == n;
+                }
+            }
+        }
+
+        @Override
+        protected void run() {
+            oldNodeCount = nodes.size();
+
+
+            if (combine == Combine.SAME_OUTPUTS) {
+
+                Comparator<LayoutEdge> comparator = new Comparator<LayoutEdge>() {
+
+                    @Override
+                    public int compare(LayoutEdge e1, LayoutEdge e2) {
+                        return e1.to.layer - e2.to.layer;
+                    }
+                };
+                HashMap<Integer, List<LayoutEdge>> portHash = new HashMap<>();
+                ArrayList<LayoutNode> currentNodes = new ArrayList<>(nodes);
+                for (LayoutNode n : currentNodes) {
+                    portHash.clear();
+
+                    ArrayList<LayoutEdge> succs = new ArrayList<>(n.succs);
+                    HashMap<Integer, LayoutNode> topNodeHash = new HashMap<>();
+                    HashMap<Integer, HashMap<Integer, LayoutNode>> bottomNodeHash = new HashMap<>();
+                    for (LayoutEdge e : succs) {
+                        assert e.from.layer < e.to.layer;
+                        if (e.from.layer != e.to.layer - 1) {
+                            if (maxLayerLength != -1 && e.to.layer - e.from.layer > maxLayerLength/* && e.to.preds.size() > 1 && e.from.succs.size() > 1*/) {
+                                assert maxLayerLength > 2;
+                                e.to.preds.remove(e);
+                                e.from.succs.remove(e);
+
+                                LayoutEdge topEdge = null;
+
+                                if (combine == Combine.SAME_OUTPUTS && topNodeHash.containsKey(e.relativeFrom)) {
+                                    LayoutNode topNode = topNodeHash.get(e.relativeFrom);
+                                    topEdge = new LayoutEdge();
+                                    topEdge.relativeFrom = e.relativeFrom;
+                                    topEdge.from = e.from;
+                                    topEdge.relativeTo = topNode.width / 2;
+                                    topEdge.to = topNode;
+                                    topEdge.link = e.link;
+                                    topEdge.vip = e.vip;
+                                    e.from.succs.add(topEdge);
+                                    topNode.preds.add(topEdge);
+                                } else {
+
+                                    LayoutNode topNode = new LayoutNode();
+                                    topNode.layer = e.from.layer + 1;
+                                    topNode.width = DUMMY_WIDTH;
+                                    topNode.height = DUMMY_HEIGHT;
+                                    nodes.add(topNode);
+                                    topEdge = new LayoutEdge();
+                                    topEdge.relativeFrom = e.relativeFrom;
+                                    topEdge.from = e.from;
+                                    topEdge.relativeTo = topNode.width / 2;
+                                    topEdge.to = topNode;
+                                    topEdge.link = e.link;
+                                    topEdge.vip = e.vip;
+                                    e.from.succs.add(topEdge);
+                                    topNode.preds.add(topEdge);
+                                    topNodeHash.put(e.relativeFrom, topNode);
+                                    bottomNodeHash.put(e.relativeFrom, new HashMap<Integer, LayoutNode>());
+                                }
+
+                                HashMap<Integer, LayoutNode> hash = bottomNodeHash.get(e.relativeFrom);
+
+                                LayoutNode bottomNode = null;
+                                if (hash.containsKey(e.to.layer)) {
+                                    bottomNode = hash.get(e.to.layer);
+                                } else {
+
+                                    bottomNode = new LayoutNode();
+                                    bottomNode.layer = e.to.layer - 1;
+                                    bottomNode.width = DUMMY_WIDTH;
+                                    bottomNode.height = DUMMY_HEIGHT;
+                                    nodes.add(bottomNode);
+                                    hash.put(e.to.layer, bottomNode);
+                                }
+
+                                LayoutEdge bottomEdge = new LayoutEdge();
+                                bottomEdge.relativeTo = e.relativeTo;
+                                bottomEdge.to = e.to;
+                                bottomEdge.relativeFrom = bottomNode.width / 2;
+                                bottomEdge.from = bottomNode;
+                                bottomEdge.link = e.link;
+                                bottomEdge.vip = e.vip;
+                                e.to.preds.add(bottomEdge);
+                                bottomEdgeHash.put(topEdge, bottomEdge);
+                                bottomNode.succs.add(bottomEdge);
+
+                            } else {
+                                Integer i = e.relativeFrom;
+                                if (!portHash.containsKey(i)) {
+                                    portHash.put(i, new ArrayList<LayoutEdge>());
+                                }
+                                portHash.get(i).add(e);
+                            }
+                        }
+                    }
+
+                    succs = new ArrayList<>(n.succs);
+                    for (LayoutEdge e : succs) {
+
+                        Integer i = e.relativeFrom;
+                        if (portHash.containsKey(i)) {
+
+                            List<LayoutEdge> list = portHash.get(i);
+                            Collections.sort(list, comparator);
+
+                            if (list.size() == 1) {
+                                processSingleEdge(list.get(0));
+                            } else {
+
+                                int maxLayer = list.get(0).to.layer;
+                                for (LayoutEdge curEdge : list) {
+                                    maxLayer = Math.max(maxLayer, curEdge.to.layer);
+                                }
+
+
+                                int cnt = maxLayer - n.layer - 1;
+                                LayoutEdge[] edges = new LayoutEdge[cnt];
+                                LayoutNode[] nodes = new LayoutNode[cnt];
+                                edges[0] = new LayoutEdge();
+                                edges[0].from = n;
+                                edges[0].relativeFrom = i;
+                                edges[0].vip = e.vip;
+                                n.succs.add(edges[0]);
+
+                                nodes[0] = new LayoutNode();
+                                nodes[0].width = dummyWidth;
+                                nodes[0].height = dummyHeight;
+                                nodes[0].layer = n.layer + 1;
+                                nodes[0].preds.add(edges[0]);
+                                edges[0].to = nodes[0];
+                                edges[0].relativeTo = nodes[0].width / 2;
+                                for (int j = 1; j < cnt; j++) {
+                                    edges[j] = new LayoutEdge();
+                                    edges[j].vip = e.vip;
+                                    edges[j].from = nodes[j - 1];
+                                    edges[j].relativeFrom = nodes[j - 1].width / 2;
+                                    nodes[j - 1].succs.add(edges[j]);
+                                    nodes[j] = new LayoutNode();
+                                    nodes[j].width = dummyWidth;
+                                    nodes[j].height = dummyHeight;
+                                    nodes[j].layer = n.layer + j + 1;
+                                    nodes[j].preds.add(edges[j]);
+                                    edges[j].to = nodes[j];
+                                    edges[j].relativeTo = nodes[j].width / 2;
+                                }
+
+                                for (LayoutEdge curEdge : list) {
+                                    assert curEdge.to.layer - n.layer - 2 >= 0;
+                                    assert curEdge.to.layer - n.layer - 2 < cnt;
+                                    LayoutNode anchor = nodes[curEdge.to.layer - n.layer - 2];
+                                    anchor.succs.add(curEdge);
+                                    curEdge.from = anchor;
+                                    curEdge.relativeFrom = anchor.width / 2;
+                                    n.succs.remove(curEdge);
+                                }
+
+                            }
+
+                            portHash.remove(i);
+                        }
+                    }
+                }
+            } else if (combine == Combine.SAME_INPUTS) {
+                throw new UnsupportedOperationException("Currently not supported");
+            } else {
+                ArrayList<LayoutNode> currentNodes = new ArrayList<>(nodes);
+                for (LayoutNode n : currentNodes) {
+                    for (LayoutEdge e : n.succs) {
+                        processSingleEdge(e);
+                    }
+                }
+            }
+        }
+
+        private void processSingleEdge(LayoutEdge e) {
+            LayoutNode n = e.from;
+            if (e.to.layer > n.layer + 1) {
+                LayoutEdge last = e;
+                for (int i = n.layer + 1; i < last.to.layer; i++) {
+                    last = addBetween(last, i);
+                }
+            }
+        }
+
+        private LayoutEdge addBetween(LayoutEdge e, int layer) {
+            LayoutNode n = new LayoutNode();
+            n.width = dummyWidth;
+            n.height = dummyHeight;
+            n.layer = layer;
+            n.preds.add(e);
+            nodes.add(n);
+            LayoutEdge result = new LayoutEdge();
+            result.vip = e.vip;
+            n.succs.add(result);
+            result.from = n;
+            result.relativeFrom = n.width / 2;
+            result.to = e.to;
+            result.relativeTo = e.relativeTo;
+            e.relativeTo = n.width / 2;
+            e.to.preds.remove(e);
+            e.to.preds.add(result);
+            e.to = n;
+            return result;
+        }
+
+        @Override
+        public void printStatistics() {
+            System.out.println("Dummy nodes created: " + (nodes.size() - oldNodeCount));
+        }
+
+        @Override
+        public void postCheck() {
+            ArrayList<LayoutNode> currentNodes = new ArrayList<>(nodes);
+            for (LayoutNode n : currentNodes) {
+                for (LayoutEdge e : n.succs) {
+                    assert e.from.layer == e.to.layer - 1;
+                }
+            }
+
+            for (int i = 0; i < layers.length; i++) {
+                assert layers[i].size() > 0;
+                for (LayoutNode n : layers[i]) {
+                    assert n.layer == i;
+                }
+            }
+        }
+    }
+
+    private class AssignLayers extends AlgorithmPart {
+
+        @Override
+        public void preCheck() {
+            for (LayoutNode n : nodes) {
+                assert n.layer == -1;
+            }
+        }
+
+        @Override
+        protected void run() {
+
+            List<LayoutNode> insertOrder = new ArrayList<>();
+
+            HashSet<LayoutNode> set = new HashSet<>();
+            for (LayoutNode n : nodes) {
+                if (n.preds.size() == 0) {
+                    set.add(n);
+                    insertOrder.add(n);
+                    n.layer = 0;
+                }
+            }
+
+            int z = minLayerDifference;
+            HashSet<LayoutNode> newSet = new HashSet<>();
+            HashSet<LayoutNode> failed = new HashSet<>();
+            while (!set.isEmpty()) {
+
+                newSet.clear();
+                failed.clear();
+
+                for (LayoutNode n : set) {
+
+                    for (LayoutEdge se : n.succs) {
+                        LayoutNode s = se.to;
+                        if (!newSet.contains(s) && !failed.contains(s)) {
+                            boolean ok = true;
+                            for (LayoutEdge pe : s.preds) {
+                                LayoutNode p = pe.from;
+                                if (p.layer == -1) {
+                                    ok = false;
+                                    break;
+                                }
+                            }
+
+                            if (ok) {
+                                newSet.add(s);
+                            } else {
+                                failed.add(s);
+                            }
+                        }
+                    }
+
+                }
+
+                for (LayoutNode n : newSet) {
+                    n.layer = z;
+                    insertOrder.add(n);
+                }
+
+                // Swap sets
+                HashSet<LayoutNode> tmp = set;
+                set = newSet;
+                newSet = tmp;
+                z += minLayerDifference;
+            }
+
+            optimize(insertOrder);
+
+            layerCount = z - minLayerDifference;
+
+            for (Vertex v : lastLayerHint) {
+
+                LayoutNode n = vertexToLayoutNode.get(v);
+                assert n.succs.size() == 0;
+                n.layer = layerCount - 1;
+            }
+
+            for (Vertex v : firstLayerHint) {
+                LayoutNode n = vertexToLayoutNode.get(v);
+                assert n.preds.size() == 0;
+                n.layer = 0;
+                assert n.layer == 0;
+            }
+        }
+
+        public void optimize(List<LayoutNode> insertOrder) {
+            for (int i = insertOrder.size() - 1; i >= 0; i--) {
+                LayoutNode cur = insertOrder.get(i);
+                if (cur.succs.size() > cur.preds.size()) {
+                    int minLayer = cur.succs.get(0).to.layer;
+                    for (LayoutEdge e : cur.succs) {
+                        minLayer = Math.min(minLayer, e.to.layer);
+                    }
+                    cur.layer = minLayer - 1;
+                }
+            }
+        }
+
+        @Override
+        public void postCheck() {
+            for (LayoutNode n : nodes) {
+                assert n.layer >= 0;
+                assert n.layer < layerCount;
+                for (LayoutEdge e : n.succs) {
+                    assert e.from.layer < e.to.layer;
+                }
+            }
+        }
+    }
+
+    private class ReverseEdges extends AlgorithmPart {
+
+        private HashSet<LayoutNode> visited;
+        private HashSet<LayoutNode> active;
+
+        @Override
+        protected void run() {
+
+            // Remove self-edges
+            for (LayoutNode node : nodes) {
+                ArrayList<LayoutEdge> succs = new ArrayList<>(node.succs);
+                for (LayoutEdge e : succs) {
+                    assert e.from == node;
+                    if (e.to == node) {
+                        node.succs.remove(e);
+                        node.preds.remove(e);
+                    }
+                }
+            }
+
+            // Reverse inputs of roots
+            for (LayoutNode node : nodes) {
+                if (node.vertex.isRoot()) {
+                    boolean ok = true;
+                    for (LayoutEdge e : node.preds) {
+                        if (e.from.vertex.isRoot()) {
+                            ok = false;
+                            break;
+                        }
+                    }
+                    if (ok) {
+                        reverseAllInputs(node);
+                    }
+                }
+            }
+
+
+            // Start DFS and reverse back edges
+            visited = new HashSet<>();
+            active = new HashSet<>();
+            for (LayoutNode node : nodes) {
+                DFS(node);
+            }
+
+
+            for (LayoutNode node : nodes) {
+
+                SortedSet<Integer> reversedDown = new TreeSet<>();
+
+                for (LayoutEdge e : node.succs) {
+                    if (reversedLinks.contains(e.link)) {
+                        reversedDown.add(e.relativeFrom);
+                    }
+                }
+
+
+                SortedSet<Integer> reversedUp = null;
+                if (reversedDown.size() == 0) {
+                    reversedUp = new TreeSet<>(Collections.reverseOrder());
+                } else {
+                    reversedUp = new TreeSet<>();
+                }
+
+                for (LayoutEdge e : node.preds) {
+                    if (reversedLinks.contains(e.link)) {
+                        reversedUp.add(e.relativeTo);
+                    }
+                }
+
+                final int offset = X_OFFSET + DUMMY_WIDTH;
+
+                int curX = 0;
+                int curWidth = node.width + reversedDown.size() * offset;
+                for (int pos : reversedDown) {
+                    ArrayList<LayoutEdge> reversedSuccs = new ArrayList<>();
+                    for (LayoutEdge e : node.succs) {
+                        if (e.relativeFrom == pos && reversedLinks.contains(e.link)) {
+                            reversedSuccs.add(e);
+                            e.relativeFrom = curWidth;
+                        }
+                    }
+
+                    ArrayList<Point> startPoints = new ArrayList<>();
+                    startPoints.add(new Point(curWidth, curX));
+                    startPoints.add(new Point(pos, curX));
+                    startPoints.add(new Point(pos, reversedDown.size() * offset));
+                    for (LayoutEdge e : reversedSuccs) {
+                        reversedLinkStartPoints.put(e.link, startPoints);
+                    }
+
+                    node.inOffsets.put(pos, -curX);
+                    curX += offset;
+                    node.height += offset;
+                    node.yOffset += offset;
+                    curWidth -= offset;
+                }
+                node.width += reversedDown.size() * offset;
+
+                if (reversedDown.size() == 0) {
+                    curX = offset;
+                } else {
+                    curX = -offset;
+                }
+
+                curX = 0;
+                int minX = 0;
+                if (reversedDown.size() != 0) {
+                    minX = -offset * reversedUp.size();
+                }
+
+                int oldNodeHeight = node.height;
+                for (int pos : reversedUp) {
+                    ArrayList<LayoutEdge> reversedPreds = new ArrayList<>();
+                    for (LayoutEdge e : node.preds) {
+                        if (e.relativeTo == pos && reversedLinks.contains(e.link)) {
+                            if (reversedDown.size() == 0) {
+                                e.relativeTo = node.width + offset;
+                            } else {
+                                e.relativeTo = curX - offset;
+                            }
+
+                            reversedPreds.add(e);
+                        }
+                    }
+                    node.height += offset;
+                    ArrayList<Point> endPoints = new ArrayList<>();
+
+                    if (reversedDown.size() == 0) {
+
+                        curX += offset;
+                        node.width += offset;
+                        endPoints.add(new Point(node.width, node.height));
+
+                    } else {
+                        curX -= offset;
+                        node.width += offset;
+                        endPoints.add(new Point(curX, node.height));
+                    }
+
+                    node.outOffsets.put(pos - minX, curX);
+                    curX += offset;
+                    node.bottomYOffset += offset;
+
+
+                    endPoints.add(new Point(pos, node.height));
+                    endPoints.add(new Point(pos, oldNodeHeight));
+                    for (LayoutEdge e : reversedPreds) {
+                        reversedLinkEndPoints.put(e.link, endPoints);
+                    }
+                }
+
+
+                if (minX < 0) {
+                    for (LayoutEdge e : node.preds) {
+                        e.relativeTo -= minX;
+                    }
+
+                    for (LayoutEdge e : node.succs) {
+                        e.relativeFrom -= minX;
+                    }
+
+                    node.xOffset = -minX;
+                    node.width += -minX;
+                }
+            }
+
+        }
+
+        private void DFS(LayoutNode startNode) {
+            if (visited.contains(startNode)) {
+                return;
+            }
+
+            Stack<LayoutNode> stack = new Stack<>();
+            stack.push(startNode);
+
+            while (!stack.empty()) {
+                LayoutNode node = stack.pop();
+
+                if (visited.contains(node)) {
+                    // Node no longer active
+                    active.remove(node);
+                    continue;
+                }
+
+                // Repush immediately to know when no longer active
+                stack.push(node);
+                visited.add(node);
+                active.add(node);
+
+                ArrayList<LayoutEdge> succs = new ArrayList<>(node.succs);
+                for (LayoutEdge e : succs) {
+                    if (active.contains(e.to)) {
+                        assert visited.contains(e.to);
+                        // Encountered back edge
+                        reverseEdge(e);
+                    } else if (!visited.contains(e.to) && (linksToFollow.size() == 0 || linksToFollow.contains(e.link))) {
+                        stack.push(e.to);
+                    }
+                }
+            }
+        }
+
+        private void reverseAllInputs(LayoutNode node) {
+            for (LayoutEdge e : node.preds) {
+                assert !reversedLinks.contains(e.link);
+                reversedLinks.add(e.link);
+                node.succs.add(e);
+                e.from.preds.add(e);
+                e.from.succs.remove(e);
+                int oldRelativeFrom = e.relativeFrom;
+                int oldRelativeTo = e.relativeTo;
+                e.to = e.from;
+                e.from = node;
+                e.relativeFrom = oldRelativeTo;
+                e.relativeTo = oldRelativeFrom;
+            }
+            node.preds.clear();
+        }
+
+        private void reverseEdge(LayoutEdge e) {
+            assert !reversedLinks.contains(e.link);
+            reversedLinks.add(e.link);
+
+            LayoutNode oldFrom = e.from;
+            LayoutNode oldTo = e.to;
+            int oldRelativeFrom = e.relativeFrom;
+            int oldRelativeTo = e.relativeTo;
+
+            e.from = oldTo;
+            e.to = oldFrom;
+            e.relativeFrom = oldRelativeTo;
+            e.relativeTo = oldRelativeFrom;
+
+            oldFrom.succs.remove(e);
+            oldFrom.preds.add(e);
+            oldTo.preds.remove(e);
+            oldTo.succs.add(e);
+        }
+
+        @Override
+        public void postCheck() {
+
+            for (LayoutNode n : nodes) {
+
+                HashSet<LayoutNode> curVisited = new HashSet<>();
+                Queue<LayoutNode> queue = new LinkedList<>();
+                for (LayoutEdge e : n.succs) {
+                    LayoutNode s = e.to;
+                    queue.add(s);
+                    curVisited.add(s);
+                }
+
+                while (!queue.isEmpty()) {
+                    LayoutNode curNode = queue.remove();
+
+                    for (LayoutEdge e : curNode.succs) {
+                        assert e.to != n;
+                        if (!curVisited.contains(e.to)) {
+                            queue.add(e.to);
+                            curVisited.add(e.to);
+                        }
+                    }
+                }
+            }
+        }
+    }
+    private Comparator<Link> linkComparator = new Comparator<Link>() {
+
+        @Override
+        public int compare(Link l1, Link l2) {
+
+            int result = l1.getFrom().getVertex().compareTo(l2.getFrom().getVertex());
+            if (result != 0) {
+                return result;
+            }
+            result = l1.getTo().getVertex().compareTo(l2.getTo().getVertex());
+            if (result != 0) {
+                return result;
+            }
+            result = l1.getFrom().getRelativePosition().x - l2.getFrom().getRelativePosition().x;
+            if (result != 0) {
+                return result;
+            }
+            result = l1.getTo().getRelativePosition().x - l2.getTo().getRelativePosition().x;
+            return result;
+        }
+    };
+
+    private class BuildDatastructure extends AlgorithmPart {
+
+        @Override
+        protected void run() {
+            // Set up nodes
+            List<Vertex> vertices = new ArrayList<>(graph.getVertices());
+            Collections.sort(vertices);
+
+            for (Vertex v : vertices) {
+                LayoutNode node = new LayoutNode();
+                Dimension size = v.getSize();
+                node.width = (int) size.getWidth();
+                node.height = (int) size.getHeight();
+                node.vertex = v;
+                nodes.add(node);
+                vertexToLayoutNode.put(v, node);
+            }
+
+            // Set up edges
+            List<Link> links = new ArrayList<>(graph.getLinks());
+            Collections.sort(links, linkComparator);
+            for (Link l : links) {
+                LayoutEdge edge = new LayoutEdge();
+                assert vertexToLayoutNode.containsKey(l.getFrom().getVertex());
+                assert vertexToLayoutNode.containsKey(l.getTo().getVertex());
+                edge.from = vertexToLayoutNode.get(l.getFrom().getVertex());
+                edge.to = vertexToLayoutNode.get(l.getTo().getVertex());
+                edge.relativeFrom = l.getFrom().getRelativePosition().x;
+                edge.relativeTo = l.getTo().getRelativePosition().x;
+                edge.link = l;
+                edge.from.succs.add(edge);
+                edge.to.preds.add(edge);
+                edge.vip = l.isVIP();
+            //assert edge.from != edge.to; // No self-loops allowed
+            }
+
+            for (Link l : importantLinks) {
+                if (!vertexToLayoutNode.containsKey(l.getFrom().getVertex()) ||
+                        vertexToLayoutNode.containsKey(l.getTo().getVertex())) {
+                    continue;
+                }
+                LayoutNode from = vertexToLayoutNode.get(l.getFrom().getVertex());
+                LayoutNode to = vertexToLayoutNode.get(l.getTo().getVertex());
+                for (LayoutEdge e : from.succs) {
+                    if (e.to == to) {
+                        linksToFollow.add(e.link);
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void postCheck() {
+
+            assert vertexToLayoutNode.keySet().size() == nodes.size();
+            assert nodes.size() == graph.getVertices().size();
+
+            for (Vertex v : graph.getVertices()) {
+
+                LayoutNode node = vertexToLayoutNode.get(v);
+                assert node != null;
+
+                for (LayoutEdge e : node.succs) {
+                    assert e.from == node;
+                }
+
+                for (LayoutEdge e : node.preds) {
+                    assert e.to == node;
+                }
+
+            }
+        }
+    }
+
+    @Override
+    public void doRouting(LayoutGraph graph) {
+        // Do nothing for now
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Node.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.hierarchicallayout;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Node<N, E> {
+
+    private N data;
+    private List<Edge<N, E>> inEdges;
+    private List<Edge<N, E>> outEdges;
+    private boolean visited;
+    private boolean active;
+    private boolean reachable;
+    private Graph<N, E> graph;
+
+    protected boolean isVisited() {
+        return visited;
+    }
+
+    protected void setVisited(boolean b) {
+        visited = b;
+    }
+
+    protected boolean isReachable() {
+        return reachable;
+    }
+
+    protected void setReachable(boolean b) {
+        reachable = b;
+    }
+
+    protected boolean isActive() {
+        return active;
+    }
+
+    protected void setActive(boolean b) {
+        active = b;
+    }
+
+    public int getInDegree() {
+        return getInDegree(true);
+    }
+
+    public int getInDegree(boolean countSelfLoops) {
+        if (countSelfLoops) {
+            return inEdges.size();
+        } else {
+            int cnt = 0;
+            for (Edge<N, E> e : inEdges) {
+                if (e.getSource() != this) {
+                    cnt++;
+                }
+            }
+            return cnt;
+        }
+    }
+
+    public int getOutDegree() {
+        return outEdges.size();
+    }
+
+    protected Node(Graph<N, E> graph, N data) {
+        setData(data);
+        this.graph = graph;
+        inEdges = new ArrayList<>();
+        outEdges = new ArrayList<>();
+    }
+
+    protected void addInEdge(Edge<N, E> e) {
+        inEdges.add(e);
+    }
+
+    public Graph<N, E> getGraph() {
+        return graph;
+    }
+
+    protected void addOutEdge(Edge<N, E> e) {
+        outEdges.add(e);
+    }
+
+    protected void removeInEdge(Edge<N, E> e) {
+        //assert inEdges.contains(e);
+        inEdges.remove(e);
+    }
+
+    protected void removeOutEdge(Edge<N, E> e) {
+        //assert outEdges.contains(e);
+        outEdges.remove(e);
+    }
+
+    public List<Edge<N, E>> getInEdges() {
+        return Collections.unmodifiableList(inEdges);
+    }
+
+    public List<Edge<N, E>> getOutEdges() {
+        return Collections.unmodifiableList(outEdges);
+    }
+
+    public List<Node<N, E>> getSuccessors() {
+        ArrayList<Node<N, E>> succ = new ArrayList<>();
+        for (Edge<N, E> e : getOutEdges()) {
+            Node<N, E> n = e.getDest();
+            if (!succ.contains(n)) {
+                succ.add(n);
+            }
+        }
+        return succ;
+    }
+
+    public List<Node<N, E>> getPredecessors() {
+        ArrayList<Node<N, E>> pred = new ArrayList<>();
+        for (Edge<N, E> e : getInEdges()) {
+            Node<N, E> n = e.getSource();
+            if (!pred.contains(n)) {
+                pred.add(n);
+            }
+        }
+        return pred;
+    }
+
+    public N getData() {
+        return data;
+    }
+
+    public void setData(N d) {
+        data = d;
+    }
+
+    @Override
+    public String toString() {
+        return "Node: " + data;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Timing.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.hierarchicallayout;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Timing {
+
+    private long lastValue;
+    private long sum;
+    private String name;
+
+    public Timing(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String toString() {
+        long val = sum;
+        if (lastValue != 0) {
+            // Timer running
+            long newValue = System.nanoTime();
+            val += (newValue - lastValue);
+        }
+        return "Timing for " + name + " is: " + val / 1000000 + " ms";
+    }
+
+    public void print() {
+        System.out.println(toString());
+    }
+
+    public void start() {
+        lastValue = System.nanoTime();
+    }
+
+    public void stop() {
+        if (lastValue == 0) {
+            throw new IllegalStateException("You must call start before stop");
+        }
+        long newValue = System.nanoTime();
+        sum += newValue - lastValue;
+        lastValue = 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Layout/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.layout" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.layout.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Layout/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.layout
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/layout/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Layout/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.layout-impl" basedir="..">
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+        <condition>
+            <not>
+                <available file="${harness.dir}" type="dir"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Layout/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=cb0889d9
+build.xml.script.CRC32=d65fccb9
+build.xml.stylesheet.CRC32=79c3b980
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=cb0889d9
+nbproject/build-impl.xml.script.CRC32=7f82736d
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Layout/nbproject/platform.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.javahelp,\
+    org.netbeans.modules.masterfs,\
+    org.netbeans.modules.options.keymap,\
+    org.netbeans.modules.sendopts,\
+    org.netbeans.modules.templates,\
+    org.openide.compat,\
+    org.openide.execution,\
+    org.openide.util.enumerations
+enabled.clusters=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Layout/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Layout/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.layout</code-name-base>
+            <suite-component/>
+            <module-dependencies/>
+            <public-packages>
+                <package>com.sun.hotspot.igv.layout</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Layout/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Layout/src/com/sun/hotspot/igv/layout/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=Layout
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutGraph.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.layout;
+
+import java.util.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class LayoutGraph {
+
+    private Set<? extends Link> links;
+    private SortedSet<Vertex> vertices;
+    private HashMap<Vertex, Set<Port>> inputPorts;
+    private HashMap<Vertex, Set<Port>> outputPorts;
+    private HashMap<Port, Set<Link>> portLinks;
+
+    public LayoutGraph(Set<? extends Link> links) {
+        this(links, new HashSet<Vertex>());
+    }
+
+    public LayoutGraph(Set<? extends Link> links, Set<? extends Vertex> additionalVertices) {
+        this.links = links;
+        assert verify();
+
+        vertices = new TreeSet<>();
+        portLinks = new HashMap<>(links.size());
+        inputPorts = new HashMap<>(links.size());
+        outputPorts = new HashMap<>(links.size());
+
+        for (Link l : links) {
+            Port p = l.getFrom();
+            Port p2 = l.getTo();
+            Vertex v1 = p.getVertex();
+            Vertex v2 = p2.getVertex();
+
+            if (!vertices.contains(v1)) {
+
+                outputPorts.put(v1, new HashSet<Port>(1));
+                inputPorts.put(v1, new HashSet<Port>(3));
+                vertices.add(v1);
+                assert vertices.contains(v1);
+            }
+
+            if (!vertices.contains(v2)) {
+                vertices.add(v2);
+                assert vertices.contains(v2);
+                outputPorts.put(v2, new HashSet<Port>(1));
+                inputPorts.put(v2, new HashSet<Port>(3));
+            }
+
+            if (!portLinks.containsKey(p)) {
+                HashSet<Link> hashSet = new HashSet<>(3);
+                portLinks.put(p, hashSet);
+            }
+
+            if (!portLinks.containsKey(p2)) {
+                portLinks.put(p2, new HashSet<Link>(3));
+            }
+
+            outputPorts.get(v1).add(p);
+            inputPorts.get(v2).add(p2);
+
+            portLinks.get(p).add(l);
+            portLinks.get(p2).add(l);
+        }
+
+        for (Vertex v : additionalVertices) {
+            if (!vertices.contains(v)) {
+                outputPorts.put(v, new HashSet<Port>(1));
+                inputPorts.put(v, new HashSet<Port>(3));
+                vertices.add(v);
+                vertices.contains(v);
+            }
+        }
+    }
+
+    public Set<Port> getInputPorts(Vertex v) {
+        return this.inputPorts.get(v);
+    }
+
+    public Set<Port> getOutputPorts(Vertex v) {
+        return this.outputPorts.get(v);
+    }
+
+    public Set<Link> getPortLinks(Port p) {
+        return portLinks.get(p);
+    }
+
+    public Set<? extends Link> getLinks() {
+        return links;
+    }
+
+    public boolean verify() {
+        return true;
+    }
+
+    public SortedSet<Vertex> getVertices() {
+        return vertices;
+    }
+
+    private void markNotRoot(Set<Vertex> notRootSet, Vertex v, Vertex startingVertex) {
+
+        if (notRootSet.contains(v)) {
+            return;
+        }
+        if (v != startingVertex) {
+            notRootSet.add(v);
+        }
+        Set<Port> outPorts = getOutputPorts(v);
+        for (Port p : outPorts) {
+            Set<Link> portLinks = getPortLinks(p);
+            for (Link l : portLinks) {
+                Port other = l.getTo();
+                Vertex otherVertex = other.getVertex();
+                if (otherVertex != startingVertex) {
+                    markNotRoot(notRootSet, otherVertex, startingVertex);
+                }
+            }
+        }
+    }
+
+    // Returns a set of vertices with the following properties:
+    // - All Vertices in the set startingRoots are elements of the set.
+    // - When starting a DFS at every vertex in the set, every vertex of the 
+    //   whole graph is visited.
+    public Set<Vertex> findRootVertices(Set<Vertex> startingRoots) {
+
+        Set<Vertex> notRootSet = new HashSet<>();
+        for (Vertex v : startingRoots) {
+            if (!notRootSet.contains(v)) {
+                markNotRoot(notRootSet, v, v);
+            }
+        }
+
+        Set<Vertex> tmpVertices = getVertices();
+        for (Vertex v : tmpVertices) {
+            if (!notRootSet.contains(v)) {
+                if (this.getInputPorts(v).size() == 0) {
+                    markNotRoot(notRootSet, v, v);
+                }
+            }
+        }
+
+        for (Vertex v : tmpVertices) {
+            if (!notRootSet.contains(v)) {
+                markNotRoot(notRootSet, v, v);
+            }
+        }
+
+        Set<Vertex> result = new HashSet<>();
+        for (Vertex v : tmpVertices) {
+            if (!notRootSet.contains(v)) {
+                result.add(v);
+            }
+        }
+        assert tmpVertices.size() == 0 || result.size() > 0;
+        return result;
+    }
+
+    public Set<Vertex> findRootVertices() {
+        return findRootVertices(new HashSet<Vertex>());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutManager.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.layout;
+
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface LayoutManager {
+
+    public void doLayout(LayoutGraph graph);
+
+    public void doLayout(LayoutGraph graph, Set<? extends Vertex> firstLayerHint, Set<? extends Vertex> lastLayerHint, Set<? extends Link> importantLinks);
+
+    public void doRouting(LayoutGraph graph);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Layout/src/com/sun/hotspot/igv/layout/Link.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.layout;
+
+import java.awt.Point;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface Link {
+
+    public Port getFrom();
+
+    public Port getTo();
+    
+    public boolean isVIP();
+
+    public List<Point> getControlPoints();
+
+    public void setControlPoints(List<Point> list);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Layout/src/com/sun/hotspot/igv/layout/Port.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.layout;
+
+import java.awt.Point;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface Port {
+
+    public Vertex getVertex();
+
+    public Point getRelativePosition();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Layout/src/com/sun/hotspot/igv/layout/Vertex.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.layout;
+
+import java.awt.Dimension;
+import java.awt.Point;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface Vertex extends Comparable<Vertex> {
+
+    public Dimension getSize();
+
+    public Point getPosition();
+
+    public void setPosition(Point p);
+
+    public boolean isRoot();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.coordinator" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.oracle.graal.visualizer.outline.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.oracle.graal.visualizer.outline
+OpenIDE-Module-Layer: com/oracle/graal/visualizer/outline/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/oracle/graal/visualizer/outline/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.coordinator-impl" basedir="..">
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+        <condition>
+            <not>
+                <available file="${harness.dir}" type="dir"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=077de97c
+build.xml.script.CRC32=d29d586c
+build.xml.stylesheet.CRC32=79c3b980
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=077de97c
+nbproject/build-impl.xml.script.CRC32=03daa42d
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/nbproject/platform.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.javahelp,\
+    org.netbeans.modules.masterfs,\
+    org.netbeans.modules.options.keymap,\
+    org.netbeans.modules.sendopts,\
+    org.netbeans.modules.templates,\
+    org.openide.compat,\
+    org.openide.execution,\
+    org.openide.util.enumerations
+enabled.clusters=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.oracle.graal.visualizer.outline</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>at.ssw.visualizer.cfg</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.difference</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.settings</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.api.progress</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.23.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.actions</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.21.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.30.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.dialogs</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.18.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.explorer</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.34.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.filesystems</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.46.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.loaders</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.20.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.nodes</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.20.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.39.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.oracle.graal.visualizer.outline</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,5 @@
+AdvancedOption_DisplayName_Coordinator=Settings
+AdvancedOption_Tooltip_Coordinator=Visualization Tool Settings
+CTL_OutlineTopComponent=Outline
+HINT_OutlineTopComponent=Displays loaded compilations.
+OpenIDE-Module-Name=OutlineView
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/CompilationNode.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,148 @@
+/*
+ * 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.visualizer.outline;
+
+import com.sun.hotspot.igv.data.*;
+import com.sun.hotspot.igv.data.services.GraphViewer;
+import java.awt.Image;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.Action;
+import javax.swing.JOptionPane;
+import org.openide.actions.OpenAction;
+import org.openide.cookies.OpenCookie;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.openide.util.ImageUtilities;
+import org.openide.util.Lookup;
+import org.openide.util.lookup.AbstractLookup;
+import org.openide.util.lookup.InstanceContent;
+import org.openide.util.lookup.Lookups;
+
+public class CompilationNode extends AbstractNode implements ChangedListener {
+
+    private CompilationNode(final Folder folder, Children children, InstanceContent content) {
+        super(children, new AbstractLookup(content));
+        this.setDisplayName(folder.getName());
+
+        if (folder instanceof Group) {
+            content.add(new OpenCookie() {
+
+                @Override
+                public void open() {
+                    final List<InputGraph> graphs = ((Group) folder).getGraphs();
+                    if (graphs.isEmpty()) {
+                        JOptionPane.showMessageDialog(null, "Cannot open compilation, because there was no snapshots recorded!");
+                    } else {
+                        Lookup.getDefault().lookup(GraphViewer.class).view(graphs.get(0));
+                    }
+                }
+            });
+        }
+        content.add(folder);
+        folder.getChangedEvent().addListener(this);
+    }
+
+    @Override
+    public void changed(Object folder) {
+        if (this.getChildren() == Children.LEAF) {
+            setChildren(createFolderChildren((Folder) folder));
+            this.fireIconChange();
+        }
+    }
+
+    private static class FolderChildren extends Children.Keys<Folder> {
+
+        private final Folder folder;
+
+        public FolderChildren(Folder folder) {
+            this.folder = folder;
+            folder.getChangedEvent().addListener(changedListener);
+        }
+
+        @Override
+        protected Node[] createNodes(Folder e) {
+            return new Node[]{new CompilationNode(e)};
+        }
+
+        @Override
+        public void addNotify() {
+            List<Folder> result = new ArrayList<>();
+            for (FolderElement o : folder.getElements()) {
+                if (o instanceof Folder) {
+                    result.add((Folder) o);
+                }
+            }
+            this.setKeys(result);
+        }
+        private final ChangedListener changedListener = new ChangedListener() {
+
+            @Override
+            public void changed(Object source) {
+                addNotify();
+            }
+        };
+    }
+
+    @Override
+    public Image getIcon(int i) {
+        if (this.getChildren() == Children.LEAF) {
+            return ImageUtilities.loadImage("com/oracle/graal/visualizer/outline/images/leaf_node.gif");
+        } else {
+            return ImageUtilities.loadImage("com/oracle/graal/visualizer/outline/images/node.gif");
+        }
+    }
+
+    protected CompilationNode(Folder folder) {
+        this(folder, createFolderChildren(folder), new InstanceContent());
+    }
+
+    private static Children createFolderChildren(Folder folder) {
+        for (FolderElement elem : folder.getElements()) {
+            if (elem instanceof Folder) {
+                return new FolderChildren(folder);
+            }
+        }
+        return Children.LEAF;
+    }
+
+    @Override
+    public Action[] getActions(boolean context) {
+        List<Action> actions = new ArrayList<>();
+        actions.add((Action) OpenAction.findObject(OpenAction.class, true));
+        actions.addAll(Lookups.forPath(OutlineTopComponent.NODE_ACTIONS_FOLDER).lookupAll(Action.class));
+        return actions.toArray(new Action[actions.size()]);
+    }
+
+    @Override
+    public Action getPreferredAction() {
+        return (Action) OpenAction.findObject(OpenAction.class, true);
+    }
+
+    @Override
+    public Image getOpenedIcon(int i) {
+        return getIcon(i);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/OutlineTopComponent.form	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+    <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
+  </AuxValues>
+
+  <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+  <SubComponents>
+    <Container class="javax.swing.JScrollPane" name="treeView">
+      <AuxValues>
+        <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new BeanTreeView();"/>
+      </AuxValues>
+      <Constraints>
+        <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+          <BorderConstraints direction="Center"/>
+        </Constraint>
+      </Constraints>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+    </Container>
+  </SubComponents>
+</Form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/OutlineTopComponent.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,123 @@
+/*
+ * 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.visualizer.outline;
+
+import com.oracle.graal.visualizer.outline.server.ServerPanel;
+import com.oracle.graal.visualizer.util.LookupUtils;
+import com.sun.hotspot.igv.data.GraphDocument;
+import java.awt.BorderLayout;
+import javax.swing.Action;
+import org.openide.actions.GarbageCollectAction;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.Toolbar;
+import org.openide.explorer.ExplorerManager;
+import org.openide.explorer.ExplorerUtils;
+import org.openide.explorer.view.BeanTreeView;
+import org.openide.util.NbBundle;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
+
+@TopComponent.Description(preferredID = OutlineTopComponent.PREFERRED_ID, persistenceType = TopComponent.PERSISTENCE_ALWAYS)
+@TopComponent.Registration(mode = "explorer", openAtStartup = true)
+@ActionID(category = "Window", id = "com.oracle.graal.visualizer.outline.OutlineTopComponent")
+@ActionReference(path = "Menu/Window")
+@TopComponent.OpenActionRegistration(displayName = "Outline", preferredID = OutlineTopComponent.PREFERRED_ID)
+public final class OutlineTopComponent extends TopComponent implements ExplorerManager.Provider {
+
+    public static final String GLOBAL_ACTIONS_FOLDER = "Actions/Outline/Global";
+    public static final String NODE_ACTIONS_FOLDER = "Actions/Outline/Nodes";
+    public static OutlineTopComponent instance;
+    public static final String PREFERRED_ID = "OutlineTopComponent";
+    private ExplorerManager manager;
+    private GraphDocument document;
+
+    private OutlineTopComponent() {
+        initComponents();
+
+        setName(NbBundle.getMessage(OutlineTopComponent.class, "CTL_OutlineTopComponent"));
+        setToolTipText(NbBundle.getMessage(OutlineTopComponent.class, "HINT_OutlineTopComponent"));
+
+        document = new GraphDocument();
+        initListView();
+        initToolbar();
+    }
+
+    private void initListView() {
+        manager = new ExplorerManager();
+        manager.setRootContext(new CompilationNode(document));
+        ((BeanTreeView) this.treeView).setRootVisible(false);
+        associateLookup(ExplorerUtils.createLookup(manager, getActionMap()));
+    }
+
+    private void initToolbar() {
+        Toolbar toolbar = new Toolbar();
+        this.add(toolbar, BorderLayout.NORTH);
+        for (Action a : LookupUtils.lookupActions(GLOBAL_ACTIONS_FOLDER, getLookup())) {
+            toolbar.add(a);
+        }
+        toolbar.add(GarbageCollectAction.get(GarbageCollectAction.class).getToolbarPresenter());
+        toolbar.add(new ServerPanel(getDocument()));
+    }
+
+    @Override
+    public ExplorerManager getExplorerManager() {
+        return manager;
+    }
+
+    public GraphDocument getDocument() {
+        return document;
+    }
+
+    public static OutlineTopComponent findInstance() {
+        return (OutlineTopComponent) WindowManager.getDefault().findTopComponent(PREFERRED_ID);
+    }
+
+    @Override
+    public int getPersistenceType() {
+        return TopComponent.PERSISTENCE_NEVER;
+    }
+
+    @Override
+    protected String preferredID() {
+        return PREFERRED_ID;
+    }
+
+    /**
+     * This method is called from within the constructor to initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is always
+     * regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        treeView = new BeanTreeView();
+
+        setLayout(new java.awt.BorderLayout());
+        add(treeView, java.awt.BorderLayout.CENTER);
+    }// </editor-fold>//GEN-END:initComponents
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JScrollPane treeView;
+    // End of variables declaration//GEN-END:variables
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/actions/ImportAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,155 @@
+/*
+ * 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.visualizer.outline.actions;
+
+import com.oracle.graal.visualizer.outline.OutlineTopComponent;
+import com.sun.hotspot.igv.data.GraphDocument;
+import com.sun.hotspot.igv.data.serialization.Parser;
+import com.sun.hotspot.igv.data.serialization.XMLParser;
+import com.sun.hotspot.igv.settings.Settings;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import javax.swing.JFileChooser;
+import javax.swing.SwingUtilities;
+import javax.swing.filechooser.FileFilter;
+import org.netbeans.api.progress.ProgressHandle;
+import org.netbeans.api.progress.ProgressHandleFactory;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+import org.openide.util.RequestProcessor;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+@ActionID(id = "com.oracle.graal.visualizer.outline.actions.ImportAction", category = "File")
+@ActionRegistration(displayName = "Import", iconBase="com/oracle/graal/visualizer/outline/images/import.png")
+@ActionReferences(value = {
+    @ActionReference(path = "Menu/File", position = 100),
+    @ActionReference(path = OutlineTopComponent.GLOBAL_ACTIONS_FOLDER)})
+public final class ImportAction implements ActionListener {
+
+    public static FileFilter getFileFilter() {
+        return new FileFilter() {
+
+            @Override
+            public boolean accept(File f) {
+                return f.getName().toLowerCase().endsWith(".xml") || f.isDirectory();
+            }
+
+            @Override
+            public String getDescription() {
+                return "XML files (*.xml)";
+            }
+        };
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+
+        JFileChooser fc = new JFileChooser();
+        fc.setFileFilter(ImportAction.getFileFilter());
+        fc.setCurrentDirectory(new File(Settings.get().get(Settings.DIRECTORY, Settings.DIRECTORY_DEFAULT)));
+
+        if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
+            File file = fc.getSelectedFile();
+
+            File dir = file;
+            if (!dir.isDirectory()) {
+                dir = dir.getParentFile();
+            }
+
+            Settings.get().put(Settings.DIRECTORY, dir.getAbsolutePath());
+
+            try {
+                final FileInputStream inputStream = new FileInputStream(file);
+                final InputSource is = new InputSource(inputStream);
+
+                final ProgressHandle handle = ProgressHandleFactory.createHandle("Opening file " + file.getName());
+                final int basis = 1000;
+                handle.start(basis);
+                final int start = inputStream.available();
+
+                final XMLParser.ParseMonitor parseMonitor = new XMLParser.ParseMonitor() {
+
+                    @Override
+                    public void setProgress(double d) {
+                        try {
+                            int curAvailable = inputStream.available();
+                            int prog = (int) (basis * (double) (start - curAvailable) / (double) start);
+                            handle.progress(prog);
+                        } catch (IOException ex) {
+                        }
+                    }
+
+                    @Override
+                    public void setState(String state) {
+                        setProgress(0.0);
+                        handle.progress(state);
+                    }
+                };
+                final Parser parser = new Parser();
+                final OutlineTopComponent component = OutlineTopComponent.findInstance();
+
+                component.requestActive();
+
+                RequestProcessor.getDefault().post(new Runnable() {
+
+                    @Override
+                    public void run() {
+                        try {
+                            final GraphDocument document = parser.parse(is, parseMonitor);
+                            parseMonitor.setState("Finishing");
+                            SwingUtilities.invokeLater(new Runnable(){
+
+                                @Override
+                                public void run() {
+                                    component.getDocument().addGraphDocument(document);
+                                }
+                            });
+                        } catch (SAXException ex) {
+                            String s = "Exception during parsing the XML file, could not load document!";
+                            if (ex instanceof XMLParser.MissingAttributeException) {
+                                XMLParser.MissingAttributeException e = (XMLParser.MissingAttributeException) ex;
+                                s += "\nMissing attribute \"" + e.getAttributeName() + "\"";
+                            }
+                            NotifyDescriptor d = new NotifyDescriptor.Message(s, NotifyDescriptor.ERROR_MESSAGE);
+                            DialogDisplayer.getDefault().notify(d);
+                        }
+                        handle.finish();
+                    }
+                });
+
+            } catch (IOException ex) {
+                DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error reading file!", NotifyDescriptor.ERROR_MESSAGE));
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/actions/RemoveAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * 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.visualizer.outline.actions;
+
+import com.oracle.graal.visualizer.outline.OutlineTopComponent;
+import com.sun.hotspot.igv.data.FolderElement;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+
+@ActionID(id = "com.oracle.graal.visualizer.outline.actions.RemoveAction", category = "Edit")
+@ActionRegistration(displayName = "Remove", iconBase = "com/oracle/graal/visualizer/outline/images/remove.png")
+@ActionReferences(value = {
+    @ActionReference(path = "Menu/File", position = 400),
+    @ActionReference(path = OutlineTopComponent.NODE_ACTIONS_FOLDER)})
+public final class RemoveAction implements ActionListener {
+
+    List<FolderElement> elements;
+
+    public RemoveAction(List<FolderElement> elements) {
+        this.elements = elements;
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        for (FolderElement element : elements) {
+            element.getParent().removeElement(element);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/actions/RemoveAllAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.visualizer.outline.actions;
+
+import com.oracle.graal.visualizer.outline.OutlineTopComponent;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+
+@ActionID(id = "com.oracle.graal.visualizer.outline.actions.RemoveAllAction", category = "Edit")
+@ActionRegistration(displayName = "Remove all", iconBase = "com/oracle/graal/visualizer/outline/images/removeall.png")
+@ActionReferences(value = {
+    @ActionReference(path = "Menu/File", position = 500),
+    @ActionReference(path = OutlineTopComponent.GLOBAL_ACTIONS_FOLDER)})
+public final class RemoveAllAction implements ActionListener {
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        OutlineTopComponent.findInstance().getDocument().clear();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/actions/SaveAllAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.visualizer.outline.actions;
+
+import com.oracle.graal.visualizer.outline.OutlineTopComponent;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+
+@ActionID(id = "com.oracle.graal.visualizer.outline.actions.SaveAllAction", category = "File")
+@ActionRegistration(displayName = "Save all..", iconBase = "com/oracle/graal/visualizer/outline/images/saveall.gif")
+@ActionReferences(value = {
+    @ActionReference(path = "Menu/File", position = 300),
+    @ActionReference(path = OutlineTopComponent.GLOBAL_ACTIONS_FOLDER)})
+public final class SaveAllAction implements ActionListener {
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        final OutlineTopComponent component = OutlineTopComponent.findInstance();
+        SaveAsAction.save(component.getDocument());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/actions/SaveAsAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,105 @@
+/*
+ * 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.visualizer.outline.actions;
+
+import com.oracle.graal.visualizer.outline.OutlineTopComponent;
+import com.sun.hotspot.igv.data.Folder;
+import com.sun.hotspot.igv.data.FolderElement;
+import com.sun.hotspot.igv.data.GraphDocument;
+import com.sun.hotspot.igv.data.serialization.Printer;
+import com.sun.hotspot.igv.settings.Settings;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.*;
+import java.util.List;
+import javax.swing.JFileChooser;
+import javax.swing.JOptionPane;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+
+@ActionID(id = "com.oracle.graal.visualizer.outline.actions.SaveAsAction", category = "File")
+@ActionRegistration(displayName = "Save as...", iconBase="com/oracle/graal/visualizer/outline/images/save.png")
+@ActionReferences(value = {
+    @ActionReference(path = "Menu/File", position = 200),
+    @ActionReference(path = OutlineTopComponent.NODE_ACTIONS_FOLDER)})
+public final class SaveAsAction implements ActionListener {
+
+    private final List<FolderElement> elements;
+    
+    public SaveAsAction(List<FolderElement> elements) {
+        this.elements = elements;
+    }
+
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        GraphDocument doc = new GraphDocument();
+        outer: for (FolderElement element : elements) {
+            Folder cur = element.getParent();
+            while (cur instanceof FolderElement) {
+                FolderElement curElement = (FolderElement) cur;
+                if (elements.contains(curElement)) {
+                    continue outer;
+                }
+                cur = curElement.getParent();
+            }
+            
+            Folder previousParent = element.getParent();
+            doc.addElement(element);
+            element.setParent(previousParent);
+        }
+
+        save(doc);
+    }
+
+    public static void save(GraphDocument doc) {
+        JFileChooser fc = new JFileChooser();
+        fc.setFileFilter(ImportAction.getFileFilter());
+        fc.setCurrentDirectory(new File(Settings.get().get(Settings.DIRECTORY, Settings.DIRECTORY_DEFAULT)));
+
+        if (fc.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
+            File file = fc.getSelectedFile();
+            if (!file.getName().contains(".")) {
+                file = new File(file.getAbsolutePath() + ".xml");
+            }
+
+            File dir = file;
+            if (!dir.isDirectory()) {
+                dir = dir.getParentFile();
+            }
+            Settings.get().put(Settings.DIRECTORY, dir.getAbsolutePath());
+            try {
+                try (Writer writer = new OutputStreamWriter(new FileOutputStream(file))) {
+                    Printer p = new Printer();
+                    p.export(writer, doc);
+                }
+            } catch (IOException e) {
+                JOptionPane.showMessageDialog(null, "Error writing file " + file.getAbsolutePath());
+            }
+        }
+    }
+}
Binary file visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/images/import.png has changed
Binary file visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/images/leaf_node.gif has changed
Binary file visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/images/node.gif has changed
Binary file visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/images/remove.png has changed
Binary file visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/images/removeall.png has changed
Binary file visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/images/save.png has changed
Binary file visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/images/saveall.gif has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/layer.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
+<filesystem>
+    <folder name="Actions"/>
+    
+    <folder name="Menu">
+        <folder name="File">
+            <file name="Separator2.instance_hidden"/>
+            <file name="Separator3.instance_hidden"/>
+            <file name="SeparatorOpen.instance_hidden"/>
+            <file name="SeparatorSave.instance">
+                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
+                <attr name="position" intvalue="150"/>
+            </file>
+            <file name="SeparatorRemove.instance">
+                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
+                <attr name="position" intvalue="350"/>
+            </file>
+            
+            <!-- Hidden menu entries from other modules -->
+            <file name="org-netbeans-modules-editor-ExportHtmlAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-openfile-OpenFileAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-openfile-RecentFileAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-print-action-PageSetupAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-print-action-PrintAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-CloseProject.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-CustomizeProject.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-NewFile.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-NewProject.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-OpenProject.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-RecentProjects.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-groups-GroupsMenu.shadow_hidden"/>
+            <file name="org-openide-actions-SaveAction.shadow_hidden"/>
+            <file name="org-openide-actions-SaveAllAction.shadow_hidden"/>
+            <file name="org-openide-actions-SaveAsAction.shadow_hidden"/>
+        </folder>
+        
+        <folder name="Edit">
+            <!-- Hidden menu entries from other modules -->
+            <file name="Separator1.instance_hidden"/>
+            <file name="Separator2.instance_hidden"/>
+            <file name="SeparatorAfterFindPrevious.instance_hidden"/>
+            <file name="SeparatorAfterProjectsSearch.instance_hidden"/>
+            <file name="WhereUsedAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$FindNextAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$FindPreviousAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$FindSelectionAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$PasteFormattedAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$SelectAllAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$SelectIdentifierAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$StartMacroRecordingAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$StopMacroRecordingAction.instance_hidden"/>
+            <file name="org-netbeans-modules-search-FindInFilesAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-search-ReplaceInFilesAction.shadow_hidden"/>
+            <file name="org-openide-actions-CopyAction.shadow_hidden"/>
+            <file name="org-openide-actions-CutAction.shadow_hidden"/>
+            <file name="org-openide-actions-DeleteAction.shadow_hidden"/>
+            <file name="org-openide-actions-FindAction.shadow_hidden"/>
+            <file name="org-openide-actions-PasteAction.shadow_hidden"/>
+            <file name="org-openide-actions-ReplaceAction.shadow_hidden"/>
+            <file name="sep-before-reposearch.instance_hidden"/>
+        </folder>
+        
+        <folder name="View">
+            <!-- Hidden menu entries from other modules -->
+            <file name="Separator1.instance_hidden"/>
+            <file name="Separator2.instance_hidden"/>
+            <file name="org-netbeans-core-actions-HTMLViewAction.shadow_hidden"/>
+            <file name="org-netbeans-core-actions-LogAction.shadow_hidden"/>
+            <file name="org-netbeans-core-multiview-EditorsAction.instance_hidden"/>
+            <file name="org-netbeans-core-windows-actions-ToolbarsListAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-NbCodeFoldingAction.instance_hidden"/>
+            <file name="org-netbeans-modules-project-ui-SyncEditorWithViewsAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-versioning-ShowTextAnnotationsAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-versioning-diff-ShowDiffSidebarAction.shadow_hidden"/>
+            <file name="toggle-line-numbers.shadow_hidden"/>
+            <file name="toggle-non-printable-characters.shadow_hidden"/>
+            <file name="toggle-toolbar.shadow_hidden"/>
+        </folder>
+        
+        <!-- Hidden menus -->
+        <folder name="GoTo_hidden"/>
+        <folder name="Source_hidden"/>
+        <folder name="Refactoring_hidden"/>
+        <folder name="BuildProject_hidden"/>
+        <folder name="RunProject_hidden"/>
+        <folder name="Versioning_hidden"/>
+        
+        <folder name="Tools">
+            <!-- Hidden menu entries from other modules -->
+            <file name="LibrariesCustomizerAction.shadow_hidden"/>
+            <file name="PaletteManager_hidden"/>
+            <file name="Separator1.instance_hidden"/>
+            <file name="Separator2.instance_hidden"/>
+            <file name="ServerManagerAction3.shadow_hidden"/>
+            <file name="VariablesCustomizerAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-autoupdate-ui-actions-PluginManagerAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-favorites-templates-TemplatesAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-options-OptionsWindowAction-separatorBefore.instance_hidden"/>
+            <file name="org-netbeans-modules-xml-catalog-CatalogAction.shadow_hidden"/>
+            <file name="org-openide-actions-ToolsAction.shadow_hidden"/>
+        </folder>
+        
+        <folder name="Window">
+            
+            <!-- Hidden menu entries from other modules -->
+            <file name="Debug_hidden"/>
+            <file name="Navigator_hidden"/>
+            <file name="Other_hidden"/>
+            <file name="Output_hidden"/>
+            <file name="ProgressListAction.shadow_hidden"/>
+            <file name="ShowPaletteAction.shadow_hidden"/>
+            <file name="SwitchToRecentDocumentAction.shadow_hidden"/>
+            <file name="Versioning_hidden"/>
+            <file name="org-netbeans-core-ide-ServicesTabAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-favorites-View.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-logical-tab-action.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-physical-tab-action.shadow_hidden"/>
+            <file name="org-netbeans-modules-tasklist-ui-TaskListAction.shadow_hidden"/>
+            <file name="CloneDocumentAction.shadow_hidden"/>
+        </folder>
+
+        <folder name="Help">
+            <!-- Hidden menu entries from other modules -->
+            <file name="Separator1.instance_hidden"/>
+            <file name="netbeans-kb.url_hidden"/>
+            <file name="org-netbeans-modules-autoupdate-ui-actions-CheckForUpdatesAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-bugzilla-ReportNBIssueAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-usersguide-master.xml_hidden"/>
+            <file name="shortcuts.xml_hidden"/>
+        </folder>
+    </folder>
+
+    <folder name="OptionsDialog">
+        <!-- Hidden option tabs from other modules -->
+        <file name="Editor.instance_hidden"/>
+        <file name="FontsAndColors.instance_hidden"/>
+        <file name="General.instance_hidden"/>
+        <file name="Keymaps.instance_hidden"/>
+        <folder name="Advanced">
+            <file name="Files.instance_hidden"/>
+            <file name="IssueTracking.instance_hidden"/>
+            <file name="JavaScript.instance_hidden"/>
+            <file name="Spellchecker.instance_hidden"/>
+            <file name="TermAdvancedOption.instance_hidden"/>
+            <file name="ToDo.instance_hidden"/>
+            <file name="Versioning.instance_hidden"/>
+        </folder>
+    </folder>
+    
+    <folder name="Toolbars">
+        <file name="Build_hidden"/>
+        <file name="Clipboard_hidden"/>
+        <file name="Debug_hidden"/>
+        <file name="Debugging.xml_hidden"/>
+        <file name="File_hidden"/>
+        <file name="Memory_hidden"/>
+        <file name="Standard.xml_hidden"/>
+        <file name="UndoRedo_hidden"/>
+    </folder>
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/server/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=NetworkConnection
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/server/Client.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.visualizer.outline.server;
+
+import com.sun.hotspot.igv.data.serialization.Parser;
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Socket;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+public class Client implements Runnable {
+
+    private Socket socket;
+    private ServerCallback callback;
+
+    public Client(Socket socket, ServerCallback callback) {
+        this.callback = callback;
+        this.socket = socket;
+    }
+
+    @Override
+    public void run() {
+        callback.connectionOpened(socket.getInetAddress());
+        try {
+            InputStream inputStream = new BufferedInputStream(socket.getInputStream());
+            InputSource is = new InputSource(inputStream);
+
+            try {
+                Parser parser = new Parser(callback);
+                parser.parse(is, null);
+            } catch (SAXException ex) {
+                throw new IOException(ex);
+            }
+        } catch (IOException ex) {
+        } finally {
+            try {
+                socket.close();
+            } catch (IOException ex) {
+            }
+            callback.connectionClosed();
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/server/Server.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,89 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.visualizer.outline.server;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.util.RequestProcessor;
+
+public class Server {
+
+    private Runnable serverRunnable;
+    private ServerSocket serverSocket;
+    
+    private Server() {}
+    
+
+    public static Server start(final ServerCallback callback, int port) {
+
+        final Server server = new Server();
+        
+        try {
+            server.serverSocket = new java.net.ServerSocket(port);
+        } catch (IOException ex) {
+            NotifyDescriptor message = new NotifyDescriptor.Message("Could not create server. Listening for incoming data is disabled.", NotifyDescriptor.ERROR_MESSAGE);
+            DialogDisplayer.getDefault().notifyLater(message);
+            return null;
+        }
+
+        Runnable runnable = new Runnable() {
+
+            @Override
+            public void run() {
+                while (true) {
+                    try {
+                        Socket clientSocket = server.serverSocket.accept();
+                        if (server.serverRunnable != this) {
+                            clientSocket.close();
+                            return;
+                        }
+                        RequestProcessor.getDefault().post(new Client(clientSocket, callback), 0, Thread.MAX_PRIORITY);
+                    } catch (IOException ex) {
+                        server.serverSocket = null;
+                        NotifyDescriptor message = new NotifyDescriptor.Message("Error during listening for incoming connections. Listening for incoming data is disabled.", NotifyDescriptor.ERROR_MESSAGE);
+                        DialogDisplayer.getDefault().notifyLater(message);
+                        return;
+                    }
+                }
+            }
+        };
+
+        server.serverRunnable = runnable;
+        RequestProcessor.getDefault().post(runnable, 0, Thread.MAX_PRIORITY);
+        return server;
+    }
+
+    void shutdown() {
+        try {
+            serverSocket.close();
+        } catch (IOException ex) {
+        }
+        
+        serverSocket = null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/server/ServerCallback.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,37 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.visualizer.outline.server;
+
+import com.sun.hotspot.igv.data.services.GroupCallback;
+import java.net.InetAddress;
+
+public interface ServerCallback extends GroupCallback {
+    
+    public void connectionOpened(InetAddress inetAddress);
+
+    public void connectionClosed();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/OutlineView/src/com/oracle/graal/visualizer/outline/server/ServerPanel.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,130 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.visualizer.outline.server;
+
+import com.sun.hotspot.igv.data.GraphDocument;
+import com.sun.hotspot.igv.data.Group;
+import com.sun.hotspot.igv.settings.Settings;
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Font;
+import java.net.InetAddress;
+import java.util.prefs.PreferenceChangeEvent;
+import java.util.prefs.PreferenceChangeListener;
+import javax.swing.BorderFactory;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+public class ServerPanel extends JPanel {
+
+    private final static int BORDER_SIZE = 2;
+    JLabel label;
+    private Server server;
+    private int port = -1;
+    private int numberOfConnections;
+    private final GraphDocument document;
+    private final PreferenceChangeListener preferenceChanged = new PreferenceChangeListener() {
+
+        @Override
+        public void preferenceChange(PreferenceChangeEvent evt) {
+            updateServer();
+        }
+    };
+    private ServerCallback callback = new ServerCallback() {
+
+        @Override
+        public void connectionOpened(InetAddress inetAddress) {
+            SwingUtilities.invokeLater(new Runnable() {
+
+                @Override
+                public void run() {
+                    numberOfConnections++;
+                    updateLabel();
+                }
+            });
+        }
+
+        @Override
+        public void connectionClosed() {
+            SwingUtilities.invokeLater(new Runnable() {
+
+                @Override
+                public void run() {
+                    numberOfConnections--;
+                    updateLabel();
+                }
+            });
+        }
+
+        @Override
+        public void started(Group g) {
+            document.addElement(g);
+        }
+    };
+
+    private void updateLabel() {
+        if (numberOfConnections == 0) {
+            label.setText(String.format("Listening on %d", port));
+            label.setFont(label.getFont().deriveFont(Font.PLAIN));
+        } else {
+            label.setText(String.format("%d connections", numberOfConnections));
+            label.setFont(label.getFont().deriveFont(Font.BOLD));
+        }
+    }
+
+    private void updateServer() {
+        int curPort = Integer.parseInt(Settings.get().get(Settings.PORT, Settings.PORT_DEFAULT));
+        if (curPort != port) {
+            port = curPort;
+            if (server != null) {
+                server.shutdown();
+            }
+            server = Server.start(callback, port);
+            SwingUtilities.invokeLater(new Runnable() {
+
+                @Override
+                public void run() {
+                    updateLabel();
+                }
+            });
+        }
+    }
+
+    public ServerPanel(GraphDocument document) {
+
+        this.document = document;
+        Settings.get().addPreferenceChangeListener(preferenceChanged);
+        label = new JLabel();
+        label.setBorder(BorderFactory.createEmptyBorder(0, BORDER_SIZE, 0, BORDER_SIZE));
+        this.setLayout(new BorderLayout());
+        this.add(label, BorderLayout.WEST);
+        updateServer();
+    }
+
+    public Component getToolbarPresenter() {
+        return label;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SelectionCoordinator/src/com/sun/hotspot/igv/selectioncoordinator/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=SelectionCoordinator
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SelectionCoordinator/src/com/sun/hotspot/igv/selectioncoordinator/SelectionCoordinator.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,138 @@
+/*
+ * 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.sun.hotspot.igv.selectioncoordinator;
+
+import com.sun.hotspot.igv.data.ChangedEvent;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas
+ */
+public class SelectionCoordinator {
+
+    private static SelectionCoordinator singleInstance = new SelectionCoordinator();
+    private Set<Object> selectedObjects;
+    private Set<Object> highlightedObjects;
+    private ChangedEvent<SelectionCoordinator> selectedChangedEvent;
+    private ChangedEvent<SelectionCoordinator> highlightedChangedEvent;
+
+    public static SelectionCoordinator getInstance() {
+        return singleInstance;
+    }
+
+    private SelectionCoordinator() {
+        selectedChangedEvent = new ChangedEvent<>(this);
+        highlightedChangedEvent = new ChangedEvent<>(this);
+        selectedObjects = new HashSet<>();
+        highlightedObjects = new HashSet<>();
+    }
+
+    public Set<Object> getSelectedObjects() {
+        return Collections.unmodifiableSet(selectedObjects);
+    }
+
+    public Set<Object> getHighlightedObjects() {
+        return Collections.unmodifiableSet(highlightedObjects);
+    }
+
+    public ChangedEvent<SelectionCoordinator> getHighlightedChangedEvent() {
+        return highlightedChangedEvent;
+    }
+
+    public ChangedEvent<SelectionCoordinator> getSelectedChangedEvent() {
+        return selectedChangedEvent;
+    }
+
+    public void addHighlighted(Object o) {
+        if (!highlightedObjects.contains(o)) {
+            highlightedObjects.add(o);
+            highlightedObjectsChanged();
+        }
+    }
+
+    public void removeHighlighted(Object o) {
+        if (highlightedObjects.contains(o)) {
+            highlightedObjects.remove(o);
+            highlightedObjectsChanged();
+        }
+    }
+
+    public void addAllHighlighted(Set<? extends Object> s) {
+        int oldSize = highlightedObjects.size();
+        highlightedObjects.addAll(s);
+        if (oldSize != highlightedObjects.size()) {
+            highlightedObjectsChanged();
+        }
+    }
+
+    public void removeAllHighlighted(Set<? extends Object> s) {
+        int oldSize = highlightedObjects.size();
+        highlightedObjects.removeAll(s);
+        if (oldSize != highlightedObjects.size()) {
+            highlightedObjectsChanged();
+        }
+    }
+
+    private void highlightedObjectsChanged() {
+        highlightedChangedEvent.fire();
+    }
+
+    public void addAllSelected(Set<? extends Object> s) {
+        int oldSize = selectedObjects.size();
+        selectedObjects.addAll(s);
+        if (oldSize != selectedObjects.size()) {
+            selectedObjectsChanged();
+        }
+    }
+
+    public void removeAllSelected(Set<? extends Object> s) {
+        int oldSize = selectedObjects.size();
+        selectedObjects.removeAll(s);
+        if (oldSize != selectedObjects.size()) {
+            selectedObjectsChanged();
+        }
+    }
+
+    public void setSelectedObjects(Set<? extends Object> s) {
+        assert s != null;
+        selectedObjects.clear();
+        selectedObjects.addAll(s);
+        selectedObjectsChanged();
+    }
+
+    private void selectedObjectsChanged() {
+        selectedChangedEvent.fire();
+    }
+
+    public void setHighlightedObjects(Set<? extends Object> s) {
+        assert s != null;
+        this.highlightedObjects.clear();
+        this.highlightedObjects.addAll(s);
+        highlightedObjectsChanged();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Settings/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.settings" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.settings.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Settings/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.settings
+OpenIDE-Module-Layer: com/sun/hotspot/igv/settings/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/settings/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Settings/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.settings-impl" basedir="..">
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+        <condition>
+            <not>
+                <available file="${harness.dir}" type="dir"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Settings/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=8869440a
+build.xml.script.CRC32=7ef09117
+build.xml.stylesheet.CRC32=79c3b980
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=8869440a
+nbproject/build-impl.xml.script.CRC32=1a0e7f21
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Settings/nbproject/platform.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.javahelp,\
+    org.netbeans.modules.masterfs,\
+    org.netbeans.modules.options.keymap,\
+    org.netbeans.modules.sendopts,\
+    org.netbeans.modules.templates,\
+    org.openide.compat,\
+    org.openide.execution,\
+    org.openide.util.enumerations
+enabled.clusters=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Settings/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Settings/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.settings</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>org.jdesktop.layout</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.16.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.options.api</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.21.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.30.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.sun.hotspot.igv.settings</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Settings/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Settings/src/com/sun/hotspot/igv/settings/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,5 @@
+AdvancedOption_DisplayName_Settings=Settings
+AdvancedOption_Tooltip_Settings=Application Settings
+OpenIDE-Module-Name=Settings
+OptionsCategory_Name_View=General
+OptionsCategory_Title_View=View Settings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Settings/src/com/sun/hotspot/igv/settings/Settings.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1998, 2007, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.settings;
+
+import java.util.prefs.Preferences;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Settings {
+
+    public final static String NODE_TEXT = "nodeText";
+    public final static String NODE_TEXT_DEFAULT = "[idx] [name]";
+    public final static String NODE_WIDTH = "nodeWidth";
+    public final static String NODE_WIDTH_DEFAULT = "100";
+    public final static String PORT = "port";
+    public final static String PORT_DEFAULT = "4444";
+    public final static String DIRECTORY = "directory";
+    public final static String DIRECTORY_DEFAULT = System.getProperty("user.dir");
+
+    public static Preferences get() {
+        return Preferences.userNodeForPackage(Settings.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Settings/src/com/sun/hotspot/igv/settings/ViewOptionsCategory.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.settings;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import org.netbeans.spi.options.OptionsCategory;
+import org.netbeans.spi.options.OptionsPanelController;
+import org.openide.util.ImageUtilities;
+import org.openide.util.NbBundle;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class ViewOptionsCategory extends OptionsCategory {
+
+    @Override
+    public Icon getIcon() {
+        return new ImageIcon(ImageUtilities.loadImage("com/sun/hotspot/igv/settings/settings.png"));
+    }
+
+    @Override
+    public String getCategoryName() {
+        return NbBundle.getMessage(ViewOptionsCategory.class, "OptionsCategory_Name_View");
+    }
+
+    @Override
+    public String getTitle() {
+        return NbBundle.getMessage(ViewOptionsCategory.class, "OptionsCategory_Title_View");
+    }
+
+    @Override
+    public OptionsPanelController create() {
+        return new ViewOptionsPanelController();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Settings/src/com/sun/hotspot/igv/settings/ViewOptionsPanelController.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.settings;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import javax.swing.JComponent;
+import org.netbeans.spi.options.OptionsPanelController;
+import org.openide.util.HelpCtx;
+import org.openide.util.Lookup;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+final class ViewOptionsPanelController extends OptionsPanelController {
+
+    private ViewPanel panel;
+    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
+    private boolean changed;
+
+    @Override
+    public void update() {
+        getPanel().load();
+        changed = false;
+    }
+
+    @Override
+    public void applyChanges() {
+        getPanel().store();
+        changed = false;
+    }
+
+    @Override
+    public void cancel() {
+    // need not do anything special, if no changes have been persisted yet
+    }
+
+    @Override
+    public boolean isValid() {
+        return getPanel().valid();
+    }
+
+    @Override
+    public boolean isChanged() {
+        return changed;
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return null; // new HelpCtx("...ID") if you have a help set
+    }
+
+    @Override
+    public JComponent getComponent(Lookup masterLookup) {
+        return getPanel();
+    }
+
+    @Override
+    public void addPropertyChangeListener(PropertyChangeListener l) {
+        pcs.addPropertyChangeListener(l);
+    }
+
+    @Override
+    public void removePropertyChangeListener(PropertyChangeListener l) {
+        pcs.removePropertyChangeListener(l);
+    }
+
+    private ViewPanel getPanel() {
+        if (panel == null) {
+            panel = new ViewPanel(this);
+        }
+        return panel;
+    }
+
+    void changed() {
+        if (!changed) {
+            changed = true;
+            pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true);
+        }
+        pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Settings/src/com/sun/hotspot/igv/settings/ViewPanel.form	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.3" maxVersion="1.3" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="jPanel1" max="32767" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="jPanel1" min="-2" max="-2" attributes="0"/>
+              <EmptySpace pref="206" max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JPanel" name="jPanel1">
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="1" attributes="0">
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
+                      <Component id="jLabel3" alignment="0" min="-2" max="-2" attributes="0"/>
+                      <Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace min="-2" pref="39" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Component id="portSpinner" alignment="0" min="-2" pref="63" max="-2" attributes="0"/>
+                      <Component id="nodeWidthSpinner" alignment="0" min="-2" pref="63" max="-2" attributes="0"/>
+                      <Component id="jScrollPane1" alignment="0" min="-2" pref="365" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace max="-2" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="0" attributes="0">
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Group type="102" alignment="0" attributes="0">
+                          <Component id="jScrollPane1" min="-2" max="-2" attributes="0"/>
+                          <EmptySpace type="separate" max="-2" attributes="0"/>
+                          <Group type="103" groupAlignment="3" attributes="0">
+                              <Component id="nodeWidthSpinner" alignment="3" min="-2" max="-2" attributes="0"/>
+                              <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
+                          </Group>
+                          <EmptySpace type="separate" max="-2" attributes="0"/>
+                          <Group type="103" groupAlignment="3" attributes="0">
+                              <Component id="portSpinner" alignment="3" min="-2" max="-2" attributes="0"/>
+                              <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/>
+                          </Group>
+                      </Group>
+                      <Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace min="-2" pref="73" max="-2" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Component class="javax.swing.JLabel" name="jLabel1">
+          <Properties>
+            <Property name="text" type="java.lang.String" value="Node Text"/>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="jLabel2">
+          <Properties>
+            <Property name="text" type="java.lang.String" value="Node Width"/>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JSpinner" name="portSpinner">
+        </Component>
+        <Container class="javax.swing.JScrollPane" name="jScrollPane1">
+          <AuxValues>
+            <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+          </AuxValues>
+
+          <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+          <SubComponents>
+            <Component class="javax.swing.JTextArea" name="nodeTextArea">
+              <Properties>
+                <Property name="columns" type="int" value="20"/>
+                <Property name="rows" type="int" value="5"/>
+              </Properties>
+            </Component>
+          </SubComponents>
+        </Container>
+        <Component class="javax.swing.JSpinner" name="nodeWidthSpinner">
+        </Component>
+        <Component class="javax.swing.JLabel" name="jLabel3">
+          <Properties>
+            <Property name="text" type="java.lang.String" value="Network Port"/>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+  </SubComponents>
+</Form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Settings/src/com/sun/hotspot/igv/settings/ViewPanel.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.settings;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+final class ViewPanel extends javax.swing.JPanel {
+
+    private final ViewOptionsPanelController controller;
+
+    ViewPanel(ViewOptionsPanelController controller) {
+        this.controller = controller;
+        initComponents();
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        jPanel1 = new javax.swing.JPanel();
+        jLabel1 = new javax.swing.JLabel();
+        jLabel2 = new javax.swing.JLabel();
+        portSpinner = new javax.swing.JSpinner();
+        jScrollPane1 = new javax.swing.JScrollPane();
+        nodeTextArea = new javax.swing.JTextArea();
+        nodeWidthSpinner = new javax.swing.JSpinner();
+        jLabel3 = new javax.swing.JLabel();
+
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, "Node Text");
+
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel2, "Node Width");
+
+        nodeTextArea.setColumns(20);
+        nodeTextArea.setRows(5);
+        jScrollPane1.setViewportView(nodeTextArea);
+
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel3, "Network Port");
+
+        org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
+        jPanel1.setLayout(jPanel1Layout);
+        jPanel1Layout.setHorizontalGroup(
+            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+            .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
+                .addContainerGap()
+                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                    .add(jLabel1)
+                    .add(jLabel3)
+                    .add(jLabel2))
+                .add(39, 39, 39)
+                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                    .add(portSpinner, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 63, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
+                    .add(nodeWidthSpinner, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 63, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
+                    .add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 365, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
+                .addContainerGap())
+        );
+        jPanel1Layout.setVerticalGroup(
+            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+            .add(jPanel1Layout.createSequentialGroup()
+                .addContainerGap()
+                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                    .add(jPanel1Layout.createSequentialGroup()
+                        .add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
+                        .add(18, 18, 18)
+                        .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
+                            .add(nodeWidthSpinner, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
+                            .add(jLabel2))
+                        .add(18, 18, 18)
+                        .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
+                            .add(portSpinner, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
+                            .add(jLabel3)))
+                    .add(jLabel1))
+                .add(73, 73, 73))
+        );
+
+        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+            .add(layout.createSequentialGroup()
+                .addContainerGap()
+                .add(jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                .addContainerGap())
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+            .add(layout.createSequentialGroup()
+                .addContainerGap()
+                .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 232, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
+                .addContainerGap(206, Short.MAX_VALUE))
+        );
+    }// </editor-fold>//GEN-END:initComponents
+    void load() {
+        nodeTextArea.setText(Settings.get().get(Settings.NODE_TEXT, Settings.NODE_TEXT_DEFAULT));
+        nodeWidthSpinner.setValue(Integer.parseInt(Settings.get().get(Settings.NODE_WIDTH, Settings.NODE_WIDTH_DEFAULT)));
+        portSpinner.setValue(Integer.parseInt(Settings.get().get(Settings.PORT, Settings.PORT_DEFAULT)));
+    }
+
+    void store() {
+        Settings.get().put(Settings.NODE_TEXT, nodeTextArea.getText());
+        Settings.get().put(Settings.NODE_WIDTH, nodeWidthSpinner.getValue().toString());
+        Settings.get().put(Settings.PORT, portSpinner.getValue().toString());
+    }
+
+    boolean valid() {
+        return true;
+    }
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JLabel jLabel1;
+    private javax.swing.JLabel jLabel2;
+    private javax.swing.JLabel jLabel3;
+    private javax.swing.JPanel jPanel1;
+    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JTextArea nodeTextArea;
+    private javax.swing.JSpinner nodeWidthSpinner;
+    private javax.swing.JSpinner portSpinner;
+    // End of variables declaration//GEN-END:variables
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Settings/src/com/sun/hotspot/igv/settings/layer.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
+<filesystem>
+    <folder name="OptionsDialog">
+      <!-- <file name="Advanced.instance_hidden"/>
+        <file name="General.instance_hidden"/>-->
+        <file name="com-sun-hotspot-igv-settings-ViewOptionsCategory.instance">
+            <attr name="position" intvalue="100" />
+        </file>
+    </folder>
+</filesystem>
Binary file visualizer/Settings/src/com/sun/hotspot/igv/settings/settings.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SharedActions/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.oracle.graal.visualizer.sharedactions" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.oracle.graal.visualizer.sharedactions.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SharedActions/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.oracle.graal.visualizer.sharedactions
+OpenIDE-Module-Localizing-Bundle: com/oracle/graal/visualizer/sharedactions/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SharedActions/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.oracle.graal.visualizer.sharedactions-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SharedActions/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=c3bdef4e
+build.xml.script.CRC32=da3659b1
+build.xml.stylesheet.CRC32=a56c6a5b@2.47.1
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=c3bdef4e
+nbproject/build-impl.xml.script.CRC32=567ad23a
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.47.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SharedActions/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SharedActions/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.oracle.graal.visualizer.sharedactions</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.svg</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.actions</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.24.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.39.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.dialogs</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.23.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.19.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.oracle.graal.visualizer.sharedactions</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SharedActions/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SharedActions/src/com/oracle/graal/visualizer/sharedactions/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=SharedActions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SharedActions/src/com/oracle/graal/visualizer/sharedactions/ExportSVGAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,118 @@
+/*
+ * 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.visualizer.sharedactions;
+
+import com.sun.hotspot.igv.svg.BatikSVG;
+import java.awt.Graphics2D;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.*;
+import javax.swing.JFileChooser;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionRegistration;
+import org.openide.util.NbPreferences;
+
+@ActionID(id = "com.oracle.graal.visualizer.sharedactions.ExportSVGAction", category = "File")
+@ActionRegistration(displayName = "Export", iconBase = "com/oracle/graal/visualizer/sharedactions/images/export.png")
+@ActionReference(path = "Menu/File", position = 600)
+public class ExportSVGAction implements ActionListener {
+
+    private static final String PREFERENCE_DIR = "dir";
+    private ExportSVGCookie exportCookie;
+
+    public ExportSVGAction(ExportSVGCookie exportCookie) {
+        this.exportCookie = exportCookie;
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent actionEvent) {
+        Graphics2D svgGenerator = BatikSVG.createGraphicsObject();
+        if (svgGenerator == null) {
+            NotifyDescriptor message = new NotifyDescriptor.Message("For export to SVG files the Batik SVG Toolkit must be intalled.", NotifyDescriptor.ERROR_MESSAGE);
+            DialogDisplayer.getDefault().notifyLater(message);
+            return;
+        }
+        
+        File f = selectFile();
+        if (f != null) {
+            exportCookie.paint(svgGenerator);
+            FileOutputStream os = null;
+            try {
+                os = new FileOutputStream(f);
+                Writer out = new OutputStreamWriter(os, "UTF-8");
+                BatikSVG.printToStream(svgGenerator, out, true);
+            } catch (FileNotFoundException e) {
+                NotifyDescriptor message = new NotifyDescriptor.Message("For export to SVG files the Batik SVG Toolkit must be intalled.", NotifyDescriptor.ERROR_MESSAGE);
+                DialogDisplayer.getDefault().notifyLater(message);
+
+            } catch (UnsupportedEncodingException e) {
+            } finally {
+                if (os != null) {
+                    try {
+                        os.close();
+                    } catch (IOException e) {
+                    }
+                }
+            }
+        }
+    }
+
+    private File selectFile() {
+        JFileChooser fc = new JFileChooser();
+        fc.setFileFilter(new javax.swing.filechooser.FileFilter() {
+
+            @Override
+            public boolean accept(File f) {
+                return true;
+            }
+
+            @Override
+            public String getDescription() {
+                return "SVG files (*.svg)";
+            }
+        });
+        fc.setCurrentDirectory(new File(NbPreferences.forModule(ExportSVGAction.class).get(PREFERENCE_DIR, "~")));
+
+
+        if (fc.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
+            File file = fc.getSelectedFile();
+            if (!file.getName().contains(".")) {
+                file = new File(file.getAbsolutePath() + ".svg");
+            }
+
+            File dir = file;
+            if (!dir.isDirectory()) {
+                dir = dir.getParentFile();
+            }
+
+            NbPreferences.forModule(ExportSVGAction.class).put(PREFERENCE_DIR, dir.getAbsolutePath());
+            return file;
+        }
+
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SharedActions/src/com/oracle/graal/visualizer/sharedactions/ExportSVGCookie.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,30 @@
+/*
+ * 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.visualizer.sharedactions;
+
+import java.awt.Graphics2D;
+
+public interface ExportSVGCookie {
+    void paint(Graphics2D g);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SharedActions/src/com/oracle/graal/visualizer/sharedactions/ShowAllAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * 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.visualizer.sharedactions;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionRegistration;
+
+@ActionID(id = "com.oracle.graal.visualizer.sharedactions.ShowAllAction", category = "View")
+@ActionRegistration(displayName = "Fit Scene to Window", iconBase="com/oracle/graal/visualizer/sharedactions/images/autosize.gif")
+@ActionReference(path = "Menu/View", position = 500)
+public class ShowAllAction implements ActionListener {
+       
+    private List<ZoomCookie> zoomCookies;
+    
+    public ShowAllAction(List<ZoomCookie> zoomCookies) {
+        this.zoomCookies = zoomCookies;
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        for (ZoomCookie c : zoomCookies) {
+            c.showAll();
+        }
+    }
+}   
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SharedActions/src/com/oracle/graal/visualizer/sharedactions/ZoomCookie.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,31 @@
+/*
+ * 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.visualizer.sharedactions;
+
+public interface ZoomCookie {
+    void zoomIn();
+    void zoomOut();
+    void showAll();
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SharedActions/src/com/oracle/graal/visualizer/sharedactions/ZoomInAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * 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.visualizer.sharedactions;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionRegistration;
+
+@ActionID(id = "com.oracle.graal.visualizer.sharedactions.ZoomInAction", category = "View")
+@ActionRegistration(displayName = "Zoom In", iconBase="com/oracle/graal/visualizer/sharedactions/images/zoomin.gif")
+@ActionReference(path = "Menu/View", position = 600)
+public class ZoomInAction implements ActionListener {
+    
+    private List<ZoomCookie> zoomCookies;
+    
+    public ZoomInAction(List<ZoomCookie> zoomCookies) {
+        this.zoomCookies = zoomCookies;
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        for (ZoomCookie c : zoomCookies) {
+            c.zoomIn();
+        }
+    }
+}   
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SharedActions/src/com/oracle/graal/visualizer/sharedactions/ZoomOutAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * 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.visualizer.sharedactions;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionRegistration;
+
+@ActionID(id = "com.oracle.graal.visualizer.sharedactions.ZoomOutAction", category = "View")
+@ActionRegistration(displayName = "Zoom Out", iconBase="com/oracle/graal/visualizer/sharedactions/images/zoomout.gif")
+@ActionReference(path = "Menu/View", position = 700)
+public class ZoomOutAction implements ActionListener {
+   
+    private List<ZoomCookie> zoomCookies;
+    
+    public ZoomOutAction(List<ZoomCookie> zoomCookies) {
+        this.zoomCookies = zoomCookies;
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        for (ZoomCookie c : zoomCookies) {
+            c.zoomOut();
+        }
+    } 
+}   
Binary file visualizer/SharedActions/src/com/oracle/graal/visualizer/sharedactions/images/autosize.gif has changed
Binary file visualizer/SharedActions/src/com/oracle/graal/visualizer/sharedactions/images/export.png has changed
Binary file visualizer/SharedActions/src/com/oracle/graal/visualizer/sharedactions/images/zoomin.gif has changed
Binary file visualizer/SharedActions/src/com/oracle/graal/visualizer/sharedactions/images/zoomout.gif has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SnapshotsView/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.oracle.graal.visualizer.snapshots" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.oracle.graal.visualizer.snapshots.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SnapshotsView/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.oracle.graal.visualizer.snapshots
+OpenIDE-Module-Layer: com/oracle/graal/visualizer/snapshots/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/oracle/graal/visualizer/snapshots/Bundle.properties
+OpenIDE-Module-Requires: org.openide.windows.WindowManager
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SnapshotsView/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.oracle.graal.visualizer.snapshots-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SnapshotsView/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=8a85c130
+build.xml.script.CRC32=d28dc95d
+build.xml.stylesheet.CRC32=a56c6a5b@2.47.1
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=8a85c130
+nbproject/build-impl.xml.script.CRC32=dfcb8f66
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.47.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SnapshotsView/nbproject/platform.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,204 @@
+cluster.path=\
+    ${nbplatform.active.dir}/ide:\
+    ${nbplatform.active.dir}/platform
+disabled.modules=\
+    com.jcraft.jsch,\
+    com.jcraft.jzlib,\
+    org.apache.commons.codec,\
+    org.apache.commons.httpclient,\
+    org.apache.commons.io,\
+    org.apache.commons.lang,\
+    org.apache.commons.logging,\
+    org.apache.ws.commons.util,\
+    org.apache.xml.resolver,\
+    org.apache.xmlrpc,\
+    org.eclipse.core.contenttype,\
+    org.eclipse.core.jobs,\
+    org.eclipse.core.net,\
+    org.eclipse.core.runtime,\
+    org.eclipse.core.runtime.compatibility.auth,\
+    org.eclipse.equinox.app,\
+    org.eclipse.equinox.common,\
+    org.eclipse.equinox.preferences,\
+    org.eclipse.equinox.registry,\
+    org.eclipse.equinox.security,\
+    org.eclipse.jgit,\
+    org.eclipse.mylyn.bugzilla.core,\
+    org.eclipse.mylyn.commons.core,\
+    org.eclipse.mylyn.commons.net,\
+    org.eclipse.mylyn.commons.xmlrpc,\
+    org.eclipse.mylyn.tasks.core,\
+    org.mozilla.rhino.patched,\
+    org.netbeans.api.debugger,\
+    org.netbeans.api.java.classpath,\
+    org.netbeans.api.xml,\
+    org.netbeans.core.browser,\
+    org.netbeans.core.execution,\
+    org.netbeans.core.ide,\
+    org.netbeans.core.io.ui,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.nativeaccess,\
+    org.netbeans.core.osgi,\
+    org.netbeans.lib.cvsclient,\
+    org.netbeans.lib.terminalemulator,\
+    org.netbeans.libs.antlr3.runtime,\
+    org.netbeans.libs.bytelist,\
+    org.netbeans.libs.commons_net,\
+    org.netbeans.libs.freemarker,\
+    org.netbeans.libs.git,\
+    org.netbeans.libs.ini4j,\
+    org.netbeans.libs.jaxb,\
+    org.netbeans.libs.jsr223,\
+    org.netbeans.libs.junit4,\
+    org.netbeans.libs.jvyamlb,\
+    org.netbeans.libs.lucene,\
+    org.netbeans.libs.smack,\
+    org.netbeans.libs.svnClientAdapter,\
+    org.netbeans.libs.svnClientAdapter.javahl,\
+    org.netbeans.libs.svnClientAdapter.svnkit,\
+    org.netbeans.libs.swingx,\
+    org.netbeans.libs.xerces,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.bugtracking,\
+    org.netbeans.modules.bugtracking.bridge,\
+    org.netbeans.modules.bugzilla,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.csl.api,\
+    org.netbeans.modules.css.editor,\
+    org.netbeans.modules.css.lib,\
+    org.netbeans.modules.css.visual,\
+    org.netbeans.modules.db,\
+    org.netbeans.modules.db.core,\
+    org.netbeans.modules.db.dataview,\
+    org.netbeans.modules.db.drivers,\
+    org.netbeans.modules.db.kit,\
+    org.netbeans.modules.db.metadata.model,\
+    org.netbeans.modules.db.mysql,\
+    org.netbeans.modules.db.sql.editor,\
+    org.netbeans.modules.db.sql.visualeditor,\
+    org.netbeans.modules.dbapi,\
+    org.netbeans.modules.defaults,\
+    org.netbeans.modules.derby,\
+    org.netbeans.modules.dlight.nativeexecution,\
+    org.netbeans.modules.dlight.terminal,\
+    org.netbeans.modules.editor.bookmarks,\
+    org.netbeans.modules.editor.bracesmatching,\
+    org.netbeans.modules.editor.codetemplates,\
+    org.netbeans.modules.editor.completion,\
+    org.netbeans.modules.editor.guards,\
+    org.netbeans.modules.editor.indent.project,\
+    org.netbeans.modules.editor.kit,\
+    org.netbeans.modules.editor.macros,\
+    org.netbeans.modules.editor.structure,\
+    org.netbeans.modules.extbrowser,\
+    org.netbeans.modules.extexecution,\
+    org.netbeans.modules.extexecution.destroy,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.git,\
+    org.netbeans.modules.glassfish.common,\
+    org.netbeans.modules.gototest,\
+    org.netbeans.modules.gsf.codecoverage,\
+    org.netbeans.modules.gsf.testrunner,\
+    org.netbeans.modules.html,\
+    org.netbeans.modules.html.editor,\
+    org.netbeans.modules.html.editor.lib,\
+    org.netbeans.modules.html.lexer,\
+    org.netbeans.modules.html.parser,\
+    org.netbeans.modules.html.validation,\
+    org.netbeans.modules.httpserver,\
+    org.netbeans.modules.hudson,\
+    org.netbeans.modules.hudson.git,\
+    org.netbeans.modules.hudson.mercurial,\
+    org.netbeans.modules.hudson.subversion,\
+    org.netbeans.modules.hudson.tasklist,\
+    org.netbeans.modules.ide.kit,\
+    org.netbeans.modules.image,\
+    org.netbeans.modules.javascript.editing,\
+    org.netbeans.modules.javascript.hints,\
+    org.netbeans.modules.javascript.kit,\
+    org.netbeans.modules.javascript.refactoring,\
+    org.netbeans.modules.jellytools.ide,\
+    org.netbeans.modules.jumpto,\
+    org.netbeans.modules.keyring.impl,\
+    org.netbeans.modules.languages,\
+    org.netbeans.modules.languages.diff,\
+    org.netbeans.modules.languages.manifest,\
+    org.netbeans.modules.languages.yaml,\
+    org.netbeans.modules.lexer.nbbridge,\
+    org.netbeans.modules.localhistory,\
+    org.netbeans.modules.mercurial,\
+    org.netbeans.modules.netbinox,\
+    org.netbeans.modules.parsing.api,\
+    org.netbeans.modules.parsing.lucene,\
+    org.netbeans.modules.print.editor,\
+    org.netbeans.modules.project.ant,\
+    org.netbeans.modules.project.libraries,\
+    org.netbeans.modules.projectui,\
+    org.netbeans.modules.projectui.buildmenu,\
+    org.netbeans.modules.projectuiapi,\
+    org.netbeans.modules.properties,\
+    org.netbeans.modules.properties.syntax,\
+    org.netbeans.modules.refactoring.api,\
+    org.netbeans.modules.schema2beans,\
+    org.netbeans.modules.server,\
+    org.netbeans.modules.servletapi,\
+    org.netbeans.modules.spellchecker,\
+    org.netbeans.modules.spellchecker.apimodule,\
+    org.netbeans.modules.spellchecker.bindings.htmlxml,\
+    org.netbeans.modules.spellchecker.bindings.properties,\
+    org.netbeans.modules.spellchecker.dictionary_en,\
+    org.netbeans.modules.spellchecker.kit,\
+    org.netbeans.modules.spi.actions,\
+    org.netbeans.modules.subversion,\
+    org.netbeans.modules.swing.validation,\
+    org.netbeans.modules.target.iterator,\
+    org.netbeans.modules.tasklist.kit,\
+    org.netbeans.modules.tasklist.projectint,\
+    org.netbeans.modules.tasklist.todo,\
+    org.netbeans.modules.tasklist.ui,\
+    org.netbeans.modules.terminal,\
+    org.netbeans.modules.usersguide,\
+    org.netbeans.modules.utilities,\
+    org.netbeans.modules.utilities.project,\
+    org.netbeans.modules.versioning,\
+    org.netbeans.modules.versioning.indexingbridge,\
+    org.netbeans.modules.versioning.system.cvss.installer,\
+    org.netbeans.modules.versioning.util,\
+    org.netbeans.modules.web.client.tools.api,\
+    org.netbeans.modules.web.common,\
+    org.netbeans.modules.web.indent,\
+    org.netbeans.modules.xml,\
+    org.netbeans.modules.xml.axi,\
+    org.netbeans.modules.xml.catalog,\
+    org.netbeans.modules.xml.core,\
+    org.netbeans.modules.xml.jaxb.api,\
+    org.netbeans.modules.xml.lexer,\
+    org.netbeans.modules.xml.multiview,\
+    org.netbeans.modules.xml.retriever,\
+    org.netbeans.modules.xml.schema.completion,\
+    org.netbeans.modules.xml.schema.model,\
+    org.netbeans.modules.xml.tax,\
+    org.netbeans.modules.xml.text,\
+    org.netbeans.modules.xml.tools,\
+    org.netbeans.modules.xml.wsdl.model,\
+    org.netbeans.modules.xml.xam,\
+    org.netbeans.modules.xml.xdm,\
+    org.netbeans.modules.xsl,\
+    org.netbeans.spi.debugger.ui,\
+    org.netbeans.spi.editor.hints,\
+    org.netbeans.spi.navigator,\
+    org.netbeans.spi.palette,\
+    org.netbeans.spi.tasklist,\
+    org.netbeans.spi.viewmodel,\
+    org.netbeans.swing.dirchooser,\
+    org.openide.compat,\
+    org.openide.execution,\
+    org.openide.options,\
+    org.openide.util.enumerations
+## Not disabled because of NetBeans bug 206347:
+## Applications not using OSGi don't start on NbP 7.1
+#   org.netbeans.core.netigso,\
+#   org.netbeans.libs.felix,\
+#   org.netbeans.libs.osgi,\
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SnapshotsView/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.6
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SnapshotsView/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.oracle.graal.visualizer.snapshots</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.oracle.graal.visualizer.editor</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.settings</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.33.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.39.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.19.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.11.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.48.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages/>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SnapshotsView/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=SnapshotsView
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/SnapshotTopComponent.form	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.3" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <EmptySpace min="0" pref="400" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <EmptySpace min="0" pref="300" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+</Form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/SnapshotTopComponent.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,130 @@
+/*
+ * 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.visualizer.snapshots;
+
+import com.oracle.graal.visualizer.editor.EditorTopComponent;
+import com.oracle.graal.visualizer.util.LookupUtils;
+import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.util.RangeSlider;
+import com.sun.hotspot.igv.util.RangeSliderModel;
+import java.awt.BorderLayout;
+import javax.swing.JScrollPane;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.util.Lookup.Result;
+import org.openide.util.LookupEvent;
+import org.openide.util.LookupListener;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
+
+@TopComponent.Description(preferredID = SnapshotTopComponent.PREFERRED_ID, persistenceType = TopComponent.PERSISTENCE_ALWAYS)
+@TopComponent.Registration(mode = "belowExplorer", openAtStartup = true)
+@ActionID(category = "Window", id = "com.oracle.graal.visualizer.snapshots.SnapshotTopComponent")
+@ActionReference(path = "Menu/Window")
+@TopComponent.OpenActionRegistration(displayName = "Snapshot", preferredID = SnapshotTopComponent.PREFERRED_ID)
+public final class SnapshotTopComponent extends TopComponent {
+    public static final String PREFERRED_ID = "SnapshotTopComponent";
+
+    private final Result<RangeSliderModel> result;
+    private final RangeSlider rangeSlider;
+    private final ChangedEvent<RangeSliderModel> rangeSliderChangedEvent = new ChangedEvent<RangeSliderModel>(null);
+    private final LookupListener lookupListener = new LookupListener() {
+
+        @Override
+        public void resultChanged(LookupEvent le) {
+            update();
+        }
+    };
+
+    private final ChangedListener<RangeSliderModel> rangeSliderChangedListener = new ChangedListener<RangeSliderModel>(){
+
+        @Override
+        public void changed(RangeSliderModel source) {
+            rangeSliderChangedEvent.fire();
+        }
+    };
+
+    public SnapshotTopComponent() {
+        initComponents();
+        setName("Snapshot Window");
+        setToolTipText("This is a Snapshot window");
+
+        result = LookupUtils.getLastActiveDelegatingLookup(EditorTopComponent.class).lookupResult(RangeSliderModel.class);
+        result.addLookupListener(lookupListener);
+        this.rangeSlider = new RangeSlider(null);
+        this.setLayout(new BorderLayout());
+        final JScrollPane scrollPane = new JScrollPane(rangeSlider);
+        scrollPane.getVerticalScrollBar().setUnitIncrement(RangeSlider.ITEM_HEIGHT);
+        this.add(scrollPane, BorderLayout.CENTER);
+        update();
+    }
+
+    private void update() {
+        RangeSliderModel newModel;
+        if (result.allInstances().size() > 0) {
+            newModel = result.allInstances().iterator().next();
+        } else {
+            newModel = null;
+        }
+        if (rangeSlider.getModel() != null) {
+            rangeSlider.getModel().getChangedEvent().removeListener(rangeSliderChangedListener);
+        }
+        rangeSlider.setModel(newModel);
+        rangeSliderChangedEvent.changeObject(newModel);
+        if (newModel != null) {
+            newModel.getChangedEvent().addListener(rangeSliderChangedListener);
+        }
+    }
+
+    public ChangedEvent<RangeSliderModel> getRangeSliderChangedEvent() {
+        return rangeSliderChangedEvent;
+    }
+
+    public static SnapshotTopComponent findInstance() {
+        return (SnapshotTopComponent) WindowManager.getDefault().findTopComponent(PREFERRED_ID);
+    }
+
+    /**
+     * This method is called from within the constructor to initialize the form. WARNING: Do NOT modify this code. The content of this method is always
+     * regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGap(0, 400, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGap(0, 300, Short.MAX_VALUE)
+        );
+    }// </editor-fold>//GEN-END:initComponents
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    // End of variables declaration//GEN-END:variables
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/actions/NextSnapshotAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,66 @@
+/*
+ * 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.visualizer.snapshots.actions;
+
+import com.oracle.graal.visualizer.snapshots.SnapshotTopComponent;
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.util.RangeSliderModel;
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionRegistration;
+
+@ActionID(id = "com.oracle.graal.visualizer.editor.actions.NextSnapshotAction", category = "View")
+@ActionRegistration(displayName = "Next snapshot", iconBase = "com/oracle/graal/visualizer/snapshots/images/next_snapshot.png")
+@ActionReference(path = "Menu/View", position = 150)
+public final class NextSnapshotAction extends AbstractAction{
+
+    private RangeSliderModel model;
+
+    public NextSnapshotAction() {
+        SnapshotTopComponent.findInstance().getRangeSliderChangedEvent().addListenerAndFire(changeListener);
+    }
+    private final ChangedListener<RangeSliderModel> changeListener = new ChangedListener<RangeSliderModel>() {
+
+        @Override
+        public void changed(RangeSliderModel source) {
+            model = source;
+            setEnabled(model != null && model.getSecondPosition() != model.getPositions().size() - 1);
+        }
+    };
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        if (model != null) {
+            int fp = model.getFirstPosition();
+            int sp = model.getSecondPosition();
+            if (sp != model.getPositions().size() - 1) {
+                int nfp = fp + 1;
+                int nsp = sp + 1;
+                model.setPositions(nfp, nsp);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/actions/PrevSnapshotAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2008, 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.visualizer.snapshots.actions;
+
+import com.oracle.graal.visualizer.snapshots.SnapshotTopComponent;
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.util.RangeSliderModel;
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionRegistration;
+
+@ActionID(id = "com.oracle.graal.visualizer.editor.actions.PrevSnapshotAction", category = "View")
+@ActionRegistration(displayName = "Previous snapshot", iconBase = "com/oracle/graal/visualizer/snapshots/images/prev_snapshot.png")
+@ActionReference(path = "Menu/View", position = 100)
+public final class PrevSnapshotAction extends AbstractAction {
+
+    private RangeSliderModel model;
+
+    public PrevSnapshotAction() {
+        SnapshotTopComponent.findInstance().getRangeSliderChangedEvent().addListenerAndFire(changeListener);
+    }
+    private final ChangedListener<RangeSliderModel> changeListener = new ChangedListener<RangeSliderModel>() {
+
+        @Override
+        public void changed(RangeSliderModel source) {
+            model = source;
+            setEnabled(model != null && model.getFirstPosition() != 0);
+        }
+    };
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        if (model != null) {
+            int fp = model.getFirstPosition();
+            int sp = model.getSecondPosition();
+            if (fp != 0) {
+                int nfp = fp - 1;
+                int nsp = sp - 1;
+                model.setPositions(nfp, nsp);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/belowExplorerWsmode.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mode version="2.4">
+    <name unique="belowExplorer"/>
+    <kind type="view"/>
+    <state type="joined"/>
+    <constraints>
+        <path orientation="horizontal" number="20" weight="0.3"/>
+        <path orientation="vertical" number="21" weight="0.548"/>
+    </constraints>
+    <bounds x="0" y="0" width="0" height="0"/>
+    <frame state="0"/>
+    
+    <empty-behavior permanent="false"/>
+</mode>
Binary file visualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/images/next_snapshot.png has changed
Binary file visualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/images/prev_snapshot.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/SnapshotsView/src/com/oracle/graal/visualizer/snapshots/layer.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
+<filesystem> 
+    <folder name="Windows2">
+        <folder name="Modes">  
+            <file name="belowExplorer.wsmode" url="belowExplorerWsmode.xml"/>
+        </folder>
+    </folder>
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.util" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.util.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.util
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/util/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.util-impl" basedir="..">
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+        <condition>
+            <not>
+                <available file="${harness.dir}" type="dir"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=a470a16f
+build.xml.script.CRC32=466cf03b
+build.xml.stylesheet.CRC32=05353c81
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=a470a16f
+nbproject/build-impl.xml.script.CRC32=39f45e01
+nbproject/build-impl.xml.stylesheet.CRC32=3f8b4615
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/nbproject/platform.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.javahelp,\
+    org.netbeans.modules.masterfs,\
+    org.netbeans.modules.options.keymap,\
+    org.netbeans.modules.sendopts,\
+    org.netbeans.modules.templates,\
+    org.openide.compat,\
+    org.openide.execution,\
+    org.openide.util.enumerations
+enabled.clusters=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.util</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.api.visual</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>2.27.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.nodes</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.20.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.48.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.oracle.graal.visualizer.util</package>
+                <package>com.sun.hotspot.igv.util</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/src/com/oracle/graal/visualizer/util/LookupUtils.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,123 @@
+/*
+ * 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.visualizer.util;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.Action;
+import org.openide.util.ContextAwareAction;
+import org.openide.util.Lookup;
+import org.openide.util.Lookup.Provider;
+import org.openide.util.lookup.Lookups;
+import org.openide.windows.TopComponent;
+
+/**
+ * Utilities that build upon the Lookup API.
+ */
+public class LookupUtils {
+
+    
+    /**
+     * Creates a new lookup that will delegate to the last open window of a specified top component class. If the window is closed, the lookup will be empty.
+     * @param clazz the class identifying the top component type
+     * @return a delegating lookup
+     */
+    public static Lookup getLastActiveDelegatingLookup(Class<?> clazz) {
+        final TopComponentLookup topComponentLookupImpl = new TopComponentLookup(clazz);
+        TopComponent.getRegistry().addPropertyChangeListener(topComponentLookupImpl);
+        return topComponentLookupImpl.lookup;
+    }
+    
+    public static Iterable<Action> lookupActions(String path) {
+        return lookupActions(path, null);
+    }
+
+    public static Iterable<Action> lookupActions(String path, Lookup context) {
+        List<Action> actions = new ArrayList<>();
+        for (Action a : Lookups.forPath(path).lookupAll(Action.class)) {
+            Action newAction = a;
+            if (a instanceof ContextAwareAction && context != null) {
+                newAction = ((ContextAwareAction) a).createContextAwareInstance(context);
+            }
+            newAction.putValue(Action.SHORT_DESCRIPTION, newAction.getValue(Action.NAME));
+            actions.add(newAction);
+            
+        }
+        return actions;
+    }
+    
+    private static class TopComponentLookup implements PropertyChangeListener {
+        private final Class<?> clazz;
+        private final Lookup lookup;
+        private TopComponent lastActive;
+        
+        private final Provider lookupProvider = new Provider() {
+
+            @Override
+            public Lookup getLookup() {
+                if (lastActive == null) {
+                    return Lookup.EMPTY;
+                } else {
+                    return lastActive.getLookup();
+                }
+            }
+        };
+        
+        public TopComponentLookup(Class<?> clazz) {
+            this.clazz = clazz;
+            lookup = Lookups.proxy(lookupProvider);
+            update();
+        }
+        
+        @Override
+        public void propertyChange(PropertyChangeEvent evt) {
+            update();
+        }
+
+        private void update() {
+            TopComponent curActivated = TopComponent.getRegistry().getActivated();
+            if (curActivated != lastActive) {
+                if (clazz.isAssignableFrom(curActivated.getClass())) {
+                    // We have a new top component for our lookup.
+                    lastActive = curActivated;
+                    refreshLookup();
+                } else {
+                    // We have no new top component. Check if the old one is still opened.
+                    if (lastActive != null && !TopComponent.getRegistry().getOpened().contains(lastActive)) {
+                        // The top component was closed => Remove lookup.
+                        lastActive = null;
+                        refreshLookup();
+                    }
+                }
+            }
+        }
+
+        private void refreshLookup() {
+            lookup.lookup(Object.class);
+        }
+    };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/src/com/sun/hotspot/igv/util/BoundedZoomAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.util;
+
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Rectangle;
+import javax.swing.JComponent;
+import javax.swing.JScrollPane;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.action.WidgetAction.State;
+import org.netbeans.api.visual.action.WidgetAction.WidgetMouseWheelEvent;
+import org.netbeans.api.visual.animator.SceneAnimator;
+import org.netbeans.api.visual.widget.Scene;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class BoundedZoomAction extends WidgetAction.Adapter {
+
+    private double minFactor = 0.0;
+    private double maxFactor = Double.MAX_VALUE;
+    private double zoomMultiplier;
+    private boolean useAnimator;
+
+    public BoundedZoomAction(double zoomMultiplier, boolean useAnimator) {
+        this.zoomMultiplier = zoomMultiplier;
+        this.useAnimator = useAnimator;
+    }
+
+    public double getMinFactor() {
+        return minFactor;
+    }
+
+    public void setMinFactor(double d) {
+        minFactor = d;
+    }
+
+    public double getMaxFactor() {
+        return maxFactor;
+    }
+
+    public void setMaxFactor(double d) {
+        maxFactor = d;
+    }
+
+    private JScrollPane findScrollPane(JComponent component) {
+        for (;;) {
+            if (component == null) {
+                return null;
+            }
+            if (component instanceof JScrollPane) {
+                return ((JScrollPane) component);
+            }
+            Container parent = component.getParent();
+            if (!(parent instanceof JComponent)) {
+                return null;
+            }
+            component = (JComponent) parent;
+        }
+    }
+
+    @Override
+    public State mouseWheelMoved(Widget widget, WidgetMouseWheelEvent event) {
+        final Scene scene = widget.getScene();
+        int amount = event.getWheelRotation();
+        JScrollPane scrollPane = findScrollPane(scene.getView());
+        Point viewPosition = null;
+        Point mouseLocation = scene.convertSceneToView(event.getPoint());
+        int xOffset = 0;
+        int yOffset = 0;
+        Rectangle bounds = new Rectangle(scene.getBounds());
+        Dimension componentSize = new Dimension(scene.getView().getPreferredSize());
+
+        if (scrollPane != null) {
+            viewPosition = new Point(scrollPane.getViewport().getViewPosition());
+            xOffset = (mouseLocation.x - viewPosition.x);
+            yOffset = (mouseLocation.y - viewPosition.y);
+            viewPosition.x += xOffset;
+            viewPosition.y += yOffset;
+        }
+
+        if (useAnimator) {
+            SceneAnimator sceneAnimator = scene.getSceneAnimator();
+            synchronized (sceneAnimator) {
+                double zoom = sceneAnimator.isAnimatingZoomFactor() ? sceneAnimator.getTargetZoomFactor() : scene.getZoomFactor();
+                while (amount > 0 && zoom / zoomMultiplier >= minFactor && zoom / zoomMultiplier <= maxFactor) {
+                    zoom /= zoomMultiplier;
+                    if (viewPosition != null) {
+                        viewPosition.x /= zoomMultiplier;
+                        viewPosition.y /= zoomMultiplier;
+                        bounds.width /= zoomMultiplier;
+                        bounds.height /= zoomMultiplier;
+                        componentSize.width /= zoomMultiplier;
+                        componentSize.height /= zoomMultiplier;
+                    }
+                    amount--;
+                }
+                while (amount < 0 && zoom * zoomMultiplier >= minFactor && zoom * zoomMultiplier <= maxFactor) {
+                    zoom *= zoomMultiplier;
+                    if (viewPosition != null) {
+                        viewPosition.x *= zoomMultiplier;
+                        viewPosition.y *= zoomMultiplier;
+                        bounds.width *= zoomMultiplier;
+                        bounds.height *= zoomMultiplier;
+                        componentSize.width *= zoomMultiplier;
+                        componentSize.height *= zoomMultiplier;
+                    }
+                    amount++;
+                }
+                sceneAnimator.animateZoomFactor(zoom);
+            }
+        } else {
+            double zoom = scene.getZoomFactor();
+            while (amount > 0 && zoom / zoomMultiplier >= minFactor && zoom / zoomMultiplier <= maxFactor) {
+                zoom /= zoomMultiplier;
+                if (viewPosition != null) {
+                    viewPosition.x /= zoomMultiplier;
+                    viewPosition.y /= zoomMultiplier;
+                    bounds.width /= zoomMultiplier;
+                    bounds.height /= zoomMultiplier;
+                    componentSize.width /= zoomMultiplier;
+                    componentSize.height /= zoomMultiplier;
+                }
+                amount--;
+            }
+            while (amount < 0 && zoom * zoomMultiplier >= minFactor && zoom * zoomMultiplier <= maxFactor) {
+                zoom *= zoomMultiplier;
+                if (viewPosition != null) {
+                    viewPosition.x *= zoomMultiplier;
+                    viewPosition.y *= zoomMultiplier;
+                    bounds.width *= zoomMultiplier;
+                    bounds.height *= zoomMultiplier;
+                    componentSize.width *= zoomMultiplier;
+                    componentSize.height *= zoomMultiplier;
+                }
+                amount++;
+            }
+            scene.setZoomFactor(zoom);
+        }
+
+        if (scrollPane != null) {
+            scene.validate(); // Call validate to update size of scene
+            Dimension size = scrollPane.getViewport().getExtentSize();
+            viewPosition.x -= xOffset;
+            viewPosition.y -= yOffset;
+            scene.resolveBounds(scene.getLocation(), bounds);
+            scene.getView().setPreferredSize(componentSize);
+            scene.getView().revalidate();
+            scene.getView().addNotify();
+            scrollPane.getViewport().setViewPosition(viewPosition);
+        }
+
+        return WidgetAction.State.CONSUMED;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/src/com/sun/hotspot/igv/util/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=Util
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/src/com/sun/hotspot/igv/util/ColorIcon.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.util;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics;
+import javax.swing.Icon;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ColorIcon implements Icon {
+
+    private Color color;
+
+    public ColorIcon(Color c) {
+        color = c;
+    }
+
+    @Override
+    public void paintIcon(Component c, Graphics g, int x, int y) {
+        g.setColor(color);
+        g.fillRect(x, y, 16, 16);
+    }
+
+    @Override
+    public int getIconWidth() {
+        return 16;
+    }
+
+    @Override
+    public int getIconHeight() {
+        return 16;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/src/com/sun/hotspot/igv/util/CompilationViewModel.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package com.sun.hotspot.igv.util;
+
+import com.sun.hotspot.igv.data.*;
+import java.awt.Color;
+import java.util.List;
+
+public class CompilationViewModel implements ChangedEventProvider<CompilationViewModel> {
+    
+    private final ChangedEvent<CompilationViewModel> changedEvent = new ChangedEvent<>(this);
+    private final RangeSliderModel model;
+    private final Group group;
+
+    @Override
+    public ChangedEvent<CompilationViewModel> getChangedEvent() {
+        return changedEvent;
+    }
+    
+    public CompilationViewModel(RangeSliderModel model, Group group) {
+        this.model = model;
+        this.group = group;
+        model.getChangedEvent().addListener(rangeSliderChangedListener);
+    }
+    
+    private final ChangedListener<RangeSliderModel> rangeSliderChangedListener = new ChangedListener<RangeSliderModel>() {
+        @Override
+        public void changed(RangeSliderModel source) {
+            changedEvent.fire();
+        }
+    };
+    
+    public InputGraph getFirstSnapshot() {
+        return group.getGraphs().get(model.getFirstPosition());
+    }
+    
+    public InputGraph getSecondSnapshot() {
+        return group.getGraphs().get(model.getSecondPosition());
+    }
+
+    public void setColors(List<Color> colors) {
+        model.setColors(colors);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/src/com/sun/hotspot/igv/util/DoubleClickAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.util;
+
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class DoubleClickAction extends WidgetAction.Adapter {
+
+    private DoubleClickHandler handler;
+
+    public DoubleClickAction(DoubleClickHandler handler) {
+        this.handler = handler;
+    }
+
+    @Override
+    public WidgetAction.State mouseClicked(Widget widget, WidgetAction.WidgetMouseEvent event) {
+        if (event.getClickCount() > 1) {
+            handler.handleDoubleClick(widget, event);
+            return WidgetAction.State.CONSUMED;
+        }
+        return WidgetAction.State.REJECTED;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/src/com/sun/hotspot/igv/util/DoubleClickHandler.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.util;
+
+import org.netbeans.api.visual.action.WidgetAction.WidgetMouseEvent;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface DoubleClickHandler {
+
+    public void handleDoubleClick(Widget w, WidgetMouseEvent e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/src/com/sun/hotspot/igv/util/ExtendedSatelliteComponent.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.util;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.JComponent;
+import org.netbeans.api.visual.widget.Scene;
+
+/**
+ * @author David Kaspar
+ * @author Thomas Wuerthinger
+ */
+public class ExtendedSatelliteComponent extends JComponent implements MouseListener, MouseMotionListener, Scene.SceneListener, ComponentListener {
+
+    private Scene scene;
+    private Image image;
+    private int imageWidth;
+    private int imageHeight;
+
+    public ExtendedSatelliteComponent(Scene scene) {
+        this.scene = scene;
+        setDoubleBuffered(true);
+        setPreferredSize(new Dimension(128, 128));
+        addMouseListener(this);
+        addMouseMotionListener(this);
+    }
+
+    @Override
+    public void addNotify() {
+        super.addNotify();
+        scene.addSceneListener(this);
+        JComponent viewComponent = scene.getView();
+        if (viewComponent == null) {
+            viewComponent = scene.createView();
+        }
+        viewComponent.addComponentListener(this);
+        repaint();
+    }
+
+    @Override
+    public void removeNotify() {
+        scene.getView().removeComponentListener(this);
+        scene.removeSceneListener(this);
+        super.removeNotify();
+    }
+
+    public void update() {
+        this.image = null;
+        repaint();
+    }
+
+    @Override
+    public void paint(Graphics g) {
+        Graphics2D gr = (Graphics2D) g;
+        super.paint(g);
+        Rectangle bounds = scene.getBounds();
+        Dimension size = getSize();
+
+        double sx = bounds.width > 0 ? (double) size.width / bounds.width : 0.0;
+        double sy = bounds.width > 0 ? (double) size.height / bounds.height : 0.0;
+        double scale = Math.min(sx, sy);
+
+        int vw = (int) (scale * bounds.width);
+        int vh = (int) (scale * bounds.height);
+        int vx = (size.width - vw) / 2;
+        int vy = (size.height - vh) / 2;
+
+
+        if (image == null || vw != imageWidth || vh != imageHeight) {
+
+            imageWidth = vw;
+            imageHeight = vh;
+            image = this.createImage(imageWidth, imageHeight);
+            Graphics2D ig = (Graphics2D) image.getGraphics();
+            ig.scale(scale, scale);
+            scene.paint(ig);
+        }
+
+        gr.drawImage(image, vx, vy, this);
+
+        JComponent component = scene.getView();
+        double zoomFactor = scene.getZoomFactor();
+        Rectangle viewRectangle = component != null ? component.getVisibleRect() : null;
+        if (viewRectangle != null) {
+            Rectangle window = new Rectangle(
+                    (int) ((double) viewRectangle.x * scale / zoomFactor),
+                    (int) ((double) viewRectangle.y * scale / zoomFactor),
+                    (int) ((double) viewRectangle.width * scale / zoomFactor),
+                    (int) ((double) viewRectangle.height * scale / zoomFactor));
+            window.translate(vx, vy);
+            gr.setColor(new Color(200, 200, 200, 128));
+            gr.fill(window);
+            gr.setColor(Color.BLACK);
+            gr.drawRect(window.x, window.y, window.width - 1, window.height - 1);
+        }
+    }
+
+    @Override
+    public void mouseClicked(MouseEvent e) {
+    }
+
+    @Override
+    public void mousePressed(MouseEvent e) {
+        moveVisibleRect(e.getPoint());
+    }
+
+    @Override
+    public void mouseReleased(MouseEvent e) {
+        moveVisibleRect(e.getPoint());
+    }
+
+    @Override
+    public void mouseEntered(MouseEvent e) {
+    }
+
+    @Override
+    public void mouseExited(MouseEvent e) {
+    }
+
+    @Override
+    public void mouseDragged(MouseEvent e) {
+        moveVisibleRect(e.getPoint());
+    }
+
+    @Override
+    public void mouseMoved(MouseEvent e) {
+    }
+
+    private void moveVisibleRect(Point center) {
+        JComponent component = scene.getView();
+        if (component == null) {
+            return;
+        }
+        double zoomFactor = scene.getZoomFactor();
+        Rectangle bounds = scene.getBounds();
+        Dimension size = getSize();
+
+        double sx = bounds.width > 0 ? (double) size.width / bounds.width : 0.0;
+        double sy = bounds.width > 0 ? (double) size.height / bounds.height : 0.0;
+        double scale = Math.min(sx, sy);
+
+        int vw = (int) (scale * bounds.width);
+        int vh = (int) (scale * bounds.height);
+        int vx = (size.width - vw) / 2;
+        int vy = (size.height - vh) / 2;
+
+        int cx = (int) ((double) (center.x - vx) / scale * zoomFactor);
+        int cy = (int) ((double) (center.y - vy) / scale * zoomFactor);
+
+        Rectangle visibleRect = component.getVisibleRect();
+        visibleRect.x = cx - visibleRect.width / 2;
+        visibleRect.y = cy - visibleRect.height / 2;
+        component.scrollRectToVisible(visibleRect);
+
+    }
+
+    @Override
+    public void sceneRepaint() {
+    }
+
+    @Override
+    public void sceneValidating() {
+    }
+
+    @Override
+    public void sceneValidated() {
+    }
+
+    @Override
+    public void componentResized(ComponentEvent e) {
+        repaint();
+    }
+
+    @Override
+    public void componentMoved(ComponentEvent e) {
+        repaint();
+    }
+
+    @Override
+    public void componentShown(ComponentEvent e) {
+    }
+
+    @Override
+    public void componentHidden(ComponentEvent e) {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/src/com/sun/hotspot/igv/util/ExtendedSelectAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.util;
+
+import java.awt.event.MouseEvent;
+import javax.swing.JPanel;
+import org.netbeans.api.visual.action.ActionFactory;
+import org.netbeans.api.visual.action.SelectProvider;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.action.WidgetAction.State;
+import org.netbeans.api.visual.action.WidgetAction.WidgetKeyEvent;
+import org.netbeans.api.visual.action.WidgetAction.WidgetMouseEvent;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ExtendedSelectAction extends WidgetAction.Adapter {
+
+    private WidgetAction innerAction;
+    private JPanel panel;
+
+    public ExtendedSelectAction(SelectProvider provider) {
+        innerAction = ActionFactory.createSelectAction(provider);
+        panel = new JPanel();
+    }
+
+    @Override
+    public State mousePressed(Widget widget, WidgetMouseEvent event) {
+        // TODO: Solve this differently?
+        if (event.getButton() != MouseEvent.BUTTON2) {
+            return innerAction.mousePressed(widget, new WidgetMouseEvent(event.getEventID(), new MouseEvent(panel, (int) event.getEventID(), event.getWhen(), event.getModifiersEx(), event.getPoint().x, event.getPoint().y, event.getClickCount(), event.isPopupTrigger(), MouseEvent.BUTTON1)));
+        } else {
+            return super.mousePressed(widget, event);
+        }
+    }
+
+    @Override
+    public State mouseReleased(Widget widget, WidgetMouseEvent event) {
+        return innerAction.mouseReleased(widget, event);
+    }
+
+    @Override
+    public State keyTyped(Widget widget, WidgetKeyEvent event) {
+        return innerAction.keyTyped(widget, event);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/src/com/sun/hotspot/igv/util/PropertiesSheet.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1998, 2008, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.util;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Property;
+import java.lang.reflect.InvocationTargetException;
+import org.openide.nodes.Node;
+import org.openide.nodes.Sheet;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class PropertiesSheet {
+
+    public static void initializeSheet(final Properties properties, Sheet s) {
+
+        Sheet.Set set1 = Sheet.createPropertiesSet();
+        set1.setDisplayName("Properties");
+        for (final Property p : properties) {
+            Node.Property<String> prop = new Node.Property<String>(String.class) {
+
+                @Override
+                public boolean canRead() {
+                    return true;
+                }
+
+                @Override
+                public String getValue() throws IllegalAccessException, InvocationTargetException {
+                    return p.getValue();
+                }
+
+                @Override
+                public boolean canWrite() {
+                    return false;
+                }
+
+                @Override
+                public void setValue(String arg0) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+                    properties.setProperty(p.getName(), arg0);
+                }
+            };
+            prop.setName(p.getName());
+            set1.put(prop);
+        }
+        s.put(set1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/src/com/sun/hotspot/igv/util/RangeSlider.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,263 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.util;
+
+import com.sun.hotspot.igv.data.ChangedListener;
+import java.awt.*;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.util.List;
+import javax.swing.JComponent;
+
+public final class RangeSlider extends JComponent {
+
+    public static final int BAR_THICKNESS = 2;
+    public static final int BAR_CIRCLE_SIZE = 9;
+    public static final int MOUSE_ENDING_OFFSET = 3;
+    public static final Color BACKGROUND_COLOR = Color.white;
+    public static final Color BAR_COLOR = Color.black;
+    public static final Color BAR_SELECTION_COLOR = new Color(255, 0, 0, 120);
+    public static final Color TEXT_SELECTION_COLOR = new Color(200, 200, 200, 255);
+    public static final int ITEM_HEIGHT = 30;
+    public static final int ITEM_WIDTH = 30;
+    private RangeSliderModel model;
+    private Point startPoint;
+    private RangeSliderModel tempModel;
+    private Point lastMouseMove;
+
+    public RangeSlider(RangeSliderModel newModel) {
+        this.addMouseMotionListener(mouseMotionListener);
+        this.addMouseListener(mouseListener);
+        setModel(newModel);
+    }
+
+    private RangeSliderModel getPaintingModel() {
+        if (tempModel != null) {
+            return tempModel;
+        }
+        return model;
+    }
+
+    @Override
+    public Dimension getPreferredSize() {
+        if (getPaintingModel() != null) {
+            Graphics g = this.getGraphics();
+            int maxWidth = 0;
+            List<String> list = getPaintingModel().getPositions();
+            for (int i = 0; i < list.size(); i++) {
+                String curS = list.get(i);
+                if (curS != null && curS.length() > 0) {
+                    FontMetrics metrics = g.getFontMetrics();
+                    Rectangle bounds = metrics.getStringBounds(curS, g).getBounds();
+                    maxWidth = Math.max(maxWidth, (int) bounds.getWidth());
+                }
+            }
+            return new Dimension(maxWidth + ITEM_WIDTH, ITEM_HEIGHT * list.size());
+        }
+        return super.getPreferredSize();
+    }
+    private ChangedListener<RangeSliderModel> modelChangedListener = new ChangedListener<RangeSliderModel>() {
+
+        @Override
+        public void changed(RangeSliderModel source) {
+            update();
+        }
+    };
+
+    private void update() {
+        this.revalidate();
+        this.repaint();
+    }
+
+    private Rectangle getItemBounds(int index) {
+        Rectangle r = new Rectangle();
+        r.width = ITEM_WIDTH;
+        r.height = ITEM_HEIGHT;
+        r.x = 0;
+        r.y = ITEM_HEIGHT * index;
+        return r;
+    }
+
+    @Override
+    public void paint(Graphics g) {
+        super.paint(g);
+        Graphics2D g2 = (Graphics2D) g;
+        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                RenderingHints.VALUE_ANTIALIAS_ON);
+        int width = getWidth();
+        int height = getHeight();
+
+        g2.setColor(BACKGROUND_COLOR);
+        g2.fillRect(0, 0, width, height);
+
+        // Nothing to paint?
+        if (getPaintingModel() == null || getPaintingModel().getPositions().isEmpty()) {
+            return;
+        }
+
+        paintSelected(g2);
+        paintBar(g2);
+
+    }
+
+    private void fillRect(Graphics2D g, int startX, int startY, int endY, int thickness) {
+        g.fillRect(startX - thickness / 2, startY, thickness, endY - startY);
+    }
+
+    private void paintBar(Graphics2D g) {
+        List<String> list = getPaintingModel().getPositions();
+
+        g.setColor(BAR_COLOR);
+        Rectangle firstItemBounds = getItemBounds(0);
+        Rectangle lastItemBounds = getItemBounds(list.size() - 1);
+        fillRect(g, (int) firstItemBounds.getCenterX(), (int) firstItemBounds.getCenterY(), (int) lastItemBounds.getCenterY(), BAR_THICKNESS);
+
+        for (int i = 0; i < list.size(); i++) {
+            Rectangle curItemBounds = getItemBounds(i);
+            g.setColor(getPaintingModel().getColors().get(i));
+            g.fillOval((int) curItemBounds.getCenterX() - BAR_CIRCLE_SIZE / 2, (int) curItemBounds.getCenterY() - BAR_CIRCLE_SIZE / 2, BAR_CIRCLE_SIZE, BAR_CIRCLE_SIZE);
+            g.setColor(Color.black);
+            g.drawOval((int) curItemBounds.getCenterX() - BAR_CIRCLE_SIZE / 2, (int) curItemBounds.getCenterY() - BAR_CIRCLE_SIZE / 2, BAR_CIRCLE_SIZE, BAR_CIRCLE_SIZE);
+
+            String curS = list.get(i);
+            if (curS != null && curS.length() > 0) {
+                FontMetrics metrics = g.getFontMetrics();
+                Rectangle bounds = metrics.getStringBounds(curS, g).getBounds();
+                g.setColor(Color.black);
+                g.drawString(curS, curItemBounds.x + curItemBounds.width, (int) curItemBounds.getCenterY() + bounds.height / 2 - 2);
+            }
+        }
+
+    }
+
+    private void paintSelected(Graphics2D g) {
+        List<String> list = getPaintingModel().getPositions();
+        for (int i = 0; i < list.size(); i++) {
+            Rectangle curItemBounds = getItemBounds(i);
+            if (lastMouseMove != null && curItemBounds.y <= lastMouseMove.y && curItemBounds.y + curItemBounds.height > lastMouseMove.y) {
+                g.setColor(TEXT_SELECTION_COLOR);
+                g.fillRect(0, curItemBounds.y, getWidth(), curItemBounds.height);
+            }
+        }
+        final Rectangle barBounds = getBarBounds();
+
+        g.setColor(BAR_SELECTION_COLOR);
+        g.fill(barBounds);
+    }
+
+    private Rectangle getBarBounds() {
+        final Rectangle startItemBounds = getItemBounds(getPaintingModel().getFirstPosition());
+        final Rectangle endItemBounds = getItemBounds(getPaintingModel().getSecondPosition());
+        int startY = startItemBounds.y;
+        int endY = endItemBounds.y + endItemBounds.height;
+        return new Rectangle(0, startY, getWidth(), endY - startY);
+    }
+
+    private int getIndexFromPosition(int y) {
+        for (int i = 0; i < getPaintingModel().getPositions().size() - 1; i++) {
+            Rectangle bounds = getItemBounds(i);
+            if (bounds.y <= y && bounds.y + bounds.height >= y) {
+                return i;
+            }
+        }
+        return getPaintingModel().getPositions().size() - 1;
+    }
+    private final MouseMotionListener mouseMotionListener = new MouseMotionListener() {
+
+        @Override
+        public void mouseDragged(MouseEvent e) {
+            if (startPoint != null) {
+                int startIndex = getIndexFromPosition(startPoint.y);
+                int curIndex = getIndexFromPosition(e.getPoint().y);
+                tempModel.setPositions(startIndex, curIndex);
+            }
+        }
+
+        @Override
+        public void mouseMoved(MouseEvent e) {
+            lastMouseMove = e.getPoint();
+            update();
+        }
+    };
+    private final MouseListener mouseListener = new MouseListener() {
+
+        @Override
+        public void mouseClicked(MouseEvent e) {
+            if (model != null) {
+                int index = getIndexFromPosition(e.getPoint().y);
+                model.setPositions(index, index);
+            }
+        }
+
+        @Override
+        public void mousePressed(MouseEvent e) {
+            if (model != null) {
+                int index = getIndexFromPosition(e.getPoint().y);
+                startPoint = e.getPoint();
+                tempModel = model.copy();
+                tempModel.getChangedEvent().addListener(modelChangedListener);
+                tempModel.setPositions(index, index);
+            }
+        }
+
+        @Override
+        public void mouseReleased(MouseEvent e) {
+            if (tempModel != null) {
+                model.setPositions(tempModel.getFirstPosition(), tempModel.getSecondPosition());
+                tempModel = null;
+                startPoint = null;
+            }
+        }
+
+        @Override
+        public void mouseEntered(MouseEvent e) {
+        }
+
+        @Override
+        public void mouseExited(MouseEvent e) {
+            lastMouseMove = null;
+            repaint();
+        }
+    };
+
+    public RangeSliderModel getModel() {
+        return model;
+    }
+
+    public void setModel(RangeSliderModel newModel) {
+        if (newModel != this.model) {
+            if (this.model != null) {
+                this.model.getChangedEvent().removeListener(modelChangedListener);
+            }
+            this.model = newModel;
+            if (newModel != null) {
+                newModel.getChangedEvent().addListener(modelChangedListener);
+            }
+            this.tempModel = null;
+            update();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/Util/src/com/sun/hotspot/igv/util/RangeSliderModel.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 1998, 2008, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.sun.hotspot.igv.util;
+
+import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.data.ChangedEventProvider;
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class RangeSliderModel implements ChangedEventProvider<RangeSliderModel> {
+
+    // Warning: Update setData method if fields are added
+    private ChangedEvent<RangeSliderModel> changedEvent;
+    private List<String> positions;
+    private int firstPosition;
+    private int secondPosition;
+    private List<Color> colors;
+
+    public void setData(RangeSliderModel model) {
+        boolean changed = false;
+        changed |= (positions != model.positions);
+        positions = model.positions;
+        changed |= (firstPosition != model.firstPosition);
+        firstPosition = model.firstPosition;
+        changed |= (secondPosition != model.secondPosition);
+        secondPosition = model.secondPosition;
+        changed |= (colors != model.colors);
+        colors = model.colors;
+        if (changed) {
+            changedEvent.fire();
+        }
+    }
+
+    public RangeSliderModel(List<String> positions) {
+        assert positions.size() > 0;
+        this.changedEvent = new ChangedEvent<>(this);
+        setPositions(positions);
+    }
+
+    protected final void setPositions(List<String> positions) {
+        this.positions = positions;
+        colors = new ArrayList<>();
+        for (int i = 0; i < positions.size(); i++) {
+            colors.add(Color.black);
+        }
+        firstPosition = Math.min(firstPosition, positions.size() - 1);
+        secondPosition = Math.min(secondPosition, positions.size() - 1);
+        changedEvent.fire();
+    }
+
+    public void setColors(List<Color> colors) {
+        this.colors = colors;
+        changedEvent.fire();
+    }
+
+    public List<Color> getColors() {
+        return colors;
+    }
+
+    public RangeSliderModel copy() {
+        RangeSliderModel newModel = new RangeSliderModel(positions);
+        newModel.setData(this);
+        return newModel;
+    }
+
+    public List<String> getPositions() {
+        return Collections.unmodifiableList(positions);
+    }
+
+    public int getFirstPosition() {
+        return firstPosition;
+    }
+
+    public int getSecondPosition() {
+        return secondPosition;
+    }
+
+    public void setPositions(int fp, int sp) {
+        assert fp >= 0 && fp < positions.size();
+        assert sp >= 0 && sp < positions.size();
+        firstPosition = fp;
+        secondPosition = sp;
+        ensureOrder();
+        changedEvent.fire();
+    }
+
+    private void ensureOrder() {
+        if (secondPosition < firstPosition) {
+            int tmp = secondPosition;
+            secondPosition = firstPosition;
+            firstPosition = tmp;
+        }
+    }
+
+    @Override
+    public ChangedEvent<RangeSliderModel> getChangedEvent() {
+        return changedEvent;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.view" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.view.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/manifest.mf	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.view
+OpenIDE-Module-Layer: com/sun/hotspot/igv/view/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/view/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.view-impl" basedir="..">
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+        <condition>
+            <not>
+                <available file="${harness.dir}" type="dir"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=2de95ef6
+build.xml.script.CRC32=31afe4b1
+build.xml.stylesheet.CRC32=79c3b980
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=2de95ef6
+nbproject/build-impl.xml.script.CRC32=fa7a4119
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/nbproject/platform.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.javahelp,\
+    org.netbeans.modules.masterfs,\
+    org.netbeans.modules.options.keymap,\
+    org.netbeans.modules.sendopts,\
+    org.netbeans.modules.templates,\
+    org.openide.compat,\
+    org.openide.execution,\
+    org.openide.util.enumerations
+enabled.clusters=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.view</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.oracle.graal.visualizer.editor</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.oracle.graal.visualizer.sharedactions</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.difference</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.filter</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.hierarchicallayout</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.layout</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.settings</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.svg</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.api.visual</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>2.27.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.spi.quicksearch</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.actions</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.21.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.30.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.dialogs</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.18.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.loaders</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.20.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.nodes</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.20.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.39.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.sun.hotspot.igv.view</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/nbproject/suite.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/META-INF/services/com.oracle.graal.visualizer.editor.CompilationViewerFactory	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+com.sun.hotspot.igv.view.scene.GraphCompilationViewerFactory
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/com/sun/hotspot/igv/view/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=View
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/com/sun/hotspot/igv/view/actions/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,4 @@
+CTL_EditorAction=Open Editor Window
+CTL_EnableBlockLayoutAction=Enable block layout
+CTL_NodeFindAction=Find
+CTL_ExportAction=Export current graph...
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/com/sun/hotspot/igv/view/actions/ExpandPredecessorsAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.view.actions;
+
+import com.oracle.graal.visualizer.editor.EditorTopComponent;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CallableSystemAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class ExpandPredecessorsAction extends CallableSystemAction {
+
+    @Override
+    public void performAction() {
+        EditorTopComponent editor = EditorTopComponent.getActive();
+        if (editor != null) {
+            //editor.expandPredecessors();
+        }
+    }
+
+    @Override
+    public String getName() {
+        return "Expand Above";
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/com/sun/hotspot/igv/view/actions/ExpandSuccessorsAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.view.actions;
+
+import com.oracle.graal.visualizer.editor.EditorTopComponent;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CallableSystemAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class ExpandSuccessorsAction extends CallableSystemAction {
+
+    @Override
+    public void performAction() {
+        EditorTopComponent editor = EditorTopComponent.getActive();
+        if (editor != null) {
+            //editor.expandSuccessors();
+        }
+    }
+
+    @Override
+    public String getName() {
+        return "Expand Below";
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/com/sun/hotspot/igv/view/actions/ExtractAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.view.actions;
+
+import com.oracle.graal.visualizer.editor.EditorTopComponent;
+import java.awt.Event;
+import java.awt.event.KeyEvent;
+import javax.swing.Action;
+import javax.swing.KeyStroke;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionRegistration;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CallableSystemAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+@ActionID(id = "com.sun.hotspot.igv.view.actions.ExtractAction", category = "View")
+@ActionRegistration(displayName = "Extract nodes")
+@ActionReference(path = "Menu/View", position = 300)
+public final class ExtractAction extends CallableSystemAction {
+
+    @Override
+    public void performAction() {
+        EditorTopComponent editor = EditorTopComponent.getActive();
+        if (editor != null) {
+            //editor.extract();
+        }
+    }
+
+    public ExtractAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Extract current set of selected nodes");
+        putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_X, Event.CTRL_MASK, false));
+    }
+
+    @Override
+    public String getName() {
+        return "Extract action";
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/view/images/extract.gif";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/com/sun/hotspot/igv/view/actions/HideAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.view.actions;
+
+import com.oracle.graal.visualizer.editor.EditorTopComponent;
+import java.awt.Event;
+import java.awt.event.KeyEvent;
+import javax.swing.Action;
+import javax.swing.KeyStroke;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionRegistration;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CallableSystemAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+@ActionID(id = "com.sun.hotspot.igv.view.actions.HideAction", category = "View")
+@ActionRegistration(displayName = "Hide nodes")
+@ActionReference(path = "Menu/View", position = 400)
+public final class HideAction extends CallableSystemAction {
+
+    @Override
+    public void performAction() {
+        EditorTopComponent editor = EditorTopComponent.getActive();
+        if (editor != null) {
+            //editor.hideNodes();
+        }
+    }
+
+    public HideAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Hide selected nodes");
+        putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_H, Event.CTRL_MASK, false));
+    }
+
+    @Override
+    public String getName() {
+        return "Hide";
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/view/images/hide.gif";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/com/sun/hotspot/igv/view/actions/MouseOverAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.view.actions;
+
+import org.netbeans.api.visual.action.HoverProvider;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.action.WidgetAction.State;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class MouseOverAction extends WidgetAction.Adapter {
+
+    private long eventID = Integer.MIN_VALUE;
+    private HoverProvider provider;
+
+    public MouseOverAction(HoverProvider provider) {
+        this.provider = provider;
+    }
+
+    @Override
+    public State mouseMoved(Widget widget, WidgetMouseEvent event) {
+        long id = event.getEventID();
+        if (id != eventID) {
+            eventID = id;
+            provider.widgetHovered(widget);
+        }
+        return State.REJECTED;
+    }
+
+    @Override
+    public State mouseExited(Widget widget, WidgetMouseEvent event) {
+        provider.widgetHovered(null);
+        return State.REJECTED;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/com/sun/hotspot/igv/view/actions/PredSuccAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.view.actions;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import org.openide.util.ImageUtilities;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class PredSuccAction extends AbstractAction {
+
+    private boolean state;
+    public static final String STATE = "state";
+
+    public PredSuccAction() {
+        state = true;
+        putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource())));
+        putValue(STATE, true);
+        putValue(Action.SHORT_DESCRIPTION, "Show neighboring nodes of fully visible nodes semi-transparent");
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent ev) {
+        this.state = !state;
+        this.putValue(STATE, state);
+    }
+
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/view/images/predsucc.gif";
+    }
+}
Binary file visualizer/View/src/com/sun/hotspot/igv/view/images/blocks.gif has changed
Binary file visualizer/View/src/com/sun/hotspot/igv/view/images/expand.gif has changed
Binary file visualizer/View/src/com/sun/hotspot/igv/view/images/extract.gif has changed
Binary file visualizer/View/src/com/sun/hotspot/igv/view/images/hide.gif has changed
Binary file visualizer/View/src/com/sun/hotspot/igv/view/images/overview.png has changed
Binary file visualizer/View/src/com/sun/hotspot/igv/view/images/pan_mode.png has changed
Binary file visualizer/View/src/com/sun/hotspot/igv/view/images/predsucc.gif has changed
Binary file visualizer/View/src/com/sun/hotspot/igv/view/images/selection_mode.png has changed
Binary file visualizer/View/src/com/sun/hotspot/igv/view/images/zoom_in.png has changed
Binary file visualizer/View/src/com/sun/hotspot/igv/view/images/zoom_out.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/com/sun/hotspot/igv/view/layer.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
+<filesystem>
+    <folder name="CompilationViewer">
+        <folder name="Graph">
+            <folder name="Actions">
+                <file name="com-oracle-graal-visualizer-sharedactions-ShowAllAction.shadow">
+                    <attr name="originalFile" stringvalue="Actions/View/com-oracle-graal-visualizer-sharedactions-ShowAllAction.instance"/>
+                </file>
+                <file name="com-oracle-graal-visualizer-sharedactions-ZoomInAction.shadow">
+                    <attr name="originalFile" stringvalue="Actions/View/com-oracle-graal-visualizer-sharedactions-ZoomInAction.instance"/>
+                </file>
+                <file name="com-oracle-graal-visualizer-sharedactions-ZoomOutAction.shadow">
+                    <attr name="originalFile" stringvalue="Actions/View/com-oracle-graal-visualizer-sharedactions-ZoomOutAction.instance"/>
+                </file>
+                <file name="com-oracle-graal-visualizer-sharedactions-ExportSVGAction.shadow">
+                    <attr name="originalFile" stringvalue="Actions/File/com-oracle-graal-visualizer-sharedactions-ExportSVGAction.instance"/>
+                </file>
+            </folder>
+        </folder>
+    </folder>
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/com/sun/hotspot/igv/view/scene/CustomizablePanWidgetAction.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,146 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package com.sun.hotspot.igv.view.scene;
+
+import java.awt.Container;
+import java.awt.Point;
+import java.awt.Rectangle;
+import javax.swing.JComponent;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.action.WidgetAction.State;
+import org.netbeans.api.visual.action.WidgetAction.WidgetMouseEvent;
+import org.netbeans.api.visual.widget.Scene;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ * @author David Kaspar
+ * @author Peter Hofer
+ */
+public class CustomizablePanWidgetAction extends WidgetAction.LockedAdapter {
+    private boolean enabled = true;
+    
+    private Scene scene;
+    private JScrollPane scrollPane;
+    private Point lastLocation;
+    
+    private final int modifiersExMask;
+    private final int modifiersEx;
+
+    public CustomizablePanWidgetAction(int modifiersExMask, int modifiersEx) {
+        this.modifiersExMask = modifiersExMask;
+        this.modifiersEx = modifiersEx;
+    }
+
+    @Override
+    protected boolean isLocked() {
+        return scrollPane != null;
+    }
+    
+    public void setEnabled(boolean enabled) {
+        if (this.enabled != enabled) {
+            if (isLocked())
+                throw new IllegalStateException();
+            
+            this.enabled = enabled;
+        }
+    }
+
+    @Override
+    public State mousePressed (Widget widget, WidgetMouseEvent event) {
+        if (isLocked ())
+            return State.createLocked (widget, this);
+        if (enabled && (event.getModifiersEx() & modifiersExMask) == modifiersEx) {
+            scene = widget.getScene ();
+            scrollPane = findScrollPane (scene.getView ());
+            if (scrollPane != null) {
+                lastLocation = scene.convertSceneToView (widget.convertLocalToScene (event.getPoint ()));
+                SwingUtilities.convertPointToScreen (lastLocation, scene.getView ());
+                return State.createLocked (widget, this);
+            }
+        }
+        return State.REJECTED;
+    }
+
+    private JScrollPane findScrollPane (JComponent component) {
+        for (;;) {
+            if (component == null)
+                return null;
+            if (component instanceof JScrollPane)
+                return ((JScrollPane) component);
+            Container parent = component.getParent ();
+            if (! (parent instanceof JComponent))
+                return null;
+            component = (JComponent) parent;
+        }
+    }
+
+    @Override
+    public State mouseReleased (Widget widget, WidgetMouseEvent event) {
+        boolean state = pan (widget, event.getPoint ());
+        if (state)
+            scrollPane = null;
+        return state ? State.createLocked (widget, this) : State.REJECTED;
+    }
+
+    @Override
+    public State mouseDragged (Widget widget, WidgetMouseEvent event) {
+        return pan (widget, event.getPoint ()) ? State.createLocked (widget, this) : State.REJECTED;
+    }
+
+    private boolean pan (Widget widget, Point newLocation) {
+        if (scrollPane == null  ||  scene != widget.getScene ())
+            return false;
+        newLocation = scene.convertSceneToView (widget.convertLocalToScene (newLocation));
+        SwingUtilities.convertPointToScreen (newLocation, scene.getView ());
+        JComponent view = scene.getView ();
+        Rectangle rectangle = view.getVisibleRect ();
+        rectangle.x += lastLocation.x - newLocation.x;
+        rectangle.y += lastLocation.y - newLocation.y;
+        view.scrollRectToVisible (rectangle);
+        lastLocation = newLocation;
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/com/sun/hotspot/igv/view/scene/DiagramScene.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,964 @@
+/*
+ * 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.sun.hotspot.igv.view.scene;
+
+import com.oracle.graal.visualizer.editor.DiagramViewModel;
+import com.oracle.graal.visualizer.sharedactions.ExportSVGCookie;
+import com.oracle.graal.visualizer.sharedactions.ZoomCookie;
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.data.Pair;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.graph.*;
+import com.sun.hotspot.igv.hierarchicallayout.HierarchicalLayoutManager;
+import com.sun.hotspot.igv.layout.LayoutGraph;
+import com.sun.hotspot.igv.util.ColorIcon;
+import com.sun.hotspot.igv.util.DoubleClickAction;
+import com.sun.hotspot.igv.util.PropertiesSheet;
+import com.sun.hotspot.igv.view.widgets.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.List;
+import java.util.*;
+import javax.swing.*;
+import org.netbeans.api.visual.action.*;
+import org.netbeans.api.visual.animator.SceneAnimator;
+import org.netbeans.api.visual.layout.LayoutFactory;
+import org.netbeans.api.visual.model.*;
+import org.netbeans.api.visual.widget.LayerWidget;
+import org.netbeans.api.visual.widget.Widget;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Sheet;
+import org.openide.util.Lookup;
+import org.openide.util.lookup.AbstractLookup;
+import org.openide.util.lookup.InstanceContent;
+
+public class DiagramScene extends ObjectScene implements ExportSVGCookie, ZoomCookie {
+
+    private CustomizablePanWidgetAction panAction;
+    private WidgetAction hoverAction;
+    private WidgetAction selectAction;
+    private Lookup lookup;
+    private InstanceContent content;
+    private Action[] actions;
+    private LayerWidget connectionLayer;
+    private JScrollPane scrollPane;
+    private LayerWidget mainLayer;
+    private LayerWidget blockLayer;
+    private Widget topLeft;
+    private Widget bottomRight;
+    private DiagramViewModel model;
+    private WidgetAction zoomAction;
+    private boolean rebuilding;
+    /**
+     * The alpha level of partially visible figures.
+     */
+    public static final float ALPHA = 0.4f;
+    /**
+     * The offset of the graph to the border of the window showing it.
+     */
+    public static final int BORDER_SIZE = 20;
+    public static final int UNDOREDO_LIMIT = 100;
+    public static final int SCROLL_UNIT_INCREMENT = 80;
+    public static final int SCROLL_BLOCK_INCREMENT = 400;
+    public static final float ZOOM_MAX_FACTOR = 3.0f;
+    public static final float ZOOM_MIN_FACTOR = 0.0f;//0.15f;
+    public static final float ZOOM_INCREMENT = 1.5f;
+    public static final int SLOT_OFFSET = 6;
+    public static final int ANIMATION_LIMIT = 40;
+    private PopupMenuProvider popupMenuProvider = new PopupMenuProvider() {
+
+        @Override
+        public JPopupMenu getPopupMenu(Widget widget, Point localLocation) {
+            return DiagramScene.this.createPopupMenu();
+        }
+    };
+    private RectangularSelectDecorator rectangularSelectDecorator = new RectangularSelectDecorator() {
+
+        @Override
+        public Widget createSelectionWidget() {
+            Widget widget = new Widget(DiagramScene.this);
+            widget.setBorder(BorderFactory.createLineBorder(Color.black, 2));
+            widget.setForeground(Color.red);
+            return widget;
+        }
+    };
+
+    @SuppressWarnings("unchecked")
+    public <T> T getWidget(Object o) {
+        Widget w = this.findWidget(o);
+        return (T) w;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T getWidget(Object o, Class<T> klass) {
+        Widget w = this.findWidget(o);
+        return (T) w;
+    }
+
+    public void zoomOut() {
+        double zoom = getZoomFactor();
+        Point viewPosition = getScrollPane().getViewport().getViewPosition();
+        double newZoom = zoom / DiagramScene.ZOOM_INCREMENT;
+        if (newZoom > DiagramScene.ZOOM_MIN_FACTOR) {
+            setZoomFactor(newZoom);
+            validate();
+            getScrollPane().getViewport().setViewPosition(new Point((int) (viewPosition.x / DiagramScene.ZOOM_INCREMENT), (int) (viewPosition.y / DiagramScene.ZOOM_INCREMENT)));
+        }
+    }
+
+    public void zoomIn() {
+
+        double zoom = getZoomFactor();
+        Point viewPosition = getScrollPane().getViewport().getViewPosition();
+        double newZoom = zoom * DiagramScene.ZOOM_INCREMENT;
+        if (newZoom < DiagramScene.ZOOM_MAX_FACTOR) {
+            setZoomFactor(newZoom);
+            validate();
+            getScrollPane().getViewport().setViewPosition(new Point((int) (viewPosition.x * DiagramScene.ZOOM_INCREMENT), (int) (viewPosition.y * DiagramScene.ZOOM_INCREMENT)));
+        }
+    }
+
+    private void centerFigures(Collection<Figure> list) {
+        gotoFigures(list);
+    }
+
+    private RectangularSelectProvider rectangularSelectProvider = new RectangularSelectProvider() {
+
+        @Override
+        public void performSelection(Rectangle rectangle) {
+            if (rectangle.width < 0) {
+                rectangle.x += rectangle.width;
+                rectangle.width *= -1;
+            }
+
+            if (rectangle.height < 0) {
+                rectangle.y += rectangle.height;
+                rectangle.height *= -1;
+            }
+
+            Set<Object> selectedObjects = new HashSet<>();
+            for (Figure f : getModel().getDiagramToView().getFigures()) {
+                FigureWidget w = getWidget(f);
+                if (w != null) {
+                    Rectangle r = new Rectangle(w.getBounds());
+                    r.setLocation(w.getLocation());
+
+                    if (r.intersects(rectangle)) {
+                        selectedObjects.add(f);
+                    }
+
+                    for (Slot s : f.getSlots()) {
+                        SlotWidget sw = getWidget(s);
+                        Rectangle r2 = new Rectangle(sw.getBounds());
+                        r2.setLocation(sw.convertLocalToScene(new Point(0, 0)));
+
+                        if (r2.intersects(rectangle)) {
+                            selectedObjects.add(s);
+                        }
+                    }
+                } else {
+                    assert false : "w should not be null here!";
+                }
+            }
+
+            setSelectedObjects(selectedObjects);
+        }
+    };
+    private MouseWheelListener mouseWheelListener = new MouseWheelListener() {
+
+        @Override
+        public void mouseWheelMoved(MouseWheelEvent e) {
+            if (e.isControlDown()) {
+                DiagramScene.this.relayoutWithoutLayout(null);
+            }
+        }
+    };
+
+    public Point getScrollPosition() {
+        return getScrollPane().getViewport().getViewPosition();
+    }
+
+    public void setScrollPosition(Point p) {
+        getScrollPane().getViewport().setViewPosition(p);
+    }
+
+    private JScrollPane createScrollPane() {
+        JComponent comp = this.createView();
+        comp.setDoubleBuffered(true);
+        comp.setBackground(Color.WHITE);
+        comp.setOpaque(true);
+        this.setBackground(Color.WHITE);
+        this.setOpaque(true);
+        JScrollPane result = new JScrollPane(comp);
+        result.setBackground(Color.WHITE);
+        result.getVerticalScrollBar().setUnitIncrement(SCROLL_UNIT_INCREMENT);
+        result.getVerticalScrollBar().setBlockIncrement(SCROLL_BLOCK_INCREMENT);
+        result.getHorizontalScrollBar().setUnitIncrement(SCROLL_UNIT_INCREMENT);
+        result.getHorizontalScrollBar().setBlockIncrement(SCROLL_BLOCK_INCREMENT);
+        return result;
+    }
+    private ObjectSceneListener selectionChangedListener = new ObjectSceneListener() {
+
+        @Override
+        public void objectAdded(ObjectSceneEvent arg0, Object arg1) {
+        }
+
+        @Override
+        public void objectRemoved(ObjectSceneEvent arg0, Object arg1) {
+        }
+
+        @Override
+        public void objectStateChanged(ObjectSceneEvent e, Object o, ObjectState oldState, ObjectState newState) {
+        }
+
+        @Override
+        public void selectionChanged(ObjectSceneEvent e, Set<Object> oldSet, Set<Object> newSet) {
+            DiagramScene scene = (DiagramScene) e.getObjectScene();
+            if (scene.isRebuilding()) {
+                return;
+            }
+
+            content.set(newSet, null);
+
+            Set<Integer> nodeSelection = new HashSet<>();
+            for (Object o : newSet) {
+                if (o instanceof Properties.Provider) {
+                    final Properties.Provider provider = (Properties.Provider) o;
+                    AbstractNode node = new AbstractNode(Children.LEAF) {
+
+                        @Override
+                        protected Sheet createSheet() {
+                            Sheet s = super.createSheet();
+                            PropertiesSheet.initializeSheet(provider.getProperties(), s);
+                            return s;
+                        }
+                    };
+                    node.setDisplayName(provider.getProperties().get("name"));
+                    content.add(node);
+                }
+
+
+                if (o instanceof Figure) {
+                    nodeSelection.addAll(((Figure) o).getSource().getSourceNodesAsSet());
+                } else if (o instanceof Slot) {
+                    nodeSelection.addAll(((Slot) o).getSource().getSourceNodesAsSet());
+                }
+            }
+            getModel().setSelectedNodes(nodeSelection);
+        }
+
+        @Override
+        public void highlightingChanged(ObjectSceneEvent e, Set<Object> oldSet, Set<Object> newSet) {
+            Set<Integer> nodeHighlighting = new HashSet<>();
+            for (Object o : newSet) {
+                if (o instanceof Figure) {
+                    nodeHighlighting.addAll(((Figure) o).getSource().getSourceNodesAsSet());
+                } else if (o instanceof Slot) {
+                    nodeHighlighting.addAll(((Slot) o).getSource().getSourceNodesAsSet());
+                }
+            }
+//            boolean b = highlightedCoordinatorListener.isEnabled();
+//            highlightedCoordinatorListener.setEnabled(false);
+//            SelectionCoordinator.getInstance().setHighlightedObjects(nodeHighlighting);
+//            highlightedCoordinatorListener.setEnabled(b);
+            validate();
+        }
+
+        @Override
+        public void hoverChanged(ObjectSceneEvent e, Object oldObject, Object newObject) {
+            Set<Object> newHighlightedObjects = new HashSet<>(DiagramScene.this.getHighlightedObjects());
+            if (oldObject != null) {
+                newHighlightedObjects.remove(oldObject);
+            }
+            if (newObject != null) {
+                newHighlightedObjects.add(newObject);
+            }
+            DiagramScene.this.setHighlightedObjects(newHighlightedObjects);
+        }
+
+        @Override
+        public void focusChanged(ObjectSceneEvent arg0, Object arg1, Object arg2) {
+        }
+    };
+
+    public void setActions(Action[] actions) {
+        this.actions = actions;
+    }
+    
+    
+
+    public DiagramScene(DiagramViewModel model) {
+
+        this.model = model;
+        content = new InstanceContent();
+        lookup = new AbstractLookup(content);
+        content.add(this);
+
+        this.setCheckClipping(true);
+
+        scrollPane = createScrollPane();
+
+        hoverAction = createObjectHoverAction();
+
+        // This panAction handles the event only when the left mouse button is
+        // pressed without any modifier keys, otherwise it will not consume it
+        // and the selection action (below) will handle the event
+        panAction = new CustomizablePanWidgetAction(~0, MouseEvent.BUTTON1_DOWN_MASK);
+        this.getActions().addAction(panAction);
+
+        selectAction = createSelectAction();
+        this.getActions().addAction(selectAction);
+
+        blockLayer = new LayerWidget(this);
+        this.addChild(blockLayer);
+
+        mainLayer = new LayerWidget(this);
+        this.addChild(mainLayer);
+
+        topLeft = new Widget(this);
+        topLeft.setPreferredLocation(new Point(-BORDER_SIZE, -BORDER_SIZE));
+        this.addChild(topLeft);
+
+        bottomRight = new Widget(this);
+        bottomRight.setPreferredLocation(new Point(-BORDER_SIZE, -BORDER_SIZE));
+        this.addChild(bottomRight);
+
+        connectionLayer = new LayerWidget(this);
+        this.addChild(connectionLayer);
+
+        LayerWidget selectionLayer = new LayerWidget(this);
+        this.addChild(selectionLayer);
+
+        this.setLayout(LayoutFactory.createAbsoluteLayout());
+
+        this.getInputBindings().setZoomActionModifiers(KeyEvent.CTRL_MASK);
+        zoomAction = ActionFactory.createMouseCenteredZoomAction(1.2);
+        this.getActions().addAction(zoomAction);
+        this.getView().addMouseWheelListener(mouseWheelListener);
+        this.getActions().addAction(ActionFactory.createPopupMenuAction(popupMenuProvider));
+
+        this.getActions().addAction(ActionFactory.createWheelPanAction());
+
+        LayerWidget selectLayer = new LayerWidget(this);
+        this.addChild(selectLayer);
+        this.getActions().addAction(ActionFactory.createRectangularSelectAction(rectangularSelectDecorator, selectLayer, rectangularSelectProvider));
+
+        this.addObjectSceneListener(selectionChangedListener, ObjectSceneEventType.OBJECT_SELECTION_CHANGED, ObjectSceneEventType.OBJECT_HIGHLIGHTING_CHANGED, ObjectSceneEventType.OBJECT_HOVER_CHANGED);
+        
+        update();
+    }
+
+    public DiagramViewModel getModel() {
+        return model;
+    }
+
+    public JScrollPane getScrollPane() {
+        return scrollPane;
+    }
+
+    Component getComponent() {
+        return scrollPane;
+    }
+
+    public boolean isAllVisible() {
+        return getModel().getHiddenNodes().isEmpty();
+    }
+
+    public Action createGotoAction(final Figure f) {
+        final DiagramScene diagramScene = this;
+        Action a = new AbstractAction() {
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                diagramScene.gotoFigure(f);
+            }
+        };
+
+        a.setEnabled(true);
+        a.putValue(Action.SMALL_ICON, new ColorIcon(f.getColor()));
+        String name = f.getLines()[0];
+
+        name += " (";
+
+        if (!this.getWidget(f, FigureWidget.class).isVisible()) {
+            name += "hidden";
+        }
+        name += ")";
+        a.putValue(Action.NAME, name);
+        return a;
+    }
+
+    private void update() {
+        mainLayer.removeChildren();
+        blockLayer.removeChildren();
+
+        rebuilding = true;
+
+        Collection<Object> objects = new ArrayList<>(this.getObjects());
+        for (Object o : objects) {
+            this.removeObject(o);
+        }
+
+        Diagram d = getModel().getDiagramToView();
+
+        for (Figure f : d.getFigures()) {
+            FigureWidget w = new FigureWidget(f, hoverAction, selectAction, this, mainLayer);
+            w.getActions().addAction(ActionFactory.createPopupMenuAction(w));
+            w.getActions().addAction(selectAction);
+            w.getActions().addAction(hoverAction);
+            w.setVisible(false);
+
+            this.addObject(f, w);
+
+            for (InputSlot s : f.getInputSlots()) {
+                SlotWidget sw = new InputSlotWidget(s, this, w, w);
+                addObject(s, sw);
+                sw.getActions().addAction(new DoubleClickAction(sw));
+                sw.getActions().addAction(hoverAction);
+                sw.getActions().addAction(selectAction);
+            }
+
+            for (OutputSlot s : f.getOutputSlots()) {
+                SlotWidget sw = new OutputSlotWidget(s, this, w, w);
+                addObject(s, sw);
+                sw.getActions().addAction(new DoubleClickAction(sw));
+                sw.getActions().addAction(hoverAction);
+                sw.getActions().addAction(selectAction);
+            }
+        }
+
+        rebuilding = false;
+        this.smallUpdate(true);
+    }
+
+    public boolean isRebuilding() {
+        return rebuilding;
+    }
+
+    private void smallUpdate(boolean relayout) {
+
+        this.updateHiddenNodes(model.getHiddenNodes(), relayout);
+        this.validate();
+    }
+
+    private boolean isVisible(Connection c) {
+        FigureWidget w1 = getWidget(c.getInputSlot().getFigure());
+        FigureWidget w2 = getWidget(c.getOutputSlot().getFigure());
+
+        if (w1.isVisible() && w2.isVisible()) {
+            return true;
+        }
+
+        return false;
+    }
+
+    private void relayout(Set<Widget> oldVisibleWidgets) {
+        System.out.println("relayout called with old visible widgets: " + oldVisibleWidgets);
+
+        Diagram diagram = getModel().getDiagramToView();
+
+        HashSet<Figure> figures = new HashSet<>();
+
+        for (Figure f : diagram.getFigures()) {
+            FigureWidget w = getWidget(f);
+            if (w.isVisible()) {
+                figures.add(f);
+            }
+        }
+
+        HashSet<Connection> edges = new HashSet<>();
+
+        for (Connection c : diagram.getConnections()) {
+            if (isVisible(c)) {
+                edges.add(c);
+            }
+        }
+
+        HierarchicalLayoutManager manager = new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS);
+        manager.setMaxLayerLength(10);
+        manager.doLayout(new LayoutGraph(edges, figures));
+        relayoutWithoutLayout(oldVisibleWidgets);
+    }
+    private Set<Pair<Point, Point>> lineCache = new HashSet<>();
+
+    private void relayoutWithoutLayout(Set<Widget> oldVisibleWidgets) {
+
+        System.out.println("relayout without layout with visible widgets: " + oldVisibleWidgets);
+
+        Diagram diagram = getModel().getDiagramToView();
+
+        int maxX = -BORDER_SIZE;
+        int maxY = -BORDER_SIZE;
+        for (Figure f : diagram.getFigures()) {
+            FigureWidget w = getWidget(f);
+            if (w.isVisible()) {
+                Point p = f.getPosition();
+                Dimension d = f.getSize();
+                maxX = Math.max(maxX, p.x + d.width);
+                maxY = Math.max(maxY, p.y + d.height);
+            }
+        }
+
+        for (Connection c : diagram.getConnections()) {
+            List<Point> points = c.getControlPoints();
+            FigureWidget w1 = getWidget((Figure) c.getTo().getVertex());
+            FigureWidget w2 = getWidget((Figure) c.getFrom().getVertex());
+            if (w1.isVisible() && w2.isVisible()) {
+                for (Point p : points) {
+                    if (p != null) {
+                        maxX = Math.max(maxX, p.x);
+                        maxY = Math.max(maxY, p.y);
+                    }
+                }
+            }
+        }
+
+        bottomRight.setPreferredLocation(new Point(maxX + BORDER_SIZE, maxY + BORDER_SIZE));
+        int offx = 0;
+        int offy = 0;
+        int curWidth = maxX + 2 * BORDER_SIZE;
+        int curHeight = maxY + 2 * BORDER_SIZE;
+
+        Rectangle bounds = this.getScrollPane().getBounds();
+        bounds.width /= getZoomFactor();
+        bounds.height /= getZoomFactor();
+        if (curWidth < bounds.width) {
+            offx = (bounds.width - curWidth) / 2;
+        }
+
+        if (curHeight < bounds.height) {
+            offy = (bounds.height - curHeight) / 2;
+        }
+
+        final int offx2 = offx;
+        final int offy2 = offy;
+
+        SceneAnimator animator = this.getSceneAnimator();
+        connectionLayer.removeChildren();
+        int visibleFigureCount = 0;
+        for (Figure f : diagram.getFigures()) {
+            if (getWidget(f, FigureWidget.class).isVisible()) {
+                visibleFigureCount++;
+            }
+        }
+
+
+        Set<Pair<Point, Point>> lastLineCache = lineCache;
+        lineCache = new HashSet<>();
+        for (Figure f : diagram.getFigures()) {
+            for (OutputSlot s : f.getOutputSlots()) {
+                SceneAnimator anim = animator;
+                if (visibleFigureCount > ANIMATION_LIMIT || oldVisibleWidgets == null) {
+                    anim = null;
+                }
+                processOutputSlot(lastLineCache, s, s.getConnections(), 0, null, null, offx2, offy2, anim);
+            }
+        }
+
+        for (Figure f : diagram.getFigures()) {
+            FigureWidget w = getWidget(f);
+            if (w.isVisible()) {
+                Point p = f.getPosition();
+                Point p2 = new Point(p.x + offx2, p.y + offy2);
+                if ((visibleFigureCount <= ANIMATION_LIMIT && oldVisibleWidgets != null && oldVisibleWidgets.contains(w))) {
+                    animator.animatePreferredLocation(w, p2);
+                } else {
+                    w.setPreferredLocation(p2);
+                    animator.animatePreferredLocation(w, p2);
+                }
+            }
+        }
+
+        this.validate();
+    }
+    private final Point specialNullPoint = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
+
+    private void processOutputSlot(Set<Pair<Point, Point>> lastLineCache, OutputSlot s, List<Connection> connections, int controlPointIndex, Point lastPoint, LineWidget predecessor, int offx, int offy, SceneAnimator animator) {
+        Map<Point, List<Connection>> pointMap = new HashMap<>(connections.size());
+
+        for (Connection c : connections) {
+
+            if (!isVisible(c)) {
+                continue;
+            }
+
+            List<Point> controlPoints = c.getControlPoints();
+            if (controlPointIndex >= controlPoints.size()) {
+                continue;
+            }
+
+            Point cur = controlPoints.get(controlPointIndex);
+            if (cur == null) {
+                cur = specialNullPoint;
+            } else if (controlPointIndex == 0 && !s.shouldShowName()) {
+                cur = new Point(cur.x, cur.y - SLOT_OFFSET);
+            } else if (controlPointIndex == controlPoints.size() - 1 && !c.getInputSlot().shouldShowName()) {
+                cur = new Point(cur.x, cur.y + SLOT_OFFSET);
+            }
+
+            if (pointMap.containsKey(cur)) {
+                pointMap.get(cur).add(c);
+            } else {
+                List<Connection> newList = new ArrayList<>(2);
+                newList.add(c);
+                pointMap.put(cur, newList);
+            }
+
+        }
+
+        for (Point p : pointMap.keySet()) {
+            List<Connection> connectionList = pointMap.get(p);
+
+            boolean isBold = false;
+            boolean isDashed = true;
+
+            for (Connection c : connectionList) {
+
+                if (c.getStyle() == Connection.ConnectionStyle.BOLD) {
+                    isBold = true;
+                }
+
+                if (c.getStyle() != Connection.ConnectionStyle.DASHED) {
+                    isDashed = false;
+                }
+            }
+
+            LineWidget newPredecessor = predecessor;
+            if (p == specialNullPoint) {
+            } else if (lastPoint == specialNullPoint) {
+            } else if (lastPoint != null) {
+                Point p1 = new Point(lastPoint.x + offx, lastPoint.y + offy);
+                Point p2 = new Point(p.x + offx, p.y + offy);
+
+                Pair<Point, Point> curPair = new Pair<>(p1, p2);
+                SceneAnimator curAnimator = animator;
+                if (lastLineCache.contains(curPair)) {
+                    curAnimator = null;
+                }
+                LineWidget w = new LineWidget(this, s, connectionList, p1, p2, predecessor, curAnimator, isBold, isDashed);
+                lineCache.add(curPair);
+
+                newPredecessor = w;
+                connectionLayer.addChild(w);
+                w.getActions().addAction(hoverAction);
+            }
+
+            processOutputSlot(lastLineCache, s, connectionList, controlPointIndex + 1, p, newPredecessor, offx, offy, animator);
+        }
+    }
+
+    @Override
+    public Lookup getLookup() {
+        return lookup;
+    }
+
+    private void gotoFigures(final Collection<Figure> figures) {
+        Rectangle overall = null;
+        getModel().showFigures(figures);
+        for (Figure f : figures) {
+
+            FigureWidget fw = getWidget(f);
+            if (fw != null) {
+                Rectangle r = fw.getBounds();
+                Point p = fw.getLocation();
+                Rectangle r2 = new Rectangle(p.x, p.y, r.width, r.height);
+
+                if (overall == null) {
+                    overall = r2;
+                } else {
+                    overall = overall.union(r2);
+                }
+            }
+        }
+        if (overall != null) {
+            centerRectangle(overall);
+        }
+    }
+
+    private Set<Object> idSetToObjectSet(Set<Object> ids) {
+
+        Set<Object> result = new HashSet<>();
+        for (Figure f : getModel().getDiagramToView().getFigures()) {
+            if (DiagramScene.doesIntersect(f.getSource().getSourceNodesAsSet(), ids)) {
+                result.add(f);
+            }
+
+            for (Slot s : f.getSlots()) {
+                if (DiagramScene.doesIntersect(s.getSource().getSourceNodesAsSet(), ids)) {
+                    result.add(s);
+                }
+            }
+        }
+        return result;
+    }
+
+    public void gotoSelection(Set<Object> ids) {
+
+        Rectangle overall = null;
+        Set<Integer> hiddenNodes = new HashSet<>(this.getModel().getHiddenNodes());
+        hiddenNodes.removeAll(ids);
+        this.getModel().showNot(hiddenNodes);
+
+        Set<Object> objects = idSetToObjectSet(ids);
+        for (Object o : objects) {
+
+            Widget w = getWidget(o);
+            if (w != null) {
+                Rectangle r = w.getBounds();
+                Point p = w.convertLocalToScene(new Point(0, 0));
+
+                Rectangle r2 = new Rectangle(p.x, p.y, r.width, r.height);
+
+                if (overall == null) {
+                    overall = r2;
+                } else {
+                    overall = overall.union(r2);
+                }
+            }
+        }
+        if (overall != null) {
+            centerRectangle(overall);
+        }
+
+        setSelectedObjects(objects);
+    }
+
+    private Point calcCenter(Rectangle r) {
+
+        Point center = new Point((int) r.getCenterX(), (int) r.getCenterY());
+        center.x -= getScrollPane().getViewport().getViewRect().width / 2;
+        center.y -= getScrollPane().getViewport().getViewRect().height / 2;
+
+        // Ensure to be within area
+        center.x = Math.max(0, center.x);
+        center.x = Math.min(getScrollPane().getViewport().getViewSize().width - getScrollPane().getViewport().getViewRect().width, center.x);
+        center.y = Math.max(0, center.y);
+        center.y = Math.min(getScrollPane().getViewport().getViewSize().height - getScrollPane().getViewport().getViewRect().height, center.y);
+
+        return center;
+    }
+
+    private void centerRectangle(Rectangle r) {
+
+        if (getScrollPane().getViewport().getViewRect().width == 0 || getScrollPane().getViewport().getViewRect().height == 0) {
+            return;
+        }
+
+        Rectangle r2 = new Rectangle(r.x, r.y, r.width, r.height);
+        r2 = convertSceneToView(r2);
+
+        double factorX = (double) r2.width / (double) getScrollPane().getViewport().getViewRect().width;
+        double factorY = (double) r2.height / (double) getScrollPane().getViewport().getViewRect().height;
+        double factor = Math.max(factorX, factorY);
+        if (factor >= 1.0) {
+            Point p = getScrollPane().getViewport().getViewPosition();
+            setZoomFactor(getZoomFactor() / factor);
+            r2.x /= factor;
+            r2.y /= factor;
+            r2.width /= factor;
+            r2.height /= factor;
+            getScrollPane().getViewport().setViewPosition(calcCenter(r2));
+        } else {
+            getScrollPane().getViewport().setViewPosition(calcCenter(r2));
+        }
+    }
+
+    void setSelection(Collection<Figure> list) {
+        super.setSelectedObjects(new HashSet<>(list));
+        centerFigures(list);
+    }
+
+    private boolean isVisible(Figure f) {
+        for (Integer n : f.getSource().getSourceNodesAsSet()) {
+            if (getModel().getHiddenNodes().contains(n)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static boolean doesIntersect(Set<?> s1, Set<?> s2) {
+        if (s1.size() > s2.size()) {
+            Set<?> tmp = s1;
+            s1 = s2;
+            s2 = tmp;
+        }
+
+        for (Object o : s1) {
+            if (s2.contains(o)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private void updateHiddenNodes(Set<Integer> newHiddenNodes, boolean doRelayout) {
+
+        System.out.println("newHiddenNodes: " + newHiddenNodes);
+
+        Diagram diagram = getModel().getDiagramToView();
+        assert diagram != null;
+
+        Set<Widget> oldVisibleWidgets = new HashSet<>();
+
+        for (Figure f : diagram.getFigures()) {
+            FigureWidget w = getWidget(f);
+            if (w != null && w.isVisible()) {
+                oldVisibleWidgets.add(w);
+            }
+        }
+
+        for (Figure f : diagram.getFigures()) {
+            boolean hiddenAfter = doesIntersect(f.getSource().getSourceNodesAsSet(), newHiddenNodes);
+
+            FigureWidget w = getWidget(f);
+            w.setBoundary(false);
+            if (!hiddenAfter) {
+                // Figure is shown
+                w.setVisible(true);
+            } else {
+                // Figure is hidden
+                w.setVisible(false);
+            }
+        }
+
+        if (getModel().getShowNodeHull()) {
+            List<FigureWidget> boundaries = new ArrayList<>();
+            for (Figure f : diagram.getFigures()) {
+                FigureWidget w = getWidget(f);
+                if (!w.isVisible()) {
+                    Set<Figure> set = new HashSet<>(f.getPredecessorSet());
+                    set.addAll(f.getSuccessorSet());
+
+                    boolean b = false;
+                    for (Figure neighbor : set) {
+                        FigureWidget neighborWidget = getWidget(neighbor);
+                        if (neighborWidget.isVisible()) {
+                            b = true;
+                            break;
+                        }
+                    }
+
+                    if (b) {
+                        w.setBoundary(true);
+                        boundaries.add(w);
+                    }
+                }
+            }
+
+            for (FigureWidget w : boundaries) {
+                if (w.isBoundary()) {
+                    w.setVisible(true);
+                }
+            }
+        }
+
+        if (doRelayout) {
+            relayout(oldVisibleWidgets);
+        }
+        this.validate();
+    }
+
+    private void showFigure(Figure f) {
+        HashSet<Integer> newHiddenNodes = new HashSet<>(getModel().getHiddenNodes());
+        newHiddenNodes.removeAll(f.getSource().getSourceNodesAsSet());
+        updateHiddenNodes(newHiddenNodes, true);
+    }
+
+    public void show(final Figure f) {
+        showFigure(f);
+    }
+
+    public void setSelectedObjects(Object... args) {
+        Set<Object> set = new HashSet<>();
+        for (Object o : args) {
+            set.add(o);
+        }
+        super.setSelectedObjects(set);
+    }
+
+    private void centerWidget(Widget w) {
+        Rectangle r = w.getBounds();
+        Point p = w.getLocation();
+        centerRectangle(new Rectangle(p.x, p.y, r.width, r.height));
+    }
+
+    public void gotoFigure(final Figure f) {
+        if (!isVisible(f)) {
+            showFigure(f);
+        }
+
+        FigureWidget fw = getWidget(f);
+        if (fw != null) {
+            setSelection(new HashSet<>(Arrays.asList(f)));
+        }
+    }
+
+    public JPopupMenu createPopupMenu() {
+        JPopupMenu menu = new JPopupMenu();
+        for (Action a : actions) {
+            if (a == null) {
+                menu.addSeparator();
+            } else {
+                menu.add(a);
+            }
+        }
+        return menu;
+    }
+    
+    private final ChangedListener<DiagramViewModel> fullChange = new ChangedListener<DiagramViewModel>() {
+
+        @Override
+        public void changed(DiagramViewModel source) {
+            assert source == model : "Receive only changed event from current model!";
+            assert source != null;
+            update();
+        }
+    };
+    private final ChangedListener<DiagramViewModel> hiddenNodesChange = new ChangedListener<DiagramViewModel>() {
+
+        @Override
+        public void changed(DiagramViewModel source) {
+            assert source == model : "Receive only changed event from current model!";
+            assert source != null;
+            smallUpdate(true);
+        }
+    };
+    private final ChangedListener<DiagramViewModel> selectionChange = new ChangedListener<DiagramViewModel>() {
+
+        @Override
+        public void changed(DiagramViewModel source) {
+            assert source == model : "Receive only changed event from current model!";
+            assert source != null;
+            smallUpdate(false);
+        }
+    };
+
+    @Override
+    public void showAll() {
+        // TODO(tw): Implement.
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/com/sun/hotspot/igv/view/scene/GraphCompilationViewer.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.view.scene;
+
+import com.sun.hotspot.igv.svg.BatikSVG;
+import com.oracle.graal.visualizer.editor.CompilationViewer;
+import com.oracle.graal.visualizer.editor.DiagramViewModel;
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.view.actions.*;
+import java.awt.Component;
+import java.awt.Graphics2D;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.*;
+import java.util.Collection;
+import javax.swing.Action;
+import javax.swing.JToggleButton;
+import javax.swing.JToolBar;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.util.Lookup;
+import org.openide.util.lookup.Lookups;
+import org.openide.util.lookup.ProxyLookup;
+
+public class GraphCompilationViewer implements CompilationViewer, PropertyChangeListener {
+    
+    private DiagramScene scene;
+    private PredSuccAction predSuccAction;
+
+    GraphCompilationViewer(DiagramViewModel model) {
+        
+        scene = new DiagramScene(model);
+        
+        Action[] actions = new Action[]{
+        };
+        
+        scene.setActions(actions);
+    }
+
+    @Override
+    public Lookup getLookup() {
+        return scene.getLookup();
+    }
+
+    @Override
+    public Component getComponent() {
+        return scene.getComponent();
+    }
+
+    @Override
+    public void propertyChange(PropertyChangeEvent evt) {
+        if (evt.getSource() == this.predSuccAction) {
+            boolean b = (Boolean) predSuccAction.getValue(PredSuccAction.STATE);
+            scene.getModel().setShowNodeHull(b);
+        } else {
+            assert false : "Unknown event source";
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/com/sun/hotspot/igv/view/scene/GraphCompilationViewerFactory.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * 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.sun.hotspot.igv.view.scene;
+
+import com.oracle.graal.visualizer.editor.CompilationViewer;
+import com.oracle.graal.visualizer.editor.CompilationViewerFactory;
+import com.oracle.graal.visualizer.editor.DiagramViewModel;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.filter.FilterChain;
+import com.sun.hotspot.igv.filter.FilterChainProvider;
+import org.openide.util.Lookup;
+
+public class GraphCompilationViewerFactory implements CompilationViewerFactory{
+
+    @Override
+    public CompilationViewer createViewer(InputGraph firstGraph, InputGraph secondGraph) {
+        FilterChain filterChain;
+        FilterChain sequence;
+        FilterChainProvider provider = Lookup.getDefault().lookup(FilterChainProvider.class);
+        if (provider == null) {
+            filterChain = new FilterChain();
+            sequence = new FilterChain();
+        } else {
+            filterChain = provider.getFilterChain();
+            sequence = provider.getSequence();
+        }
+        DiagramViewModel model = new DiagramViewModel(firstGraph, secondGraph, firstGraph.getGroup(), filterChain, filterChain);
+        return new GraphCompilationViewer(model);
+    }
+
+    @Override
+    public String getName() {
+        return "Graph";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/com/sun/hotspot/igv/view/widgets/FigureWidget.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.view.widgets;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.util.DoubleClickAction;
+import com.sun.hotspot.igv.util.DoubleClickHandler;
+import com.sun.hotspot.igv.util.PropertiesSheet;
+import com.sun.hotspot.igv.view.scene.DiagramScene;
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+import javax.swing.Action;
+import javax.swing.BorderFactory;
+import javax.swing.JMenu;
+import javax.swing.JPopupMenu;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuListener;
+import org.netbeans.api.visual.action.PopupMenuProvider;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.layout.LayoutFactory;
+import org.netbeans.api.visual.model.ObjectState;
+import org.netbeans.api.visual.widget.LabelWidget;
+import org.netbeans.api.visual.widget.Widget;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.openide.nodes.Sheet;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class FigureWidget extends Widget implements Properties.Provider, PopupMenuProvider, DoubleClickHandler {
+
+    public static final boolean VERTICAL_LAYOUT = true;
+    //public static final int MAX_STRING_LENGTH = 20;
+    private static final double LABEL_ZOOM_FACTOR = 0.3;
+    private static final double ZOOM_FACTOR = 0.1;
+    private Font font;
+    private Font boldFont;
+    private Figure figure;
+    private Widget leftWidget;
+    private Widget rightWidget;
+    private Widget middleWidget;
+    private ArrayList<LabelWidget> labelWidgets;
+    private DiagramScene diagramScene;
+    private boolean boundary;
+    private Node node;
+    private Widget dummyTop;
+
+    public void setBoundary(boolean b) {
+        boundary = b;
+    }
+
+    public boolean isBoundary() {
+        return boundary;
+    }
+
+    public Node getNode() {
+        return node;
+    }
+
+	@Override
+	public boolean isHitAt(Point localLocation) {
+		return middleWidget.isHitAt(localLocation);
+	}
+    
+
+    public FigureWidget(final Figure f, WidgetAction hoverAction, WidgetAction selectAction, DiagramScene scene, Widget parent) {
+
+        super(scene);
+
+        assert this.getScene() != null;
+        assert this.getScene().getView() != null;
+
+        this.figure = f;
+        font = f.getDiagram().getFont();
+        boldFont = f.getDiagram().getFont().deriveFont(Font.BOLD);
+        this.setCheckClipping(true);
+        this.diagramScene = scene;
+        parent.addChild(this);
+
+	Widget outer = new Widget(scene);
+	outer.setBackground(f.getColor());
+	outer.setLayout(LayoutFactory.createOverlayLayout());
+	
+        middleWidget = new Widget(scene);
+        middleWidget.setLayout(LayoutFactory.createVerticalFlowLayout(LayoutFactory.SerialAlignment.CENTER, 0));
+        middleWidget.setBackground(f.getColor());
+        middleWidget.setOpaque(true);
+        //middleWidget.setBorder(BorderFactory.createLineBorder(Color.BLACK));
+        middleWidget.getActions().addAction(new DoubleClickAction(this));
+	middleWidget.setCheckClipping(true);
+
+        labelWidgets = new ArrayList<>();
+
+        String[] strings = figure.getLines();
+
+        dummyTop = new Widget(scene);
+        dummyTop.setMinimumSize(new Dimension(Figure.INSET / 2, 1));
+        middleWidget.addChild(dummyTop);
+
+
+        for (String cur : strings) {
+
+            String displayString = cur;
+
+            LabelWidget lw = new LabelWidget(scene);
+            labelWidgets.add(lw);
+            middleWidget.addChild(lw);
+            lw.setLabel(displayString);
+            lw.setFont(font);
+            lw.setForeground(Color.BLACK);
+            lw.setAlignment(LabelWidget.Alignment.CENTER);
+            lw.setVerticalAlignment(LabelWidget.VerticalAlignment.CENTER);
+	    lw.setBorder(BorderFactory.createEmptyBorder());
+        }
+
+        Widget dummyBottom = new Widget(scene);
+        dummyBottom.setMinimumSize(new Dimension(Figure.INSET / 2, 1));
+        middleWidget.addChild(dummyBottom);
+
+        middleWidget.setPreferredBounds(new Rectangle(0, Figure.SLOT_WIDTH - Figure.OVERLAPPING, f.getWidth(), f.getHeight()));
+	//outer.addChild(middleWidget);
+        this.addChild(middleWidget);
+
+        // Initialize node for property sheet
+        node = new AbstractNode(Children.LEAF) {
+
+            @Override
+            protected Sheet createSheet() {
+                Sheet s = super.createSheet();
+                PropertiesSheet.initializeSheet(f.getProperties(), s);
+                return s;
+            }
+        };
+        node.setDisplayName(getName());
+    }
+
+    public Widget getLeftWidget() {
+        return leftWidget;
+    }
+
+    public Widget getRightWidget() {
+        return rightWidget;
+    }
+
+    @Override
+    protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
+        super.notifyStateChanged(previousState, state);
+
+        Color borderColor = Color.BLACK;
+	Color innerBorderColor = getFigure().getColor();
+        int thickness = 1;
+        boolean repaint = false;
+        Font f = font;
+        if (state.isSelected() || state.isHighlighted()) {
+            thickness = 2;
+	}
+	if(state.isSelected()) {
+            f = boldFont;
+		innerBorderColor = borderColor;
+        } else {
+	}
+
+        if (state.isHighlighted()) {
+		innerBorderColor = borderColor = Color.BLUE;
+		repaint = true;
+        } else {
+		repaint = true;
+	}
+
+        if (state.isHovered() != previousState.isHovered()) {
+
+		/*
+            if (state.isHovered()) {
+                diagramScene.addAllHighlighted(this.getFigure().getSource().getSourceNodesAsSet());
+            } else {
+                diagramScene.removeAllHighlighted(this.getFigure().getSource().getSourceNodesAsSet());
+            }*/
+            repaint = true;
+        }
+
+        if (state.isSelected() != previousState.isSelected()) {
+            repaint = true;
+        }
+
+        if (repaint) {
+            middleWidget.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(borderColor, 1), BorderFactory.createLineBorder(innerBorderColor, 1)));
+            for (LabelWidget labelWidget : labelWidgets) {
+                labelWidget.setFont(f);
+            }
+            repaint();
+        }
+    }
+
+    public String getName() {
+        return getProperties().get("name");
+    }
+
+    @Override
+    public Properties getProperties() {
+        return figure.getProperties();
+    }
+
+    public Figure getFigure() {
+        return figure;
+    }
+
+    @Override
+    protected void paintChildren() {
+        Composite oldComposite = null;
+        if (boundary) {
+            oldComposite = getScene().getGraphics().getComposite();
+            float alpha = DiagramScene.ALPHA;
+            this.getScene().getGraphics().setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
+        }
+
+        if (diagramScene.getZoomFactor() < LABEL_ZOOM_FACTOR) {
+
+            for (LabelWidget labelWidget : labelWidgets) {
+                labelWidget.setVisible(false);
+            }
+            super.paintChildren();
+            for (LabelWidget labelWidget : labelWidgets) {
+                labelWidget.setVisible(true);
+            }
+
+        } else {
+            super.paintChildren();
+        }
+
+        if (boundary) {
+            getScene().getGraphics().setComposite(oldComposite);
+        }
+    }
+ 
+    @Override
+    public JPopupMenu getPopupMenu(Widget widget, Point point) {
+        JPopupMenu menu = diagramScene.createPopupMenu();
+        menu.addSeparator();
+
+        JMenu predecessors = new JMenu("Nodes Above");
+        predecessors.addMenuListener(new NeighborMenuListener(predecessors, getFigure(), false));
+        menu.add(predecessors);
+
+        JMenu successors = new JMenu("Nodes Below");
+        successors.addMenuListener(new NeighborMenuListener(successors, getFigure(), true));
+        menu.add(successors);
+
+        return menu;
+    }
+
+    /**
+     * Builds the submenu for a figure's neighbors on demand.
+     */
+    private class NeighborMenuListener implements MenuListener {
+
+        private final JMenu menu;
+        private final Figure figure;
+        private final boolean successors;
+
+        public NeighborMenuListener(JMenu menu, Figure figure, boolean successors) {
+            this.menu = menu;
+            this.figure = figure;
+            this.successors = successors;
+        }
+
+        @Override
+        public void menuSelected(MenuEvent e) {
+            if (menu.getItemCount() > 0) {
+                // already built before
+                return;
+            }
+
+            Set<Figure> set = figure.getPredecessorSet();
+            if (successors) {
+                set = figure.getSuccessorSet();
+            }
+
+            boolean first = true;
+            for (Figure f : set) {
+                if (f == figure) {
+                    continue;
+                }
+
+                if (first) {
+                    first = false;
+                } else {
+                    menu.addSeparator();
+                }
+
+                Action go = diagramScene.createGotoAction(f);
+                menu.add(go);
+
+                JMenu preds = new JMenu("Nodes Above");
+                preds.addMenuListener(new NeighborMenuListener(preds, f, false));
+                menu.add(preds);
+
+                JMenu succs = new JMenu("Nodes Below");
+                succs.addMenuListener(new NeighborMenuListener(succs, f, true));
+                menu.add(succs);
+            }
+
+            if (menu.getItemCount() == 0) {
+                menu.add("(none)");
+            }
+        }
+
+        @Override
+        public void menuDeselected(MenuEvent e) {
+            // ignore
+        }
+
+        @Override
+        public void menuCanceled(MenuEvent e) {
+            // ignore
+        }
+    }
+
+    @Override
+    public void handleDoubleClick(Widget w, WidgetAction.WidgetMouseEvent e) {
+
+        if (diagramScene.isAllVisible()) {
+            final Set<Integer> hiddenNodes = new HashSet<>(diagramScene.getModel().getGraphToView().getGroup().getAllNodes());
+            hiddenNodes.removeAll(this.getFigure().getSource().getSourceNodesAsSet());
+            this.diagramScene.getModel().showNot(hiddenNodes);
+        } else if (isBoundary()) {
+
+            final Set<Integer> hiddenNodes = new HashSet<>(diagramScene.getModel().getHiddenNodes());
+            hiddenNodes.removeAll(this.getFigure().getSource().getSourceNodesAsSet());
+            this.diagramScene.getModel().showNot(hiddenNodes);
+        } else {
+            final Set<Integer> hiddenNodes = new HashSet<>(diagramScene.getModel().getHiddenNodes());
+            hiddenNodes.addAll(this.getFigure().getSource().getSourceNodesAsSet());
+            this.diagramScene.getModel().showNot(hiddenNodes);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/com/sun/hotspot/igv/view/widgets/InputSlotWidget.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.view.widgets;
+
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.graph.InputSlot;
+import com.sun.hotspot.igv.view.scene.DiagramScene;
+import java.awt.Point;
+import java.util.List;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputSlotWidget extends SlotWidget {
+
+    private InputSlot inputSlot;
+
+    public InputSlotWidget(InputSlot slot, DiagramScene scene, Widget parent, FigureWidget fw) {
+        super(slot, scene, parent, fw);
+        inputSlot = slot;
+        //init();
+        //getFigureWidget().getLeftWidget().addChild(this);
+        Point p = inputSlot.getRelativePosition();
+        p.x -= this.calculateClientArea().width / 2;
+        p.y += Figure.SLOT_START;
+        this.setPreferredLocation(p);
+    }
+
+    public InputSlot getInputSlot() {
+        return inputSlot;
+    }
+    
+    @Override
+    protected int calculateSlotWidth() {
+        List<InputSlot> slots = getSlot().getFigure().getInputSlots();
+        assert slots.contains(getSlot());
+        return calculateWidth(slots.size());
+    }
+/*
+    protected Point calculateRelativeLocation() {
+        if (getFigureWidget().getBounds() == null) {
+            return new Point(0, 0);
+        }
+
+        double x = 0;
+        List<InputSlot> slots = inputSlot.getFigure().getInputSlots();
+        assert slots.contains(inputSlot);
+        return new Point((int) x, (int) (calculateRelativeY(slots.size(), slots.indexOf(inputSlot))));
+    }*/
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/com/sun/hotspot/igv/view/widgets/LineWidget.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.view.widgets;
+
+import com.sun.hotspot.igv.graph.Connection;
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.graph.InputSlot;
+import com.sun.hotspot.igv.graph.OutputSlot;
+import com.sun.hotspot.igv.view.scene.DiagramScene;
+import java.awt.*;
+import java.awt.geom.Line2D;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.swing.JPopupMenu;
+import javax.swing.event.PopupMenuEvent;
+import javax.swing.event.PopupMenuListener;
+import org.netbeans.api.visual.action.ActionFactory;
+import org.netbeans.api.visual.action.PopupMenuProvider;
+import org.netbeans.api.visual.action.SelectProvider;
+import org.netbeans.api.visual.animator.SceneAnimator;
+import org.netbeans.api.visual.model.ObjectState;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class LineWidget extends Widget implements PopupMenuProvider {
+
+    public final int BORDER = 5;
+    public final int ARROW_SIZE = 6;
+    public final int BOLD_ARROW_SIZE = 7;
+    public final int HOVER_ARROW_SIZE = 8;
+    public final int BOLD_STROKE_WIDTH = 2;
+    public final int HOVER_STROKE_WIDTH = 3;
+    private static double ZOOM_FACTOR = 0.1;
+    private OutputSlot outputSlot;
+    private DiagramScene scene;
+    private List<Connection> connections;
+    private Point from;
+    private Point to;
+    private Rectangle clientArea;
+    private Color color = Color.BLACK;
+    private LineWidget predecessor;
+    private List<LineWidget> successors;
+    private boolean highlighted;
+    private boolean popupVisible;
+    private boolean isBold;
+    private boolean isDashed;
+
+    public LineWidget(DiagramScene scene, OutputSlot s, List<Connection> connections, Point from, Point to, LineWidget predecessor, SceneAnimator animator, boolean isBold, boolean isDashed) {
+        super(scene);
+        this.scene = scene;
+        this.outputSlot = s;
+        this.connections = connections;
+        this.from = from;
+        this.to = to;
+        this.predecessor = predecessor;
+        this.successors = new ArrayList<>();
+        if (predecessor != null) {
+            predecessor.addSuccessor(this);
+        }
+
+        this.isBold = isBold;
+        this.isDashed = isDashed;
+
+        int minX = from.x;
+        int minY = from.y;
+        int maxX = to.x;
+        int maxY = to.y;
+        if (minX > maxX) {
+            int tmp = minX;
+            minX = maxX;
+            maxX = tmp;
+        }
+
+        if (minY > maxY) {
+            int tmp = minY;
+            minY = maxY;
+            maxY = tmp;
+        }
+
+        clientArea = new Rectangle(minX, minY, maxX - minX + 1, maxY - minY + 1);
+        clientArea.grow(BORDER, BORDER);
+
+        if (connections.size() > 0) {
+            color = connections.get(0).getColor();
+        }
+
+        this.setToolTipText("<HTML>" + generateToolTipText(this.connections) + "</HTML>");
+
+        this.setCheckClipping(true);
+
+        this.getActions().addAction(ActionFactory.createPopupMenuAction(this));
+        if (animator == null) {
+            this.setBackground(color);
+        } else {
+            this.setBackground(Color.WHITE);
+            animator.animateBackgroundColor(this, color);
+        }
+
+        this.getActions().addAction(ActionFactory.createSelectAction(new SelectProvider() {
+
+            @Override
+            public boolean isAimingAllowed(Widget arg0, Point arg1, boolean arg2) {
+                return true;
+            }
+
+            @Override
+            public boolean isSelectionAllowed(Widget arg0, Point arg1, boolean arg2) {
+                return true;
+            }
+
+            @Override
+            public void select(Widget arg0, Point arg1, boolean arg2) {
+                Set<Figure> set = new HashSet<>();
+                for (Connection c : LineWidget.this.connections) {
+                    set.add(c.getInputSlot().getFigure());
+                    set.add(c.getOutputSlot().getFigure());
+                }
+                LineWidget.this.scene.setSelectedObjects(set);
+            }
+        }));
+    }
+
+    private String generateToolTipText(List<Connection> conn) {
+        StringBuilder sb = new StringBuilder();
+        for (Connection c : conn) {
+            sb.append(c.getToolTipText());
+            sb.append("<br>");
+        }
+        return sb.toString();
+    }
+
+    public Point getFrom() {
+        return from;
+    }
+
+    public Point getTo() {
+        return to;
+    }
+
+    private void addSuccessor(LineWidget widget) {
+        this.successors.add(widget);
+    }
+
+    @Override
+    protected Rectangle calculateClientArea() {
+        return clientArea;
+    }
+
+    @Override
+    protected void paintWidget() {
+        if (scene.getZoomFactor() < ZOOM_FACTOR) {
+            return;
+        }
+
+        Graphics2D g = getScene().getGraphics();
+        g.setPaint(this.getBackground());
+        float width = 1.0f;
+
+        if (isBold) {
+            width = BOLD_STROKE_WIDTH;
+        }
+
+        if (highlighted || popupVisible) {
+            width = HOVER_STROKE_WIDTH;
+        }
+
+        Stroke oldStroke = g.getStroke();
+        if (isDashed) {
+            float[] dashPattern = {5, 5, 5, 5};
+            g.setStroke(new BasicStroke(width, BasicStroke.CAP_BUTT,
+                    BasicStroke.JOIN_MITER, 10,
+                    dashPattern, 0));
+        } else {
+            g.setStroke(new BasicStroke(width));
+        }
+
+        g.drawLine(from.x, from.y, to.x, to.y);
+
+        boolean sameFrom = false;
+        boolean sameTo = successors.size() == 0;
+        for (LineWidget w : successors) {
+            if (w.getFrom().equals(getTo())) {
+                sameTo = true;
+            }
+        }
+
+        if (predecessor == null || predecessor.getTo().equals(getFrom())) {
+            sameFrom = true;
+        }
+
+
+        int size = ARROW_SIZE;
+        if (isBold) {
+            size = BOLD_ARROW_SIZE;
+        }
+        if (highlighted || popupVisible) {
+            size = HOVER_ARROW_SIZE;
+        }
+        if (!sameFrom) {
+            g.fillPolygon(
+                    new int[]{from.x - size / 2, from.x + size / 2, from.x},
+                    new int[]{from.y - size / 2, from.y - size / 2, from.y + size / 2},
+                    3);
+        }
+        if (!sameTo) {
+            g.fillPolygon(
+                    new int[]{to.x - size / 2, to.x + size / 2, to.x},
+                    new int[]{to.y - size / 2, to.y - size / 2, to.y + size / 2},
+                    3);
+        }
+        g.setStroke(oldStroke);
+    }
+
+    private void setHighlighted(boolean b) {
+        this.highlighted = b;
+	Set<Object> highlightedObjects = new HashSet<>(scene.getHighlightedObjects());
+	Set<Object> highlightedObjectsChange = new HashSet<>();
+        for (Connection c : connections) {
+		highlightedObjectsChange.add(c.getInputSlot().getFigure());
+		highlightedObjectsChange.add(c.getInputSlot());
+		highlightedObjectsChange.add(c.getOutputSlot().getFigure());
+		highlightedObjectsChange.add(c.getOutputSlot());
+        }
+	if(b) {
+		highlightedObjects.addAll(highlightedObjectsChange);
+	} else {
+		highlightedObjects.removeAll(highlightedObjectsChange);
+	}
+	scene.setHighlightedObjects(highlightedObjects);
+        this.revalidate(true);
+    }
+
+    private void setPopupVisible(boolean b) {
+        this.popupVisible = b;
+        this.revalidate(true);
+    }
+
+    @Override
+    public boolean isHitAt(Point localPoint) {
+        return Line2D.ptLineDistSq(from.x, from.y, to.x, to.y, localPoint.x, localPoint.y) <= BORDER * BORDER;
+    }
+
+    @Override
+    protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
+        if (previousState.isHovered() != state.isHovered()) {
+            setRecursiveHighlighted(state.isHovered());
+        }
+    }
+
+    private void setRecursiveHighlighted(boolean b) {
+        LineWidget cur = predecessor;
+        while (cur != null) {
+            cur.setHighlighted(b);
+            cur = cur.predecessor;
+        }
+
+        highlightSuccessors(b);
+        this.setHighlighted(b);
+    }
+
+    private void highlightSuccessors(boolean b) {
+        for (LineWidget s : successors) {
+            s.setHighlighted(b);
+            s.highlightSuccessors(b);
+        }
+    }
+
+    private void setRecursivePopupVisible(boolean b) {
+        LineWidget cur = predecessor;
+        while (cur != null) {
+            cur.setPopupVisible(b);
+            cur = cur.predecessor;
+        }
+
+        popupVisibleSuccessors(b);
+        setPopupVisible(b);
+    }
+
+    private void popupVisibleSuccessors(boolean b) {
+        for (LineWidget s : successors) {
+            s.setPopupVisible(b);
+            s.popupVisibleSuccessors(b);
+        }
+    }
+
+    @Override
+    public JPopupMenu getPopupMenu(Widget widget, Point localLocation) {
+        JPopupMenu menu = new JPopupMenu();
+        menu.add(scene.createGotoAction(outputSlot.getFigure()));
+        menu.addSeparator();
+
+        for (Connection c : connections) {
+            InputSlot s = c.getInputSlot();
+            menu.add(scene.createGotoAction(s.getFigure()));
+        }
+
+        final LineWidget w = this;
+        menu.addPopupMenuListener(new PopupMenuListener() {
+
+            @Override
+            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
+                w.setRecursivePopupVisible(true);
+            }
+
+            @Override
+            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
+                w.setRecursivePopupVisible(false);
+            }
+
+            @Override
+            public void popupMenuCanceled(PopupMenuEvent e) {
+            }
+        });
+
+        return menu;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/com/sun/hotspot/igv/view/widgets/OutputSlotWidget.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.view.widgets;
+
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.graph.OutputSlot;
+import com.sun.hotspot.igv.view.scene.DiagramScene;
+import java.awt.Point;
+import java.util.List;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class OutputSlotWidget extends SlotWidget {
+
+    private OutputSlot outputSlot;
+
+    public OutputSlotWidget(OutputSlot slot, DiagramScene scene, Widget parent, FigureWidget fw) {
+        super(slot, scene, parent, fw);
+        outputSlot = slot;
+        //init();
+        //getFigureWidget().getRightWidget().addChild(this);
+        Point p = outputSlot.getRelativePosition();
+        p.y += getSlot().getFigure().getHeight() - Figure.SLOT_START;
+        p.x -= this.calculateClientArea().width / 2;
+        //p.x += this.calculateClientArea().width / 2;
+        this.setPreferredLocation(p);
+    }
+
+    public OutputSlot getOutputSlot() {
+        return outputSlot;
+    }
+
+    @Override
+    protected int calculateSlotWidth() {
+        
+        List<OutputSlot> slots = getSlot().getFigure().getOutputSlots();
+        assert slots.contains(getSlot());
+        return calculateWidth(slots.size());
+        
+    }
+    /*
+    protected Point calculateRelativeLocation() {
+        if (getFigureWidget().getBounds() == null) {
+            return new Point(0, 0);
+        }
+
+        double x = this.getFigureWidget().getBounds().width;
+        List<OutputSlot> slots = outputSlot.getFigure().getOutputSlots();
+        assert slots.contains(outputSlot);
+        return new Point((int) x, (int) (calculateRelativeY(slots.size(), slots.indexOf(outputSlot))));
+    }*/
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/View/src/com/sun/hotspot/igv/view/widgets/SlotWidget.java	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2008, 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.sun.hotspot.igv.view.widgets;
+
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.graph.OutputSlot;
+import com.sun.hotspot.igv.graph.Slot;
+import com.sun.hotspot.igv.util.DoubleClickHandler;
+import com.sun.hotspot.igv.view.scene.DiagramScene;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
+import java.util.HashSet;
+import java.util.Set;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.model.ObjectState;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public abstract class SlotWidget extends Widget implements DoubleClickHandler {
+
+    private Slot slot;
+    private FigureWidget figureWidget;
+    private static double TEXT_ZOOM_FACTOR = 0.9;
+    private static double ZOOM_FACTOR = 0.6;
+    private DiagramScene diagramScene;
+
+    public SlotWidget(Slot slot, DiagramScene scene, Widget parent, FigureWidget fw) {
+        super(scene);
+        this.diagramScene = scene;
+        this.slot = slot;
+        figureWidget = fw;
+        this.setToolTipText("<HTML>" + slot.getToolTipText() + "</HTML>");
+        this.setCheckClipping(true);
+        parent.addChild(this);
+        
+        //this.setPreferredBounds(this.calculateClientArea());
+    }
+    
+    
+    @Override
+    protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
+        super.notifyStateChanged(previousState, state);
+	repaint();
+    }
+    
+    public Slot getSlot() {
+        return slot;
+    }
+
+    public FigureWidget getFigureWidget() {
+        return figureWidget;
+    }
+
+    @Override
+    protected void paintWidget() {
+
+        if (getScene().getZoomFactor() < ZOOM_FACTOR) {
+            return;
+        }
+
+        Graphics2D g = this.getGraphics();
+       // g.setColor(Color.DARK_GRAY);
+        int w = this.getBounds().width;
+        int h = this.getBounds().height;
+
+        if(getSlot().getSource().getSourceNodes().size() > 0) {
+            final int SMALLER = 0;
+            g.setColor(getSlot().getColor());
+
+            int FONT_OFFSET = 2;
+            
+            int s = h - SMALLER;
+            int rectW = s;
+            
+            Font font = this.getSlot().getFigure().getDiagram().getSlotFont();
+            if(this.getState().isSelected()) {
+                font = font.deriveFont(Font.BOLD);
+            }
+            
+            if (getSlot().getShortName() != null && getSlot().getShortName().length() > 0) {
+                g.setFont(font);
+                Rectangle2D r1 = g.getFontMetrics().getStringBounds(getSlot().getShortName(), g);
+                rectW = (int)r1.getWidth() + FONT_OFFSET * 2;
+            }
+            g.fillRect(w/2 - rectW/2, 0, rectW-1, s-1);
+            
+            if(this.getState().isHighlighted()) {
+                g.setColor(Color.BLUE);
+            } else {
+                g.setColor(Color.BLACK);
+            }
+            g.drawRect(w/2 - rectW/2, 0, rectW-1, s-1);
+            
+            
+            if (getSlot().getShortName() != null && getSlot().getShortName().length() > 0 && getScene().getZoomFactor() >= TEXT_ZOOM_FACTOR) {
+                Rectangle2D r1 = g.getFontMetrics().getStringBounds(getSlot().getShortName(), g);
+                g.drawString(getSlot().getShortName(), (int) (w - r1.getWidth()) / 2, g.getFontMetrics().getAscent()-1);//(int) (r1.getHeight()));
+            }
+            
+        } else {
+
+            if(this.getState().isHighlighted()) {
+                g.setColor(Color.BLUE);
+            } else {
+                g.setColor(Color.BLACK);
+            }
+            int r = 2;
+            if (slot instanceof OutputSlot) {
+                g.fillOval(w/2-r, Figure.SLOT_WIDTH - Figure.SLOT_START - r, 2*r, 2*r);
+                //g.fillArc(w / 2 - r, -r, 2*r, 2*r, 180, 180);
+            } else {
+                g.fillOval(w/2-r, Figure.SLOT_START - r, 2*r, 2*r);
+                //g.fillArc(w / 2 - r, h - r, 2*r, 2*r, 0, 180);
+            }
+        }
+    }
+
+    @Override
+    protected Rectangle calculateClientArea() {
+        return new Rectangle(0, 0, slot.getWidth(), Figure.SLOT_WIDTH);
+    }
+ 
+    protected abstract int calculateSlotWidth();
+    
+    protected int calculateWidth(int count) {
+        return getFigureWidget().getFigure().getWidth() / count;
+    }
+
+    @Override
+    public void handleDoubleClick(Widget w, WidgetAction.WidgetMouseEvent e) {
+        Set<Integer> hiddenNodes = new HashSet<>(diagramScene.getModel().getHiddenNodes());
+        if (diagramScene.isAllVisible()) {
+            hiddenNodes = new HashSet<>(diagramScene.getModel().getGraphToView().getGroup().getAllNodes());
+        } 
+
+        boolean progress = false;
+        for(Figure f : diagramScene.getModel().getDiagramToView().getFigures()) {
+            for(Slot s : f.getSlots()) {
+                if(DiagramScene.doesIntersect(s.getSource().getSourceNodesAsSet(), slot.getSource().getSourceNodesAsSet())) {
+                    progress = true;
+                    hiddenNodes.removeAll(f.getSource().getSourceNodesAsSet());
+                }
+            }
+        }
+
+        if(progress) {
+            this.diagramScene.getModel().showNot(hiddenNodes);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,7 @@
+currentVersion=Graal Visualizer {0}
+LBL_splash_window_title=Starting Graal Visualizer
+SPLASH_WIDTH=475
+SplashProgressBarBounds=0,273,475,6
+SplashProgressBarColor=0xFFFFFF
+SplashRunningTextBounds=10,283,460,12
+SplashRunningTextColor=0xFFFFFF
Binary file visualizer/branding/core/core.jar/org/netbeans/core/startup/frame.gif has changed
Binary file visualizer/branding/core/core.jar/org/netbeans/core/startup/frame32.gif has changed
Binary file visualizer/branding/core/core.jar/org/netbeans/core/startup/frame48.gif has changed
Binary file visualizer/branding/core/core.jar/org/netbeans/core/startup/splash.gif has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,2 @@
+CTL_MainWindow_Title=Graal Visualizer {0}
+CTL_MainWindow_Title_No_Project=Graal Visualizer {0}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/build.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="Graal Visualizer" basedir=".">
+    <description>Builds the module suite Graal Visualizer.</description>
+    <import file="nbproject/build-impl.xml"/>
+    
+    <target name="build-launchers" depends="suite.build-launchers">
+        <!-- Drop memory presets (-Xms, -Xmx) from default_options of packaged builds and let the executing VM choose reasonable defaults -->
+        <replaceregexp file="${build.launcher.dir}/etc/${app.name}.conf" byline="true" match="^default_options=.*" replace='default_options="--branding graalvisualizer"' />
+    </target>
+    
+    <!-- Local (environment-specific) extensions/modifications to the build -->
+    <import file="build-local.xml" optional="true" />
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/nbproject/build-impl.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="Graal Visualizer-impl" basedir=".." xmlns:sproject="http://www.netbeans.org/ns/nb-module-suite-project/1">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/platform-private.properties"/>
+    <property file="nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <sproject:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir"/>
+    <sproject:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir"/>
+    <sproject:evalprops property="cluster.path.evaluated" value="${cluster.path}"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <ant antfile="nbproject/platform.xml"/>
+    <fail message="Cannot find NetBeans build harness. ${line.separator}Check that nbplatform.${nbplatform.active}.netbeans.dest.dir and nbplatform.${nbplatform.active}.harness.dir are defined. ${line.separator}On a developer machine these are normally defined in ${user.properties.file}=${netbeans.user}/build.properties ${line.separator}but for automated builds you should pass these properties to Ant explicitly. ${line.separator}You may instead download the harness and platform: -Dbootstrap.url=.../tasks.jar -Dautoupdate.catalog.url=.../updates.xml">
+        <condition>
+            <not>
+                <available file="${harness.dir}/suite.xml"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/suite.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/nbproject/genfiles.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,11 @@
+build.xml.data.CRC32=3c2c6126
+build.xml.script.CRC32=48934e60
+build.xml.stylesheet.CRC32=eaf9f76a@1.45.1
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=3077accc
+nbproject/build-impl.xml.script.CRC32=17b494f7
+nbproject/build-impl.xml.stylesheet.CRC32=0f381476@2.47.1
+nbproject/platform.xml.data.CRC32=3077accc
+nbproject/platform.xml.script.CRC32=db9e1f43
+nbproject/platform.xml.stylesheet.CRC32=df8ac4dd@2.47.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/nbproject/platform.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,212 @@
+nbplatform.active=default
+bootstrap.url=http://deadlock.netbeans.org/hudson/job/nbms-and-javadoc/lastSuccessfulBuild/artifact/nbbuild/netbeans/harness/tasks.jar
+autoupdate.catalog.url=http://updates.netbeans.org/netbeans/updates/7.1.1/uc/final/distribution/catalog.xml.gz
+suite.dir=${basedir}
+nbplatform.active.dir=${suite.dir}/nbplatform
+nbplatform.default.netbeans.dest.dir=${suite.dir}/nbplatform
+nbplatform.default.harness.dir=${nbplatform.default.netbeans.dest.dir}/harness
+harness.dir=${nbplatform.active.dir}/harness
+cluster.path=\
+    ${nbplatform.active.dir}/ide:\
+    ${nbplatform.active.dir}/platform
+disabled.modules=\
+    com.jcraft.jsch,\
+    com.jcraft.jzlib,\
+    org.apache.commons.codec,\
+    org.apache.commons.httpclient,\
+    org.apache.commons.io,\
+    org.apache.commons.lang,\
+    org.apache.commons.logging,\
+    org.apache.ws.commons.util,\
+    org.apache.xml.resolver,\
+    org.apache.xmlrpc,\
+    org.eclipse.core.contenttype,\
+    org.eclipse.core.jobs,\
+    org.eclipse.core.net,\
+    org.eclipse.core.runtime,\
+    org.eclipse.core.runtime.compatibility.auth,\
+    org.eclipse.equinox.app,\
+    org.eclipse.equinox.common,\
+    org.eclipse.equinox.preferences,\
+    org.eclipse.equinox.registry,\
+    org.eclipse.equinox.security,\
+    org.eclipse.jgit,\
+    org.eclipse.mylyn.bugzilla.core,\
+    org.eclipse.mylyn.commons.core,\
+    org.eclipse.mylyn.commons.net,\
+    org.eclipse.mylyn.commons.xmlrpc,\
+    org.eclipse.mylyn.tasks.core,\
+    org.mozilla.rhino.patched,\
+    org.netbeans.api.debugger,\
+    org.netbeans.api.java.classpath,\
+    org.netbeans.api.xml,\
+    org.netbeans.core.browser,\
+    org.netbeans.core.execution,\
+    org.netbeans.core.ide,\
+    org.netbeans.core.io.ui,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.nativeaccess,\
+    org.netbeans.core.osgi,\
+    org.netbeans.lib.cvsclient,\
+    org.netbeans.lib.terminalemulator,\
+    org.netbeans.libs.antlr3.runtime,\
+    org.netbeans.libs.bytelist,\
+    org.netbeans.libs.commons_net,\
+    org.netbeans.libs.freemarker,\
+    org.netbeans.libs.git,\
+    org.netbeans.libs.ini4j,\
+    org.netbeans.libs.jaxb,\
+    org.netbeans.libs.jsr223,\
+    org.netbeans.libs.junit4,\
+    org.netbeans.libs.jvyamlb,\
+    org.netbeans.libs.lucene,\
+    org.netbeans.libs.smack,\
+    org.netbeans.libs.svnClientAdapter,\
+    org.netbeans.libs.svnClientAdapter.javahl,\
+    org.netbeans.libs.svnClientAdapter.svnkit,\
+    org.netbeans.libs.swingx,\
+    org.netbeans.libs.xerces,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.bugtracking,\
+    org.netbeans.modules.bugtracking.bridge,\
+    org.netbeans.modules.bugzilla,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.csl.api,\
+    org.netbeans.modules.css.editor,\
+    org.netbeans.modules.css.lib,\
+    org.netbeans.modules.css.visual,\
+    org.netbeans.modules.db,\
+    org.netbeans.modules.db.core,\
+    org.netbeans.modules.db.dataview,\
+    org.netbeans.modules.db.drivers,\
+    org.netbeans.modules.db.kit,\
+    org.netbeans.modules.db.metadata.model,\
+    org.netbeans.modules.db.mysql,\
+    org.netbeans.modules.db.sql.editor,\
+    org.netbeans.modules.db.sql.visualeditor,\
+    org.netbeans.modules.dbapi,\
+    org.netbeans.modules.defaults,\
+    org.netbeans.modules.derby,\
+    org.netbeans.modules.dlight.nativeexecution,\
+    org.netbeans.modules.dlight.terminal,\
+    org.netbeans.modules.editor.bookmarks,\
+    org.netbeans.modules.editor.bracesmatching,\
+    org.netbeans.modules.editor.codetemplates,\
+    org.netbeans.modules.editor.completion,\
+    org.netbeans.modules.editor.guards,\
+    org.netbeans.modules.editor.indent.project,\
+    org.netbeans.modules.editor.kit,\
+    org.netbeans.modules.editor.macros,\
+    org.netbeans.modules.editor.structure,\
+    org.netbeans.modules.extbrowser,\
+    org.netbeans.modules.extexecution,\
+    org.netbeans.modules.extexecution.destroy,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.git,\
+    org.netbeans.modules.glassfish.common,\
+    org.netbeans.modules.gototest,\
+    org.netbeans.modules.gsf.codecoverage,\
+    org.netbeans.modules.gsf.testrunner,\
+    org.netbeans.modules.html,\
+    org.netbeans.modules.html.editor,\
+    org.netbeans.modules.html.editor.lib,\
+    org.netbeans.modules.html.lexer,\
+    org.netbeans.modules.html.parser,\
+    org.netbeans.modules.html.validation,\
+    org.netbeans.modules.httpserver,\
+    org.netbeans.modules.hudson,\
+    org.netbeans.modules.hudson.git,\
+    org.netbeans.modules.hudson.mercurial,\
+    org.netbeans.modules.hudson.subversion,\
+    org.netbeans.modules.hudson.tasklist,\
+    org.netbeans.modules.ide.kit,\
+    org.netbeans.modules.image,\
+    org.netbeans.modules.javascript.editing,\
+    org.netbeans.modules.javascript.hints,\
+    org.netbeans.modules.javascript.kit,\
+    org.netbeans.modules.javascript.refactoring,\
+    org.netbeans.modules.jellytools.ide,\
+    org.netbeans.modules.jumpto,\
+    org.netbeans.modules.keyring.impl,\
+    org.netbeans.modules.languages,\
+    org.netbeans.modules.languages.diff,\
+    org.netbeans.modules.languages.manifest,\
+    org.netbeans.modules.languages.yaml,\
+    org.netbeans.modules.lexer.nbbridge,\
+    org.netbeans.modules.localhistory,\
+    org.netbeans.modules.mercurial,\
+    org.netbeans.modules.netbinox,\
+    org.netbeans.modules.parsing.api,\
+    org.netbeans.modules.parsing.lucene,\
+    org.netbeans.modules.print.editor,\
+    org.netbeans.modules.project.ant,\
+    org.netbeans.modules.project.libraries,\
+    org.netbeans.modules.projectui,\
+    org.netbeans.modules.projectui.buildmenu,\
+    org.netbeans.modules.projectuiapi,\
+    org.netbeans.modules.properties,\
+    org.netbeans.modules.properties.syntax,\
+    org.netbeans.modules.refactoring.api,\
+    org.netbeans.modules.schema2beans,\
+    org.netbeans.modules.server,\
+    org.netbeans.modules.servletapi,\
+    org.netbeans.modules.spellchecker,\
+    org.netbeans.modules.spellchecker.apimodule,\
+    org.netbeans.modules.spellchecker.bindings.htmlxml,\
+    org.netbeans.modules.spellchecker.bindings.properties,\
+    org.netbeans.modules.spellchecker.dictionary_en,\
+    org.netbeans.modules.spellchecker.kit,\
+    org.netbeans.modules.spi.actions,\
+    org.netbeans.modules.subversion,\
+    org.netbeans.modules.swing.validation,\
+    org.netbeans.modules.target.iterator,\
+    org.netbeans.modules.tasklist.kit,\
+    org.netbeans.modules.tasklist.projectint,\
+    org.netbeans.modules.tasklist.todo,\
+    org.netbeans.modules.tasklist.ui,\
+    org.netbeans.modules.terminal,\
+    org.netbeans.modules.usersguide,\
+    org.netbeans.modules.utilities,\
+    org.netbeans.modules.utilities.project,\
+    org.netbeans.modules.versioning,\
+    org.netbeans.modules.versioning.indexingbridge,\
+    org.netbeans.modules.versioning.system.cvss.installer,\
+    org.netbeans.modules.versioning.util,\
+    org.netbeans.modules.web.client.tools.api,\
+    org.netbeans.modules.web.common,\
+    org.netbeans.modules.web.indent,\
+    org.netbeans.modules.xml,\
+    org.netbeans.modules.xml.axi,\
+    org.netbeans.modules.xml.catalog,\
+    org.netbeans.modules.xml.core,\
+    org.netbeans.modules.xml.jaxb.api,\
+    org.netbeans.modules.xml.lexer,\
+    org.netbeans.modules.xml.multiview,\
+    org.netbeans.modules.xml.retriever,\
+    org.netbeans.modules.xml.schema.completion,\
+    org.netbeans.modules.xml.schema.model,\
+    org.netbeans.modules.xml.tax,\
+    org.netbeans.modules.xml.text,\
+    org.netbeans.modules.xml.tools,\
+    org.netbeans.modules.xml.wsdl.model,\
+    org.netbeans.modules.xml.xam,\
+    org.netbeans.modules.xml.xdm,\
+    org.netbeans.modules.xsl,\
+    org.netbeans.spi.debugger.ui,\
+    org.netbeans.spi.editor.hints,\
+    org.netbeans.spi.navigator,\
+    org.netbeans.spi.palette,\
+    org.netbeans.spi.tasklist,\
+    org.netbeans.spi.viewmodel,\
+    org.netbeans.swing.dirchooser,\
+    org.openide.compat,\
+    org.openide.execution,\
+    org.openide.options,\
+    org.openide.util.enumerations
+## Not disabled because of NetBeans bug 206347:
+## Applications not using OSGi don't start on NbP 7.1
+#   org.netbeans.core.netigso,\
+#   org.netbeans.libs.felix,\
+#   org.netbeans.libs.osgi,\
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/nbproject/platform.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="platform" default="download" basedir="..">
+    <condition property="download.required">
+        <and>
+            <not>
+                <available file="${harness.dir}/suite.xml"/>
+            </not>
+            <isset property="bootstrap.url"/>
+            <isset property="autoupdate.catalog.url"/>
+        </and>
+    </condition>
+    <target name="download" if="download.required">
+        <mkdir dir="${harness.dir}"/>
+        <pathconvert pathsep="|" property="download.clusters">
+            <mapper type="flatten"/>
+            <path path="${cluster.path}"/>
+        </pathconvert>
+        <property name="disabled.modules" value=""/>
+        <pathconvert property="module.includes" pathsep="">
+            <mapper type="glob" from="${basedir}${file.separator}*" to="(?!\Q*\E)"/>
+            <path>
+                <filelist files="${disabled.modules}" dir="."/>
+            </path>
+        </pathconvert>
+        <echo message="Downloading clusters ${download.clusters}"/>
+        <property name="tasks.jar" location="${java.io.tmpdir}/tasks.jar"/>
+        <get src="${bootstrap.url}" dest="${tasks.jar}" usetimestamp="true" verbose="true"/>
+        <taskdef name="autoupdate" classname="org.netbeans.nbbuild.AutoUpdate" classpath="${tasks.jar}"/>
+        <autoupdate installdir="${nbplatform.active.dir}" updatecenter="${autoupdate.catalog.url}">
+            <modules includes="${module.includes}.*" clusters="${download.clusters}"/>
+            <modules includes="org[.]netbeans[.]modules[.]apisupport[.]harness" clusters="harness"/>
+        </autoupdate>
+    </target>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/nbproject/project.properties	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,48 @@
+app.icon=branding/core/core.jar/org/netbeans/core/startup/frame48.gif
+app.name=graalvisualizer
+app.title=Graal Visualizer
+branding.token=${app.name}
+modules=\
+    ${project.com.sun.hotspot.igv.graph}:\
+    ${project.com.sun.hotspot.igv.filter}:\
+    ${project.com.sun.hotspot.igv.hierarchicallayout}:\
+    ${project.com.sun.hotspot.igv.layout}:\
+    ${project.com.sun.hotspot.igv.data}:\
+    ${project.com.sun.hotspot.igv.view}:\
+    ${project.com.sun.hotspot.igv.bytecodes}:\
+    ${project.com.sun.hotspot.igv.difference}:\
+    ${project.com.sun.hotspot.igv.settings}:\
+    ${project.com.sun.hotspot.igv.util}:\
+    ${project.com.sun.hotspot.igv.svg}:\
+    ${project.com.sun.hotspot.igv.filterwindow}:\
+    ${project.com.sun.hotspot.igv.graal}:\
+    ${project.at.ssw.visualizer.cfg}:\
+    ${project.org.eclipse.draw2d}:\
+    ${project.com.oracle.graal.visualizer.editor}:\
+    ${project.com.oracle.graal.visualizer.outline}:\
+    ${project.com.oracle.graal.visualizer.snapshots}:\
+    ${project.com.oracle.graal.visualizer.sharedactions}
+project.at.ssw.visualizer.cfg=ControlFlowEditor
+project.com.oracle.graal.visualizer.editor=Editor
+project.com.oracle.graal.visualizer.outline=OutlineView
+project.com.oracle.graal.visualizer.sharedactions=SharedActions
+project.com.oracle.graal.visualizer.snapshots=SnapshotsView
+project.com.sun.hotspot.igv.bytecodes=Bytecodes
+project.com.sun.hotspot.igv.data=Data
+project.com.sun.hotspot.igv.difference=Difference
+project.com.sun.hotspot.igv.filter=Filter
+project.com.sun.hotspot.igv.filterwindow=FilterWindow
+project.com.sun.hotspot.igv.graal=Graal
+project.com.sun.hotspot.igv.graph=Graph
+project.com.sun.hotspot.igv.hierarchicallayout=HierarchicalLayout
+project.com.sun.hotspot.igv.layout=Layout
+project.com.sun.hotspot.igv.settings=Settings
+project.com.sun.hotspot.igv.svg=BatikSVGProxy
+project.com.sun.hotspot.igv.view=View
+project.com.sun.hotspot.igv.util=Util
+
+project.org.eclipse.draw2d=Draw2DLibrary
+# Disable assertions for RequestProcessor to prevent annoying messages in case
+# of multiple SceneAnimator update tasks in the default RequestProcessor.
+run.args.extra = -J-client -J-da:org.openide.util.RequestProcessor
+debug.args.extra = -J-client -J-da:org.openide.util.RequestProcessor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/visualizer/nbproject/project.xml	Mon Feb 27 13:10:13 2012 +0100
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project.suite</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-suite-project/1">
+            <name>Graal Visualizer</name>
+        </data>
+    </configuration>
+</project>